微信小程序支付的流程问题解析(代码解析)
本篇文章给大家带来的内容是关于微信小程序支付的流程问题解析(代码解析),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
这几天在做小程序的支付,没有用官方的SDK,这里就纯用官方的文档搞一发。
* 注:使用的PHP,不过支付流程都是这样 开发前必读主要流程小程序前端发送求参请求
接受请求封装 “统一下单” 获取package
小程序接受 “统一下单” 获取的package值带入wx.requestPayment发起支付请求准备工具申请小程序微信支付
拿到小程序微信支付的商户号及设置秘钥
注意:小程序就只需要这两步,如果是web的话还需要设置支付目录授权域名,文档里面也有写的:https://pay.weixin.qq.com/wik..统一下单/** * 统一订单 */public function unifiedorder(){// 以下配置是必填项,如有其它需求请自行配置$config = array('appid'=>'xxxxxxx',//这里是小程序appid'mch_id'=>'xxxxxxx',//商户ID'nonce_str'=>$this->getNonceStr(),//随机字符串'body'=>'这里是测试 - 测试',//请按照文档要求填写合格名称'out_trade_no'=>time().$this->getNonceStr(2),//流水单号'total_fee'=>'20',//金额,分为单位,这里是0.2元'spbill_create_ip' => '123.123.123.123',//当前IP'notify_url'=>'http://xxxx.com',//请恕我愚昧,我没搞懂他有什么用'trade_type'=>'JSAPI',//必须填写JSAPI'openid'=>'xxxxxxxx'//当前用户的openid,在trade_type=JSAPI的时候,此项就变成必填项了);$config['sign'] = $this->getSignPay($config);$xmlData = $this->ToXml($config);//转成xml数据$postData = $this->http_post($xmlData);$arrayData = $this->FromXml($postData);if($arrayData['return_code'] == 'SUCCESS' || $arrayData['result_code'] == 'SUCCESS'){return $arrayData['prepay_id'];//重点来了:走了这么多路,就为了这个值。到这一步就证明成功一多半了。}else{return $arrayData;//返回错误}}/** * 获取签名 */public function getSignPay($config){$key = 'xxxxxxx';//商户秘钥,就是自己生成的32位密码$strA = 'appid='.$config['appid'].'&body='.$config['body'].'&mch_id='.$config['mch_id'].'&nonce_str='.$config['nonce_str'].'¬ify_url='.$config['notify_url'].'&spbill_create_ip'.$config['spbill_create_ip'].'&total_fee='.$config['total_fee'].'&trade_type='.$config['trade_type'];//ASCII 字典序$strB = $strA.'&key='.$key;$sign = strtoupper(md5($strB));//大写MD5return $sign;}/** * 随机字符串 32位 */public function getNonceStr($length = 32){$chars = "abcdefghijklmnopqrstuvwxyz0123456789";$str ="";for ( $i = 0; $i < $length; $i++ ){$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);}return $str;}/** * array转XML */public function ToXml($data){if(!is_array($data) || count($data) <= 0){throw new WxPayException("数组数据异常!");}$xml = "<xml>";foreach ($data as $key=>$val){$xml.="<".$key.">".$val."</".$key.">";}$xml.="</xml>";return $xml; }/** * xml转array */public function FromXml($xml){if(!$xml){throw new WxPayException("xml数据异常!");}libxml_disable_entity_loader(true);$this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);return $this->values;}/** * post 请求 */public function http_post($url,$param,$post_file=false){$oCurl = curl_init();if(stripos($url,"https://")!==FALSE){curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1}if (PHP_VERSION_ID >= 50500 && class_exists('CURLFile')) {$is_curlFile = true;} else {$is_curlFile = false;if (defined('CURLOPT_SAFE_UPLOAD')) {curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false);}}if (is_string($param)) {$strPOST = $param;}elseif($post_file) {if($is_curlFile) {foreach ($param as $key => $val) {if (substr($val, 0, 1) == '@') {}}}$strPOST = $param;} else {$aPOST = array();foreach($param as $key=>$val){$aPOST[] = $key."=".urlencode($val);}$strPOST =join("&", $aPOST);}curl_setopt($oCurl, CURLOPT_URL, $url);curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );curl_setopt($oCurl, CURLOPT_POST,true);curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);$sContent = curl_exec($oCurl);$aStatus = curl_getinfo($oCurl);curl_close($oCurl);if(intval($aStatus["http_code"])==200){return $sContent;}else{return false;}}好了现在已经获取到了 prepay_id 的值,我们的统一下单就算完成了,其实我更乐意叫他数据封小程序微信支付先来一个插曲,首先我们小程序的前端需要去触发pay,实现的功能肯定是要点击小程序的一个触发,然后才能支付对吧,pay:function(e){//这里面使用post去请求。然后通过我接下来要写的API支付代码获取小程序支付参数success:function(res){wx.requestPayment({'timeStamp':toString(res.timeStamp),//这里转字符串,这里被坑过,不转的话可能会出现total_fee为空'nonceStr':toString(res.nonceStr),'package':toString(res.package),'signType':'MD5','paySign':toString(res.paySign),success:function(res){console.log(res);//这里可以跳转到带参地址},fail:function(res){console.info('支付失败',res);},complete:function(){console.info('支付触发回调',res);}})}}api支付也就是上面小程序代码的后端请求地址/** * api组装数据 */public function payApiBlack(){$appid = 'xxxxxx';//小程序appid,上面有重复,不过这样比较直观$timeStamp = time();$nonceStr = $this->getNonceStr();//这是调用统一下单里面的方法,为了直观,我把这些代码都写在了一个类里$package = 'prepay_id='.$this->unifiedorder();$signType = 'MD5';$key = 'xxxxxx';//这里是商户秘钥,32位,同上面也有$strA = 'appId='.$appid.'&nonceStr='.$nonceStr.'package='.$package.'&= signType='.$signType.'&timeStamp='.$timeStamp.'&key='.$key;$paySign = strtoupper(md5($strA));$data = array('appid'=>$appid,'timeStamp'=>$timeStamp,'nonceStr'=>$nonceStr,'package'=>$package,'signType'=>$signType);return $data;//返回给小程序}以上就是全部代码,还有小程序的支付回调没有什么信息,所以,我的思路判断success后进行跳转带参//此代码为wx.requestPayment success,部分代码省略//res 回调参数包括用户uid及其他重要传递success:function(res){wx.redirect({url:'pages/pay/done?uid='+res.uid})}当然那个统一下单的 notify_url 好像与回调有关,至于怎么用,试了几次回调的CURD都没反应,所以有空再研究啦。
以上代码仅作为支付流程解释,所以真正要用到项目上,还是去套官方的SDK吧,毕竟涉及到钱嘛
相关推荐:
微信小程序和支付宝小程序对比区别介绍
微信小程序如何从0开始进入支付
微信小程序微信支付接入开发
以上就是微信小程序支付的流程问题解析(代码解析)的详细内容,更多请关注小潘博客其它相关文章!