PHP微信公众号开发之微信企业付款给个人
这篇文章主要为大家详细介绍了php微信公众号开发之微信企业付款给个人，具有一定的参考价值，感兴趣的小伙伴们可以参考一下本文实例为大家分享了php微信企业付款给个人的具体代码，供大家参考，具体内容如下以下有关微信支付中企业付款的介绍及编码参考自微信支付开发文档，如图所示<?php /* <!--微信企业付款给个人--!> 具体细节参考微信支付开发文档 参数 $openid个人openid $re_user_name个人真实姓名 $amount付款金额 $partner_trade_no商户订单号 $desc描述 如果付款成功，返回true,否则返回false */ private function weixin_transfer_money($openid,$re_user_name,$amount,$partner_trade_no,$desc){ //请求参数 //公众号appid（字段名）--mch_appid(变量名)--1(必填) //输入你的公众号appid $data['mch_appid']="**************"; //商户号--mchid--1 //输入你的商户号 $data['mchid']="*************"; //设备号--device_info--0 //随机字符串--nonce_str--1 $data['nonce_str']=$this->get_unique_value(); //签名--sign--1 $data['sign']=""; //商户订单号--partner_trade_no--1 $data['partner_trade_no']=$partner_trade_no; //用户openid--openid--1 $data['openid']=$openid; //校验用户姓名选项--check_name--1 $data['check_name']="OPTION_CHECK"; //收款用户姓名--re_user_name--0 $data['re_user_name']=$re_user_name; //金额--amount--1 $data['amount']=$amount; //企业付款描述信息--desc--1 $data['desc']=$desc; //IP地址--spbill_create_ip--1 $data['spbill_create_ip']=$_SERVER['LOCAL_ADDR']; //生成签名 //对数据数组进行处理 //API密钥，输入你的appsecret $appsecret="*************"; $data=array_filter($data); ksort($data); $str=""; foreach($data as $k=>$v){ $str.=$k."=".$v."&"; } $str.="key=".$appsecret; $data['sign']=strtoupper(MD5($str)); /* 付款操作： 1.将请求数据转换成xml 2.发送请求 3.将请求结果转换为数组 4.将请求信息和请求结果录入到数据库中 5.判断是否通信成功 6.判断是否付款成功 */ //企业付款接口地址 $url="https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; //1.将请求数据由数组转换成xml $xml=$this->arraytoxml($data); //2.进行请求操作 $res=$this->curl($xml,$url); //3.将请求结果由xml转换成数组 $arr=$this->xmltoarray($res); //4.将请求信息和请求结果录入到数据库中，可以根据自己的需要进行处理，$arr是返回的结果数组 $transfer['partner_trade_no']=$data['partner_trade_no']; $transfer['request_data']=serialize($data); $transfer['response_data']=serialize($arr); if($arr['return_code']=="SUCCESS" && $arr['result_code']=="SUCCESS"){ //5. 判断是否通讯成功 6.判断是否付款成功 $transfer['success']=1; $transfer_res['success']=1; }else{ $transfer['success']=0; $transfer_res['success']=0; $transfer_res['desc']=$arr['return_msg']; } $transfer['add_time']=time(); D("weixin_transfer")->add($transfer); return $transfer_res; } // 生成32位唯一随机字符串 private function get_unique_value(){ $str=uniqid(mt_rand(),1); $str=sha1($str); return md5($str); } // 将数组转换成xml private function arraytoxml($arr){ $xml="<xml>"; foreach($arr as $k=>$v){ $xml.="<".$k.">".$v."</".$k.">"; } $xml.="</xml>"; return $xml; } // 将xml转换成数组 private function xmltoarray($xml){ //禁止引用外部xml实体 libxml_disable_entity_loader(true); $xmlstring=simplexml_load_string($xml,"SimpleXMLElement",LIBXML_NOCDATA); $arr=json_decode(json_encode($xmlstring),true); return $arr; } //进行curl操作 private function curl($param="",$url) { $postUrl = $url; $curlPost = $param; //初始化curl $ch = curl_init(); //抓取指定网页 curl_setopt($ch, CURLOPT_URL,$postUrl); //设置header curl_setopt($ch, CURLOPT_HEADER, 0); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //post提交方式 curl_setopt($ch, CURLOPT_POST, 1); // 增加 HTTP Header（头）里的字段 curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); // 终止从服务端进行验证 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //这个是证书的位置 curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'\cert\apiclient_cert.pem'); //这个也是证书的位置 curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'\cert\apiclient_key.pem'); //运行curl $data = curl_exec($ch); //关闭curl curl_close($ch); //返回结果 return $data; }以上就是本文的全部内容，希望对大家的学习有所帮助，也希望大家多多支持轩宇网。
这篇文章主要为大家详细介绍了php实现微信企业转账功能，具有一定的参考价值，感兴趣的小伙伴们可以参考一下本文实例为大家分享了php实现微信企业转账的具体代码，供大家参考，具体内容如下：WxTransfers.Config.php<?php /** * 配置账号信息 * 配置要和证书在一起！！！！ */ class WxTransfersConfig { //=======【基本信息设置】============== // /** * TODO: 修改这里配置为您自己申请的商户信息 * 微信公众号信息配置 * * APPID：绑定支付的APPID（必须配置，开户邮件中可查看） * * MCHID：商户号（必须配置，开户邮件中可查看） * * KEY：商户支付密钥，参考开户邮件设置（必须配置，登录商户平台自行设置） * 设置地址：https://pay.weixin.qq.com/index.php/account/api_cert * */ const APPID = ''; const MCHID = ''; const KEY = ''; //=======【证书路径设置】===================================== /** * TODO：设置商户证书路径 * 证书路径,注意应该填写绝对路径,发送红包和查询需要，可登录商户平台下载 * API证书下载地址：https://pay.weixin.qq.com/index.php/account/api_cert，下载之前需要安装商户操作证书） * @var path 跟这个文件同一目录下的cert文件夹放置证书！！！！ */ const SSLCRET12 = 'cert/apiclient_cert.p12'; const SSLCERT_PATH = 'cert/apiclient_cert.pem'; const SSLKEY_PATH = 'cert/apiclient_key.pem'; const SSLROOTCA = 'cert/rootca.pem'; //=======【证书路径设置】===================================== /** * 获取文件的路径，证书需要完整路径 * @return string */ public static function getRealPath(){ return __DIR__.'/'; } } WxTransfers.Api.php<?php require_once "WxTransfers.Config.php"; /** * 微信企业转账工具类 */ class WxTransfers { // 企业转账请求地址 const TRANSFERS_URL = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //获取转账信息地址 const GETINFO_URL='https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo'; // 转账需要的配置 'wxappid','mch_id','key' private $_keys; // 转账需要的证书文件 'api_cert', 'api_key', 'rootca',请传入绝对路径！！！ private $_cert; protected $log_file; public $error; // 相关配置必备参数 protected $_parameters = array(); // 最后一次生产的订单号 protected $_lastPartnerTradeNo; // 记录最后一次发送请求的结果对象 protected $_lastResult; // 最后一次随机数 protected $_lastRandNum; public function __construct($config) { $keys = array( 'wxappid', 'mch_id', 'key' ); $files = array( 'api_cert', 'api_key', 'rootca' ); foreach ($keys as $key) { try { $this->_keys[$key] = $config[$key]; } catch (Exception $e) { throw new Exception('参数缺失：' . $key); } } foreach ($files as $file) { try { $cret_file = $config[$file]; if (is_file($cret_file)) { $this->_cert[$file] = $cret_file; } } catch (Exception $e) { throw new Exception('证书错误'); } } } public function transfers($parameters){ $this->log($parameters, 'SEND_PARAM'); $this->setParameter('mchid', $this->_keys['mch_id']); $this->setParameter('mch_appid', $this->_keys['wxappid']); $must = array( 'openid', 'check_name', 're_user_name', 'amount', 'desc', 'spbill_create_ip', ); foreach ($must as $key) { if (isset($parameters[$key]) && $parameters[$key]) { $this->setParameter($key, $parameters[$key]); } else if (! isset($this->_parameters[$key]) || ! $this->_parameters[$key]) { $this->error = '参数缺损:' . $key; return false; } } if (! isset($parameters['partner_trade_no'])) { $parameters['partner_trade_no'] = $this->getPartnerTradeNo(); } $this->setParameter('partner_trade_no', $parameters['partner_trade_no']); $this->setParameter('nonce_str', $this->getRand(30, 3)); $postXml = $this->_createXml(); if (! $postXml) { return false; } $this->log($postXml, 'SEND_XML'); $result = $this->curl_post_ssl(self::TRANSFERS_URL, $postXml); $this->log($result, 'RESULT_XML'); if (! $result) { return false; } $resultObj = simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA); $this->_lastResult = $resultObj; if ($resultObj->return_code == 'SUCCESS') { // 成功标识 if ($resultObj->result_code == 'SUCCESS') { return $resultObj->send_listid; } if ($resultObj->return_msg) { $this->error = (string) $resultObj->return_msg; return false; } $this->error = (string) $resultObj->err_code_des; return false; } if ($resultObj->return_code != 'FAIL') { $this->error = '返回信息格式异常'; return false; } $this->error = (string) $resultObj->return_msg; return false; } /** * 获取转账信息 * @param unknown $partner_trade_no * @return boolean|SimpleXMLElement */ public function getInfo($partner_trade_no){ $param = array( 'nonce_str' => $this->getRand(30, 3), 'partner_trade_no'=> $partner_trade_no , 'mch_id' => $this->_keys['mch_id'], 'appid' => $this->_keys['wxappid'], ); ksort($param); $unSignParaString = $this->_formatQueryParaMap($param, false); $param['sign'] = $this->_sign($unSignParaString, $this->_keys['key']); $xml = $this->arrayToXml($param); $this->log($xml, 'GETINFO_XML'); $result = $this->curl_post_ssl(self::GETINFO_URL, $xml); if(!$result){ return false ; } $this->log($result, 'RESULT_XML'); $resultObj = simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA); $this->_lastResult = $resultObj ; if($resultObj->return_code == 'SUCCESS'){//成功标识 if($resultObj->result_code == 'SUCCESS'){ return $resultObj ; } if($resultObj->return_msg){ $this->error = $resultObj->return_msg ; return false ; } $this->error = $resultObj->err_code_des ; return false ; } if($resultObj->return_code != 'FAIL'){ $this->error = '返回信息格式异常'; return false ; } $this->error = $resultObj->return_msg ; return false ; } /** * 设置所需要的参数 * @param $parameter 键值数组/键 * @param $value 值 * @return WxBonusApi */ public function setParameter($parameter, $value = null) { if (! is_array($parameter)) { return $this->setParameter(array( $parameter => $value )); } foreach ($parameter as $key => $value) { $key = trim($key); $value = trim($value); $this->_parameters[$key] = $value; } return $this; } /** * 获取参数值 * @param $parameter 键名 * @return multitype: */ public function getParameter($parameter) { return $this->_parameters[$parameter]; } /** * 获取随机数 * @param number $len 随机数的位数 * @param number $type 取值范围 1表示数字 2小写字母 4大写字母 * @return string */ public function getRand($len = 30, $type = 0) { $str = ''; $max = - 1; if (! $type) { $type = 3; } if ($type & 1) { $str .= '1234567890'; $max += 10; } if ($type & 2) { $str .= 'abcdefghijklmnopqrstuvwxyz'; $max += 26; } if ($type & 4) { $str .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $max += 26; } $rand = ''; for ($i = 0; $i < $len; $i ++) { $rand .= $str[rand(0, $max)]; } return $rand; } /** * 生成商户的订单号 * @return string */ public function getPartnerTradeNo() { $this->_lastPartnerTradeNo = $this->_parameters['mch_id'] . date('YmdHis') . $this->getRand(4, 1); // $this->getRandNum(); return $this->_lastPartnerTradeNo; } /** * 获取最后一次创建生成的订单号 * @return string */ public function getLastPartnerTradeNo() { return $this->_lastPartnerTradeNo; } /** * 创建XML的方法 * @param number $retcode * @param string $reterrmsg * @return boolean|string */ private function _createXml() { try { $sign = $this->_getSign(); if (! $sign) { return false; } $this->setParameter('sign', $sign); return $this->arrayToXml($this->_parameters); } catch (Exception $e) { $this->error = $e->getMessage(); return false; } } /** * 参数转换成XML * @param array $arr 参数数组 * @return string */ public function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; } else { $xml .= "<" . $key . "> " . $val . " </" . $key . ">"; } } $xml .= "</xml>"; return $xml; } /** * 获得签名结果 * @return boolean|Ambigous <string, boolean> */ protected function _getSign() { try { if ($this->_checkSign() == false) { // 检查生成签名参数 $this->error = '生成签名参数缺失！'; $this->log(json_encode($this->_parameters, JSON_UNESCAPED_UNICODE), 'ERROR_Sign_XML'); return false; } ksort($this->_parameters); $unSignParaString = $this->_formatQueryParaMap($this->_parameters, false); return $this->_sign($unSignParaString, $this->_keys['key']); } catch (Exception $e) { $this->error = $e->getMessage(); return false; } } /** * 检查签名所需参数是否齐全 * @return boolean */ private function _checkSign() { // return true; if ($this->_parameters["mch_appid"] == null || $this->_parameters["mchid"] == null || //$this->_parameters["device_info"] == null || 设备id $this->_parameters["nonce_str"] == null || $this->_parameters["partner_trade_no"] == null || $this->_parameters["openid"] == null || $this->_parameters["check_name"] == null || $this->_parameters["re_user_name"] == null || $this->_parameters["desc"] == null || $this->_parameters["spbill_create_ip"] == null) { return false; } return true; } /** * * @param $paraMap * @param $urlencode * @return string */ private function _formatQueryParaMap($paraMap,$urlencode) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if (null != $v && "null" != $v && "sign" != $k) { if ($urlencode) { $v = urlencode($v); } $buff .= $k . "=" . $v . "&"; } } $reqPar; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff) - 1); } return $reqPar; } /** * 签名 * @param $content 签名的字符串 * @param $key 密钥 * @throws Exception * @return string|boolean */ private function _sign($content, $key) { try { if (null == $key) { $this->error = '签名key不能为空！'; return false; } if (null == $content) { $this->error = '签名内容不能为空'; return false; } $signStr = $content . "&key=" . $key; return strtoupper(md5($signStr)); } catch (Exception $e) { $this->error = $e->getMessage(); return false; } } /** * cURL抓取 * * @param $url 链接地址 * @param $vars 参数 * @param * $second * @param * $aHeader * @return mixed|boolean */ function curl_post_ssl($url, $data, $second = 30, $aHeader = array()) { $ch = curl_init(); // 超时时间 curl_setopt($ch, CURLOPT_TIMEOUT, $second); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 这里设置代理，如果有的话 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // cert 与 key 分别属于两个.pem文件 curl_setopt($ch, CURLOPT_SSLCERT, $this->_cert['api_cert']); curl_setopt($ch, CURLOPT_SSLKEY, $this->_cert['api_key']); curl_setopt($ch, CURLOPT_CAINFO, $this->_cert['rootca']); if (count($aHeader) >= 1) { curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader); } curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $data = curl_exec($ch); if ($data) { curl_close($ch); return $data; } else { $this->log(json_encode($this->_cert)); $this->error = 'aa:'.curl_errno($ch); curl_close($ch); return false; } } /** * 获取服务器ip * * @return string */ public function getServerIp() { $server_ip = '127.0.0.1'; if (isset($_SERVER)) { if (isset($_SERVER['SERVER_ADDR']) && $_SERVER['SERVER_ADDR']) { $server_ip = $_SERVER['SERVER_ADDR']; } elseif (isset($_SERVER['LOCAL_ADDR']) && $_SERVER['LOCAL_ADDR']) { $server_ip = $_SERVER['LOCAL_ADDR']; } } else { $server_ip = getenv('SERVER_ADDR'); } return $server_ip; } /** * 设置日志目录文件 * * @param unknown $file */ public function setLogFile($file) { $this->log_file = $file; } /** * 写日志 * * @param $msg 写入的信息 * @param $type 日志类型作为查询标示 */ public function log($msg, $type) { if ($this->log_file) { $log = str_replace(array( "\r\n", "\r", "\n" ), array( "", "", "" ), $msg); error_log($type . ' ' . date('Y-m-d H:i:s') . ' ' . json_encode($log,JSON_UNESCAPED_UNICODE) . "\r\n", 3, $this->log_file); } } } 使用方法：<?php include 'WxTransfers.Api.php'; class WxTransfers{ /** *调用方法即可测试 */ public function index(){ $path = WxTransfersConfig::getRealPath(); // 证书文件路径 $config['wxappid'] = WxTransfersConfig::APPID; $config['mch_id'] = WxTransfersConfig::MCHID; $config['key'] = WxTransfersConfig::KEY; $config['PARTNERKEY'] = WxTransfersConfig::KEY; $config['api_cert'] = $path . WxTransfersConfig::SSLCERT_PATH; $config['api_key'] = $path . WxTransfersConfig::SSLKEY_PATH; $config['rootca'] = $path . WxTransfersConfig::SSLROOTCA; $wxtran=new WxTransfers($config); $wxtran->setLogFile('D:\\transfers.log');//日志地址 //转账 $data=array( 'openid'=>'',//openid 'check_name'=>'NO_CHECK',//是否验证真实姓名参数 're_user_name'=>'11',//姓名 'amount'=>100,//最小1元 也就是100 'desc'=>'企业转账测试',//描述 'spbill_create_ip'=>$wxtran->getServerIp(),//服务器IP地址 ); var_dump(json_encode($wxtran->transfers($data),JSON_UNESCAPED_UNICODE)); var_dump($wxtran->error); //获取转账信息 var_dump($wxtran->getInfo('11111111')); var_dump($wxtran->error); } } 以上就是本文的全部内容，希望对大家的学习有所帮助，也希望大家多多支持轩宇网。
这篇文章主要为大家详细介绍了PHP微信支付之公众号支付功能的原生态写法，具有一定的参考价值，感兴趣的小伙伴们可以参考一下网上的很多PHP微信扫码支付接入教程都颇为复杂，且需要配置和引入较多的文件，本人通过整理后给出一个单文件版的，希望可以给各位想接入微信扫码支付的带来些许帮助和借鉴意义。将该文件放到你的授权目录下，并在微信里访问这个文件，即可看到演示效果。效果如下： 需要注意的事项： 1.该文件需放到支付授权目录下，可以在微信支付商户平台->产品中心->开发配置中设置。 2.如提示签名错误可以通过微信支付签名验证工具进行验证：微信公众平台支付接口调试工具具体实现代码如下：<?php header('Content-type:text/html; Charset=utf-8'); $mchid = 'xxxxx'; //微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送 $appid = 'xxxxx'; //微信支付申请对应的公众号的APPID $appKey = 'xxxxx'; //微信支付申请对应的公众号的APP Key $apiKey = 'xxxxx'; //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥 //①、获取用户openid $wxPay = new WxpayService($mchid,$appid,$appKey,$apiKey); $openId = $wxPay->GetOpenid(); //获取openid if(!$openId) exit('获取openid失败'); //②、统一下单 $outTradeNo = uniqid(); //你自己的商品订单号 $payAmount = 0.01; //付款金额，单位:元 $orderName = '支付测试'; //订单标题 $notifyUrl = 'https://www.xxx.com/wx/'; //付款成功后的回调地址(不要有问号) $payTime = time(); //付款时间 $jsApiParameters = $wxPay->createJsBizPackage($openId,$payAmount,$outTradeNo,$orderName,$notifyUrl,$payTime); $jsApiParameters = json_encode($jsApiParameters); ?> 微信支付样例-支付 该笔订单支付金额为<?php echo $payAmount?>元钱 立即支付 <?php class WxpayService { protected $mchid; protected $appid; protected $appKey; protected $apiKey; public $data = null; public function __construct($mchid, $appid, $appKey,$key) { $this->mchid = $mchid; //https://pay.weixin.qq.com 产品中心-开发配置-商户号 $this->appid = $appid; //微信支付申请对应的公众号的APPID $this->appKey = $appKey; //微信支付申请对应的公众号的APP Key $this->apiKey = $key; //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥 } /** * 通过跳转获取用户的openid，跳转流程如下： * 1、设置自己需要调回的url及其其他参数，跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize * 2、微信服务处理完成之后会跳转回用户redirect_uri地址，此时会带上一些参数，如：code * @return 用户的openid */ public function GetOpenid() { //通过code获得openid if (!isset($_GET['code'])){ //触发微信返回code码 $scheme = $_SERVER['HTTPS']=='on' ? 'https://' : 'http://'; $baseUrl = urlencode($scheme.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING']); $url = $this->__CreateOauthUrlForCode($baseUrl); Header("Location: $url"); exit(); } else { //获取code码，以获取openid $code = $_GET['code']; $openid = $this->getOpenidFromMp($code); return $openid; } } /** * 通过code从工作平台获取openid机器access_token * @param string $code 微信跳转回来带上的code * @return openid */ public function GetOpenidFromMp($code) { $url = $this->__CreateOauthUrlForOpenid($code); $res = self::curlGet($url); //取出openid $data = json_decode($res,true); $this->data = $data; $openid = $data['openid']; return $openid; } /** * 构造获取open和access_toke的url地址 * @param string $code，微信跳转带回的code * @return 请求的url */ private function __CreateOauthUrlForOpenid($code) { $urlObj["appid"] = $this->appid; $urlObj["secret"] = $this->appKey; $urlObj["code"] = $code; $urlObj["grant_type"] = "authorization_code"; $bizString = $this->ToUrlParams($urlObj); return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString; } /** * 构造获取code的url连接 * @param string $redirectUrl 微信服务器回跳的url，需要url编码 * @return 返回构造好的url */ private function __CreateOauthUrlForCode($redirectUrl) { $urlObj["appid"] = $this->appid; $urlObj["redirect_uri"] = "$redirectUrl"; $urlObj["response_type"] = "code"; $urlObj["scope"] = "snsapi_base"; $urlObj["state"] = "STATE"."#wechat_redirect"; $bizString = $this->ToUrlParams($urlObj); return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString; } /** * 拼接签名字符串 * @param array $urlObj * @return 返回已经拼接好的字符串 */ private function ToUrlParams($urlObj) { $buff = ""; foreach ($urlObj as $k => $v) { if($k != "sign") $buff .= $k . "=" . $v . "&"; } $buff = trim($buff, "&"); return $buff; } /** * 统一下单 * @param string $openid 调用【网页授权获取用户信息】接口获取到用户在该公众号下的Openid * @param float $totalFee 收款总费用 单位元 * @param string $outTradeNo 唯一的订单号 * @param string $orderName 订单名称 * @param string $notifyUrl 支付结果通知url 不要有问号 * @param string $timestamp 支付时间 * @return string */ public function createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp) { $config = array( 'mch_id' => $this->mchid, 'appid' => $this->appid, 'key' => $this->apiKey, ); $orderName = iconv('GBK','UTF-8',$orderName); $unified = array( 'appid' => $config['appid'], 'attach' => 'pay', //商家数据包，原样返回，如果填写中文，请注意转换为utf-8 'body' => $orderName, 'mch_id' => $config['mch_id'], 'nonce_str' => self::createNonceStr(), 'notify_url' => $notifyUrl, 'openid' => $openid, //rade_type=JSAPI，此参数必传 'out_trade_no' => $outTradeNo, 'spbill_create_ip' => '127.0.0.1', 'total_fee' => intval($totalFee * 100), //单位 转为分 'trade_type' => 'JSAPI', ); $unified['sign'] = self::getSign($unified, $config['key']); $responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified)); $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA); if ($unifiedOrder === false) { die('parse xml error'); } if ($unifiedOrder->return_code != 'SUCCESS') { die($unifiedOrder->return_msg); } if ($unifiedOrder->result_code != 'SUCCESS') { die($unifiedOrder->err_code); } $arr = array( "appId" => $config['appid'], "timeStamp" => "$timestamp", //这里是字符串的时间戳，不是int，所以需加引号 "nonceStr" => self::createNonceStr(), "package" => "prepay_id=" . $unifiedOrder->prepay_id, "signType" => 'MD5', ); $arr['paySign'] = self::getSign($arr, $config['key']); return $arr; } public static function curlGet($url = '', $options = array()) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function curlPost($url = '', $postData = '', $options = array()) { if (is_array($postData)) { $postData = http_build_query($postData); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function createNonceStr($length = 16) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } public static function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; } else $xml .= "<" . $key . "> " . $val . " </" . $key . ">"; } $xml .= "</xml>"; file_put_contents('1.txt',$xml); return $xml; } public static function getSign($params, $key) { ksort($params, SORT_STRING); $unSignParaString = self::formatQueryParaMap($params, false); $signStr = strtoupper(md5($unSignParaString . "&key=" . $key)); return $signStr; } protected static function formatQueryParaMap($paraMap, $urlEncode = false) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if (null != $v && "null" != $v) { if ($urlEncode) { $v = urlencode($v); } $buff .= $k . "=" . $v . "&"; } } $reqPar = ''; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff) - 1); } return $reqPar; } } ?>项目地址点击下载
微信小程序支付功能实现及PHP接口代码
这篇文章主要为大家详细介绍了微信小程序支付的PHP实现代码，具有一定的参考价值，感兴趣的小伙伴们可以参考一下本文实例为大家分享了微信小程序支付PHP具体代码，供大家参考，具体内容如下服务器端获取 openidGetopenid.php<?php header('Content-type: application/json; charset=UTF-8'); $APPID="";//填写小程序appid $SECRET="";//填写小程序secret $JSCODE=""; if(isset($_GET['js_code'])){ $JSCODE=$_GET['js_code']; $url="https://api.weixin.qq.com/sns/jscode2session?appid=".$APPID ."&secret=".$SECRET."&js_code=".$JSCODE."&grant_type=authorization_code"; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HEADER, 0); $data = curl_exec($curl); $array=json_decode($data,true); curl_close($curl); $openid=isset($array['openid'])?$array['openid']:$array['errcode']; if($openid=="40029"){ $response["result"] = 0; $response["msg"] = "invalid code"; $response["openid"] = $openid; echo json_encode($response); }else{ $response["result"] = 1; $response["msg"] = "user exist"; $response["openid"] = $openid; echo json_encode($response); } }小程序存储openid 在app.js中getUserInfo:function(cb){ var that = this if(this.globalData.userInfo){ typeof cb == "function" && cb(this.globalData.userInfo) }else{ wx.login({ success: function (res) { if (res.code) { var code = res.code; wx.getUserInfo({ success: function (res2) { console.log(res2); that.globalData.userInfo = res2.userInfo; typeof cb == "function" && cb(that.globalData.userInfo) var encryptedData = encodeURIComponent(res2.encryptedData);//一定要把加密串转成URI编码 var iv = res2.iv; //请求自己的服务器 //Login(code, encryptedData, iv); wx.showToast({ title: '正在登录...', icon: 'loading', duration: 10000 }); //请求服务器 wx.request({ url: API_URL,//Getopenid.php data: { js_code: code, }, method: 'GET', header: { 'content-type': 'application/json' }, // 设置请求的 header success: function (res) { // success wx.hideToast(); console.log("JSON:" + res.data); if (res.data.result=="1"){//获取openid成功 wx.setStorage({//存储openid key: "openid", data: res.data.openid }) }else{ wx.showToast({ title: 'openid获取失败', icon: 'none', duration: 2000 }) } console.log('服务器返回' + res.data.result); console.log('服务器返回' + res.data.msg); console.log('服务器返回' + res.data.openid); }, fail: function () { // fail // wx.hideToast(); }, complete: function () { // complete } }) } }) } else { console.log('获取用户登录态失败！' + res.errMsg) } } }) } }在登陆界面获取openidvar app = getApp() onLoad: function () { console.log('onLoad') var that = this //调用应用实例的方法获取全局数据 app.getUserInfo(function(userInfo){//获取用户信息 //更新数据 that.setData({ userInfo:userInfo }) }) }通过以上步骤已经获取到openid微信小程序支付方法pay() { var that = this; if (this.data.totalPrice == 0) { return; } wx.getStorage({//获取存储在本地的openid key: 'openid', success: function (res) { console.log(res.data) that.setData({ openid:res.data, }) var carArray = that.data.carArray; var str=""; for (var i = 0; i < carArray.length; i++) { str=str+ carArray[i].num+"个" + carArray[i].name+" "; } wx.request({ url: 'Pay.php',//支付接口 data: { openid: res.data,//openid total_fee: that.data.totalPrice,//总金额 body: str,//商品描述 }, method:'GET', success:function(res){ console.log(res.data['timeStamp']) if(res.data){ wx.requestPayment({ 'timeStamp': res.data['timeStamp'], 'nonceStr': res.data['nonceStr'], 'package': res.data['package'], 'signType': 'MD5', 'paySign': res.data['paySign'], 'success': function (res) { wx.showToast({ title: '支付成功', icon: 'succes', duration: 1000, mask: true }) //支付成功后在数据库减去购买商品的数量 var carArray = that.data.carArray; for (var i = 0; i < carArray.length; i++) { that.setData({ jiesuan_num: carArray[i].num, jiesuan_id: carArray[i].goods_id, }) DeGood(that); } }, 'fail': function (res) { wx.showToast({ title: '支付失败', icon: 'none', duration: 1000, mask: true }) } }) } } }) } }) },Pay.php<?php include 'WeixinPay.php'; $appid=''; //小程序appid $openid= $_GET['openid']; $mch_id=''; //商户id $key=''; //商户key $out_trade_no = $mch_id. time(); $total_fee = $_GET['total_fee']; $body= $_GET['body']; if(empty($total_fee)){ $body = $body; $total_fee = floatval(99*100); }else{ $body = $body; $total_fee = floatval($total_fee*100); } $weixinpay = new WeixinPay($appid,$openid,$mch_id,$key,$out_trade_no,$body,$total_fee); $return=$weixinpay->pay(); echo json_encode($return);WeixinPay.php<?php /* * 小程序微信支付 */ class WeixinPay { protected $appid; protected $mch_id; protected $key; protected $openid; protected $out_trade_no; protected $body; protected $total_fee; function __construct($appid, $openid, $mch_id, $key,$out_trade_no,$body,$total_fee) { $this->appid = $appid; $this->openid = $openid; $this->mch_id = $mch_id; $this->key = $key; $this->out_trade_no = $out_trade_no; $this->body = $body; $this->total_fee = $total_fee; } public function pay() { //统一下单接口 $return = $this->weixinapp(); return $return; } //统一下单接口 private function unifiedorder() { $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; $parameters = array( 'appid' => $this->appid, //小程序ID 'mch_id' => $this->mch_id, //商户号 'nonce_str' => $this->createNoncestr(), //随机字符串 // 'body' => 'test', //商品描述 'body' => $this->body, // 'out_trade_no' => '2015450806125348', //商户订单号 'out_trade_no'=> $this->out_trade_no, // 'total_fee' => floatval(0.01 * 100), //总金额 单位 分 'total_fee' => $this->total_fee, // 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], //终端IP 'spbill_create_ip' => '192.168.0.161', //终端IP 'notify_url' => 'http://www.weixin.qq.com/wxpay/pay.php', //通知地址 确保外网能正常访问 'openid' => $this->openid, //用户id 'trade_type' => 'JSAPI'//交易类型 ); //统一下单签名 $parameters['sign'] = $this->getSign($parameters); $xmlData = $this->arrayToXml($parameters); $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60)); return $return; } private static function postXmlCurl($xml, $url, $second = 30) { $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验 //设置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); curl_setopt($ch, CURLOPT_TIMEOUT, 40); set_time_limit(0); //运行curl $data = curl_exec($ch); //返回结果 if ($data) { curl_close($ch); return $data; } else { $error = curl_errno($ch); curl_close($ch); throw new WxPayException("curl出错，错误码:$error"); } } //数组转换成xml private function arrayToXml($arr) { $xml = "<root>"; foreach ($arr as $key => $val) { if (is_array($val)) { $xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">"; } else { $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; } } $xml .= "</root>"; return $xml; } //xml转换成数组 private function xmlToArray($xml) { //禁止引用外部xml实体 libxml_disable_entity_loader(true); $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); $val = json_decode(json_encode($xmlstring), true); return $val; } //微信小程序接口 private function weixinapp() { //统一下单接口 $unifiedorder = $this->unifiedorder(); // print_r($unifiedorder); $parameters = array( 'appId' => $this->appid, //小程序ID 'timeStamp' => '' . time() . '', //时间戳 'nonceStr' => $this->createNoncestr(), //随机串 'package' => 'prepay_id=' . $unifiedorder['prepay_id'], //数据包 'signType' => 'MD5'//签名方式 ); //签名 $parameters['paySign'] = $this->getSign($parameters); return $parameters; } //作用：产生随机字符串，不长于32位 private function createNoncestr($length = 32) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } //作用：生成签名 private function getSign($Obj) { foreach ($Obj as $k => $v) { $Parameters[$k] = $v; } //签名步骤一：按字典序排序参数 ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //签名步骤二：在string后加入KEY $String = $String . "&key=" . $this->key; //签名步骤三：MD5加密 $String = md5($String); //签名步骤四：所有字符转为大写 $result_ = strtoupper($String); return $result_; } ///作用：格式化参数，签名过程需要使用 private function formatBizQueryParaMap($paraMap, $urlencode) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if ($urlencode) { $v = urlencode($v); } $buff .= $k . "=" . $v . "&"; } $reqPar; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff) - 1); } return $reqPar; } }以上就是本文的全部内容，希望对大家的学习有所帮助，也希望大家多多支持轩宇网工作室。
微信扫码支付分为两种模式，模式一比较复杂，需要公众号配置回调地址。模式二比较简单，只需要在代码中配置回调地址就可以了。我这次使用的是模式二。需要配置参数，const APPID = 'xxx'; const MCHID = 'xxx'; const KEY = 'xxx'; const APPSECRET = 'xxx';配置公众号的appid，appsecret。以及微信支付的mchid与key。生成二维码，这个页面需要自己去美化，不像支付宝那样自带效果。require_once "./phpcms/plugin/weixinpay/lib/WxPay.Api.php"; require_once "./phpcms/plugin/weixinpay/example/WxPay.NativePay.php"; require_once './phpcms/plugin/weixinpay/example/log.php'; $input = new WxPayUnifiedOrder(); $input->SetBody('预订'.$product_info['name'].'订单'); $input->SetAttach('预订'.$product_info['name'].'订单'); $input->SetOut_trade_no($order_info['orderno']); $input->SetTotal_fee($order_info['payprice'] * 100); $input->SetTime_start(date("YmdHis")); $input->SetTime_expire(date("YmdHis", time() + 600)); $input->SetGoods_tag(""); $input->SetNotify_url("http://www.ayuanduanzu.com/wxpay/notify.php"); // 地址是外网能访问的，且不能包含参数 $input->SetTrade_type("NATIVE"); $input->SetProduct_id($product_info['id']); $notify = new NativePay(); $result = $notify->GetPayUrl($input); $code_url = $result["code_url"]; 这里的回调地址很有讲究，扫码支付成功后，微信会自动调用这个地址。这个地址不能包含任何参数，否则调用失败。啥都看不到！微信调用的时候，会传递xml类型的参数。include_once "../phpcms/base.php"; // 处理回调数据 error_reporting(E_ERROR); require_once "../phpcms/plugin/weixinpay/lib/WxPay.Api.php"; require_once '../phpcms/plugin/weixinpay/lib/WxPay.Notify.php'; require_once '../phpcms/plugin/weixinpay/example/log.php'; //初始化日志 $logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log'); $log = Log::Init($logHandler, 15); class PayNotifyCallBack extends WxPayNotify //查询订单 public function Queryorder($transaction_id) { $input = new WxPayOrderQuery(); $input->SetTransaction_id($transaction_id); $result = WxPayApi::orderQuery($input); Log::DEBUG("query:" . json_encode($result)); if(array_key_exists("return_code", $result) && array_key_exists("result_code", $result) && $result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS") { return true; } return false; } //重写回调处理函数 public function NotifyProcess($data, &$msg) { Log::DEBUG("call back:" . json_encode($data)); $notfiyOutput = array(); if(!array_key_exists("transaction_id", $data)){ $msg = "输入参数不正确"; return false; } //查询订单，判断订单真实性 if(!$this->Queryorder($data["transaction_id"])){ $msg = "订单查询失败"; return false; } return true; } Log::DEBUG("begin notify"); $notify = new PayNotifyCallBack(); $ilog_db = pc_base::load_model('ilog_model'); $order_db = pc_base::load_model('order_model'); $postXml = $GLOBALS["HTTP_RAW_POST_DATA"]; $postArr = xmlToArray($postXml); // 查询是否支付成功 $r = $notify->Queryorder($postArr['transaction_id']); if ($r) { // 获取订单信息 $order_info = $order_db->get_one(array('orderno'=>$postArr['out_trade_no'])); if ($order_info['pay_status'] != '1') { $data['pay_status'] = '1'; $data['pay_type'] = 'weixinpay'; $data['pay_code'] = $postArr['transaction_id']; $data['paytime'] = time(); $data['order_status']= 3; // 已支付 $order_db->update($data,array('orderno'=>$postArr['out_trade_no'])); } ?>通过$GLOBALS["HTTP_RAW_POST_DATA"]; 可以获取微信端传入的参数{ "appid": "wxed7996e9ad58345d", "attach": "u9884u8ba2u5bbfu8fc1u00b7u592au53e4u91ccu7f8eu5f0fu5957u623fu8ba2u5355", "bank_type": "CFT", "cash_fee": "1", "fee_type": "CNY", "is_subscribe": "Y", "mch_id": "1283301801", "nonce_str": "20xn5e0lbk2u1u6pes2uonape2sdyfs4", "openid": "oR8C7wsknwVELIRrzTlZX2eONWeY", "out_trade_no": "2016091455521024608", "result_code": "SUCCESS", "return_code": "SUCCESS", "sign": "95C2C532D095E7BF7588522C579758C4", "time_end": "20160914135518", "total_fee": "1", "trade_type": "NATIVE", "transaction_id": "4009602001201609143926590576" }查询是否已支付，支付完成的话，进行订单数据处理。这里的一切都是异步的，二维码页面啥都看不到。只能通过异步获取订单状态来判断是否操作成功。// 检测是否支付成功 $(document).ready(function () { setInterval("ajaxstatus()", 3000); function ajaxstatus() { var orderno = $("#out_trade_no").val(); if (orderno != 0) { $.ajax({ url: "?m=home&c=order&a=ajax", type: "GET", dataType:"json", data: { todo: 'ajaxCheckWxPay', orderno: orderno, }, success: function (json) { if (json.status == 1) { //订单状态为1表示支付成功 layer.msg('支付成功',{icon:1,time: 2000},function(){ window.location.href = "?m=home&c=order&a=payDone&orderno="+json.info['orderno']; }); // window.location.href = "wxScanSuccessUrl.action"; //页面跳转 } } }); } }三秒执行一次，如果成功，进行跳转处理。函数* 作用：array转xml */ function arrayToXml($arr) $xml = "<xml>"; foreach ($arr as $key=>$val) { if (is_numeric($val)) { $xml.="<".$key.">".$val."</".$key.">"; } else $xml.="<".$key."> ".$val." </".$key.">"; } $xml.="</xml>"; return $xml; * 作用：将xml转为array */ function xmlToArray($xml) { //将XML转为array $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $array_data; }小窍门对于异步的调用，如果看不到效果。可以建一个日志表，把操作的数据记录在表中。便于测试。支付回调都是异步的，可以通过日志表中的数据来判断是否支付成功，是否调用了回调，调用了几次。小结：微信扫码支付不如支付宝扫码支付便捷。需要自己做很多处理。以上所述是小编给大家介绍的PHP 微信扫码支付接入总结(总结篇),数据库显示空白的完美解决方案(图文教程)，希望对大家有所帮助，如果大家有任何疑问请给我留言，小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持！
最近由于业务所需，对接了微信H5支付，然而微信支付对这块并没有现成的demo可用，所以就必须自己老老实实对照开发文档去写咯！但这对于刚接触的童鞋来说，坑多多少少还是有的，所以寻思着把自己的经验分享出来，毕竟现成的用的还是多巴适的嘛！ 好了，官方文档的那一套就不多说了，详情见官方文档。 在这里，我主要分成了三个文件：WxPay.Config.php（支付配置文件）、Weixin.class.php（支付类）以及PayMentController.class.php（支付文件）。首先，WxPay.Config.php配置文件主要包含了商户appId、商户号、商家key、异步回调URL、支付场景信息，如下：class WxPayConfig { public static $appid = '微信支付的公众号appid'; public static $mchid = '微信支付分配的商户号'; public static $key = '微信商户自己设置的安全key'; public static $notify_url = '商户侧接收微信支付异步通知的URL'; public static $scene_info = '{"h5_info":{"type":"Wap","wap_url":" 发起微信H5支付H5的URL","wap_name":"支付"}}'; }然后，封装Weixin.class.php支付类，主要调用统一下单Api，这里不多说了，直接上代码：<?php require_once "lib/WxPay.Config.php"; class Weixin { /** * 微信H5下单付款 * @order 付款信息 * @bodys 付款内容 * */ function getCode($order,$bodys){ $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址 //1.获取调用统一下单接口所需必备参数 $appid =WxPayConfig::$appid;//微信公众号appid $mch_id = WxPayConfig::$mchid;//微信支付商户号 $key = WxPayConfig::$key;//自己设置的微信商家key $out_trade_no = $order['order_sn'];//平台内部订单号 $nonce_str=MD5($out_trade_no);//随机字符串 $body = $bodys;//付款内容 $total_fee = $order['order_amount']*100;//付款金额，单位为分 $spbill_create_ip = getIP(); //获得用户设备IP $attach = 'weixinh5';//附加数据（自定义，在支付通知中原样返回） $notify_url = WxPayConfig::$notify_url; //异步回调地址，需外网可以直接访问 $trade_type = 'MWEB';//交易类型，微信H5支付时固定为MWEB $scene_info =WxPayConfig::$scene_info;//场景信息 //2.将参数按照key=value的格式，并按照参数名ASCII字典序排序生成字符串 $signA ="appid=$appid&attach=$attach&body=$body&mch_id=$mch_id&nonce_str=$nonce_str¬ify_url=$notify_url&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type"; //3.拼接字符串 $strSignTmp = $signA."&key=$key"; //4.MD5加密后转换成大写 $sign = strtoupper(MD5($strSignTmp)); //5.拼接成所需XML格式 $post_data = "<xml> <appid>$appid</appid> <attach>$attach</attach> $body <mch_id>$mch_id</mch_id> <nonce_str>$nonce_str</nonce_str> <notify_url>$notify_url</notify_url> <out_trade_no>$out_trade_no</out_trade_no> <spbill_create_ip>$spbill_create_ip</spbill_create_ip> <total_fee>$total_fee</total_fee> <trade_type>$trade_type</trade_type> <scene_info>$scene_info</scene_info> <sign>$sign</sign> </xml>"; //6.以POST方式向微信传参，并取得微信返回的支付参数 $dataxml = httpRequest($url,'POST',$post_data); $objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的XML转换成数组 return $objectxml; } }最后，PayMentController.class.php支付文件，支付文件接收前端发起支付的请求并处理后，调用Weixin.class.php支付类并接受结果后返回给前端（此处分享已经去掉接口验证等系列代码逻辑）：public function getPay(){ //1.引入支付类文件 include_once "plugins/Payment/weixin/Weixin.class.php"; $payment = new \Weixin(); $order_id = I('order_id'); //2.判断参数是否为空 if (!empty($order_id)){ //3.根据订单id查询订单是否存在 $order = M('Order')->where(array('id'=>$order_id))->find(); if ($order){//订单存在 //4.判断该笔订单是否已经支付，如已支付则返回支付失败并给出相应提示 if ($order['pay_status'] == '1'){ exit(json_encode(array('status'=>'205','msg'=>'该订单已支付，请勿重复提交！'))); } $bodys = '订单：'.$order['order_sn'] . '支付'; //5.调用支付类中封装的支付方法并对应传参 $result = $payment->getCode($order,$bodys); //6.当return_code和result_code均为SUCCESS，代表下单成功，将支付参数返回 if($result['return_code'] == 'SUCCESS'){ if($result['result_code'] == 'SUCCESS'){ exit(json_encode(array('status'=>'0','msg'=>'下单成功，请支付！','result'=>$result['mweb_url']))); }elseif($result['result_code'] == 'FAIL'){ exit(json_encode(array('status'=>'-201','msg'=>$result['err_code_des']))); } }else{ exit(json_encode(array('status'=>'-1','msg'=>'未知错误，请稍后重试！'))); } }else{ //报错:数据不存在 exit(json_encode(array('status'=>'-200','msg'=>'订单不存在，请核实后再提交！'))); } }else{ //报错:缺少参数 exit(json_encode(array('status'=>'-204','msg'=>'参数缺失，请核实！'))); } }前端在接收到支付URL后执行即可唤醒微信支付。附一：获取用户终端设备ip方法function getIP(){ if (getenv("HTTP_CLIENT_IP")) $ip = getenv("HTTP_CLIENT_IP"); else if(getenv("HTTP_X_FORWARDED_FOR")) $ip = getenv("HTTP_X_FORWARDED_FOR"); else if(getenv("REMOTE_ADDR")) $ip = getenv("REMOTE_ADDR"); else $ip = "Unknow"; return $ip; }附二：CURL请求方法/** * CURL请求 * @param $url 请求url地址 * @param $method 请求方法 get post * @param null $postfields post数据数组 * @param array $headers 请求header信息 * @param bool|false $debug 调试开启 默认false * @return mixed */ function httpRequest($url, $method, $postfields = null, $headers = array(), $debug = false) { $method = strtoupper($method); $ci = curl_init(); /* Curl settings */ curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0"); curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间，如果设置为0，则无限等待 */ curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */ curl_setopt($ci, CURLOPT_RETURNTRANSFER, true); switch ($method) { case "POST": curl_setopt($ci, CURLOPT_POST, true); if (!empty($postfields)) { $tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields; curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr); } break; default: curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */ break; } $ssl = preg_match('/^https:\/\//i',$url) ? TRUE : FALSE; curl_setopt($ci, CURLOPT_URL, $url); if($ssl){ curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在 } curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ci, CURLOPT_MAXREDIRS, 2);/*指定最多的HTTP重定向的数量，这个选项是和CURLOPT_FOLLOWLOCATION一起使用的*/ curl_setopt($ci, CURLOPT_HTTPHEADER, $headers); curl_setopt($ci, CURLINFO_HEADER_OUT, true); $response = curl_exec($ci); $requestinfo = curl_getinfo($ci); if ($debug) { echo "=====post data======\r\n"; var_dump($postfields); echo "=====info===== \r\n"; print_r($requestinfo); echo "=====response=====\r\n"; print_r($response); } curl_close($ci); return $response; }