>위챗 애플릿 >미니 프로그램 개발 >위챗 미니 프로그램 결제 프로세스 이슈 분석(코드 분석)

위챗 미니 프로그램 결제 프로세스 이슈 분석(코드 분석)

不言
不言원래의
2018-08-14 17:23:341730검색

이 글의 내용은 위챗 애플릿 결제 프로세스 문제 분석(코드 분석)에 관한 내용으로, 도움이 필요한 친구들이 참고하시면 좋겠습니다.

요즘에는 공식 SDK를 사용하지 않고 소규모 프로그램 결제를 진행하고 있습니다. 여기서는 공식 문서만 사용하겠습니다.

* 참고: PHP를 사용하지만 결제 과정은 이렇습니다

개발 전 꼭 읽어주세요

메인 프로세스

  • 미니 프로그램의 프런트 엔드에서 매개변수 요청 전송

  • 요청을 수락하고 encapsulate "unified order" Getpackagepackage

  • 小程序接受 “统一下单” 获取的package值带入wx.requestPayment发起支付请求

准备工具

  • 申请小程序微信支付

  • 拿到小程序微信支付的商户号及设置秘钥

注意:小程序就只需要这两步,如果是web的话还需要设置支付目录授权域名,文档里面也有写的:https://pay.weixin.qq.com/wik..

统一下单

官方文档: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'].'&notify_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));//大写MD5
    return $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

애플릿은 "통합 주문"을 허용하며 얻은 package 값은 다음과 같습니다. wx.requestPayment 로 가져옴 결제 요청 시작

준비 도구

Apply 미니 프로그램 위챗 결제

미니 프로그램 위챗 결제의 판매자 번호 및 설정 키 가져오기

참고: 미니 프로그램은 이 두 단계만 필요합니다. 웹인 경우 결제 디렉토리 인증 도메인 이름도 설정해야 합니다. https://pay.weixin. .qq.com/wik..

#🎜🎜 #UnifiedOrder

공식 문서: https://pay.weixin.qq.com/wik...#🎜 🎜#

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);
             }
         })  
    }
       
}
좋아, 이제 prepay_id를 얻었습니다. 통합 주문이 완료되더라도 Data Feng이라고 부르겠습니다

작은programWeChat Payment#🎜 🎜#

공식 문서: https:/ /developers.weixin.qq.... 에피소드부터 시작하겠습니다. 먼저 미니 프로그램의 프런트 엔드에서 결제가 실행되어야 합니다. 구현할 기능은 결제 전 미니 프로그램의 트리거를 클릭해야 합니다. 그렇죠.

/**
 * 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;//返回给小程序
}
api Payment

는 백엔드 요청 주소입니다. 위의 미니 프로그램 코드

//此代码为wx.requestPayment success,部分代码省略
//res 回调参数包括用户uid及其他重要传递
success:function(res){
    wx.redirect({
        url:'pages/pay/done?uid='+res.uid
    })
}
위의 코드가 전부이고, 미니 프로그램도 있습니다. 프로그램의 결제 콜백에는 정보가 없으므로 성공 여부를 판단한 후 매개변수로 점프하는 것이 제 생각입니다 # 🎜🎜#rrreee
물론 통합주문을 위한 inform_url은 콜백과 관련이 있는 것 같습니다. 여러번 시도해 보았는데 콜백 CURD에 대한 응답이 없어서 공부하겠습니다. 시간 있을 때 하세요.
#🎜🎜#위 코드는 결제 과정을 설명하기 위한 용도로만 사용되므로 꼭 프로젝트에 사용하려면 공식 SDK를 사용해야 합니다 #🎜🎜## 🎜🎜#관련 추천: #🎜 🎜##🎜🎜##🎜🎜##🎜🎜#WeChat 애플릿과 Alipay 애플릿의 비교 및 ​​차이점#🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜 #위챗애플릿 사용방법 0부터 결제입력 시작#🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#위챗애플릿 위챗 결제접근권 개발#🎜🎜##🎜🎜##🎜🎜# #🎜🎜#

위 내용은 위챗 미니 프로그램 결제 프로세스 이슈 분석(코드 분석)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.