미니프로그램 결제 기능 구현 방법

coldplay.xixi
풀어 주다: 2020-08-31 10:41:06
원래의
13102명이 탐색했습니다.

미니 프로그램의 결제 기능을 구현하는 방법: 먼저 프런트 엔드에서 결제를 요청하고 백엔드에서 WeChat 서버를 요청한 다음 백엔드에서 WeChat 서버를 수락하고 데이터를 반환합니다. 프런트엔드가 결제를 시작하고 마지막으로 백엔드가 WeChat 서버 콜백을 수락합니다.

미니프로그램 결제 기능 구현 방법

[관련 학습 권장사항: 미니 프로그램 개발 튜토리얼]

미니 프로그램 결제 기능 구현 방법:

1 프론트엔드 결제 요청

Fron t- 결제 요청 종료, 즉 사용자 ID, 결제 금액, 결제 주문 ID 등 결제에 필요한 데이터를 간단히 휴대합니다. 귀하의 비즈니스 로직과 관련된 데이터 또는 WeChat 서버에 결제를 요청하는 다음 단계에 필요한 데이터 통합 주문 인터페이스**는 WeChat을 사용하세요. 미니 프로그램의 wx.request( )는 백엔드 결제 인터페이스를 요청합니다. wx.request( ) 去请求后端的支付接口。

2. 后端请求微信服务器

后端接收到前端发送的支付请求后,可以进行一下相关验证,例如判断一下用户有没有问题,支付金额对不对等等。在验证没什么问题,可以向微信服务器申请支付之后,后端需要使用微信规定的数据格式 去请求微信的支付统一下单接口。

在处理好所有数据后,将这些数据以 XML 格式整理并以 POST 方法发送到微信支付统一下单接口

3.后端接受微信服务器返回数据

微信服务器在接收到支付数据之后,如果数据没有问题,其会返回用于支付的相应数据,其中非常重要的是 名称为 prepay_id 的数据字段,需要将此数据返回前端,前端才能继续支付。

因此,在后端接收到微信服务器的返回数据后,需要进行相应的处理,最终返回到前端数据,后端的支付接口已经完成了接收前端支付请求,并返回了前端支付所需数据的功能。

4. 前端发起支付

前端在接收到返回数据后,使用 wx.requestPayment()来请求发起支付。此 API 需要的对象参数各项值就是我们上一步返回的各个数据。

5.后端接受微信服务器回调

前端完成支付后,微信服务器确认支付已经完成。就会向第一步中设置的回调地址发送通知。后端的接收回调接口在接收到通知后,就可以判断支付是否完成,从而决定后续动作。

确认支付后,微信服务器会根据通知result_code

2. 백엔드는 위챗 서버에 요청

백엔드는 프론트엔드에서 보낸 결제 요청을 받은 후 사용자에게 문제가 있는지, 결제 금액이 맞는지 확인하는 등 관련 확인을 수행할 수 있습니다. , 등. 문제가 없고 WeChat 서버에 결제를 신청할 수 있음을 확인한 후 백엔드는 WeChat에서 지정한 데이터 형식을 사용하여 WeChat의 통합 결제 주문 인터페이스를 요청해야 합니다.

모든 데이터를 처리한 후 데이터를 XML 형식으로 구성하고 POST 메서드를 사용하여 WeChat 결제 통합 주문 인터페이스로 보냅니다.

3. 백엔드는 WeChat 서버에서 반환된 데이터를 수락합니다

WeChat 서버는 이후 결제 데이터에 문제가 없으면 결제를 위해 해당 데이터를 반환합니다. 가장 중요한 것은 prepay_id라는 데이터 필드입니다. 계속해서 지불하세요.
🎜따라서 백엔드가 WeChat 서버로부터 반환 데이터를 받은 후 해당 처리를 수행하고 최종적으로 데이터를 프런트엔드에 반환해야 합니다. 결제 요청을 종료하고 선결제에 필요한 데이터를 반환합니다. 🎜🎜🎜4. 프런트 엔드에서 결제 시작🎜🎜🎜반환 데이터를 받은 후 프런트 엔드에서는 wx.requestPayment()를 사용하여 결제 시작을 요청합니다. 이 API에 필요한 객체 매개변수의 값은 이전 단계에서 반환된 데이터입니다. 🎜🎜🎜5. 백엔드는 WeChat 서버 콜백을 허용합니다🎜🎜🎜프론트엔드가 결제를 완료한 후 WeChat 서버는 결제가 완료되었음을 확인합니다. 첫 번째 단계에서 설정한 콜백 주소로 알림이 전송됩니다. 알림을 받은 후 백엔드 수신 콜백 인터페이스는 결제 완료 여부를 확인하고 후속 조치를 결정할 수 있습니다. 🎜🎜결제 확인 후 WeChat 서버는 알림 result_code 필드를 기반으로 결제 성공 여부를 판단합니다. 성공적인 알림을 받은 후 백엔드는 성공 데이터를 WeChat 서버에 반환하여 결제 프로세스를 완료하기 위한 콜백 알림이 수신되었음을 WeChat 서버에 알려야 합니다. 그렇지 않으면 WeChat 서버는 계속해서 백엔드에 메시지를 보냅니다. 🎜🎜비교해 보면 실제로 공식 계정으로 결제하는 것보다 미니 프로그램에서 결제하는 것이 훨씬 쉬운 것을 알 수 있습니다. 왜냐하면 승인된 디렉토리에 대한 비용을 지불할 필요도 없고, 도메인 이름을 승인할 필요도 없기 때문입니다. 그러나 결제 프로세스에는 공식 계정보다 한 단계 더 많은 단계가 있습니다. 즉, 통합 주문 선불이며 결제가 시작되기 전에 선불 결과에 다시 서명해야 합니다. 🎜🎜🎜완전한 코드는 다음과 같습니다. 🎜🎜
//小程序端代码:
pay:function(){
var that=this
wx.getStorage({
key: 'openid',
success: function(res) {
wx.request({
//这里是后台的处理方法,url是自定义的,直接换成你自己的后台处理方法即可,Wx_Pay这个方法在下面写的有
//后台用的php做处理,java的可以参考方法,道理都是一样的
url: url + 'Wx_Pay',
data: {
//用户的openid
openid:res.data,
fee: that.data.totalPrice, //支付金额
details: that.data.goodsList[0].goods_name,//支付商品的名称
},
success:function(result){
if(result.data){
//out_trade_no=res.data['out_trade_no'];
wx.requestPayment({
timeStamp: result.data['timeStamp'],
nonceStr: result.data['nonceStr'],
package: result.data['package'],
signType: 'MD5',
paySign: result.data['paySign'],
'success':function(successret){
console.log('支付成功');
//获取支付用户的信息
wx.getStorage({
key: 'userInfo',
success: function (getuser) {
//加入订单表做记录
wx.request({
url: url + 'Wx_AddOrder',
data: {
uname: getuser.data.nickName,
goods: that.data.goodsList[0].goods_name,
price: that.data.totalPrice,
openid:res.data,
},
success: function (lastreturn) {
console.log("存取成功");
}
})
},
})
},'fail':function(res){
}
})
}
}
})
},
})
},
//后台
//微信支付
    public function Wx_Pay(){
        $request=Request::instance();
        $fee=$request->param('fee');
        $details=$request->param('details');//商品的详情,比如iPhone8,紫色
       // $fee = 0.01;//举例充值0.01
        $appid =        'appid';//appid
        $body =        $details;// '金邦汇商城';//'【自己填写】'
        $mch_id =       '1486742092';//'你的商户号【自己填写】'
        $nonce_str =    $this->nonce_str();//随机字符串
        $notify_url =   'https://zys.jinbh.cn/admin/Api/Wx_Speech';//回调的url【自己填写】';
        $openid =       $request->param('openid');//'用户的openid【自己填写】';
        $out_trade_no = $this->order_number($openid);//商户订单号
        $spbill_create_ip = '123.206.45.131';//'服务器的ip【自己填写】';
        $total_fee =    $fee*100;//因为充值金额最小是1 而且单位为分 如果是充值1元所以这里需要*100
        $trade_type = 'JSAPI';//交易类型 默认
        //这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错
        $post['appid'] = $appid;
        $post['body'] = $body;
        
        $post['mch_id'] = $mch_id;
      
        $post['nonce_str'] = $nonce_str;//随机字符串
      
        $post['notify_url'] = $notify_url;
      
        $post['openid'] = $openid;
      
        $post['out_trade_no'] = $out_trade_no;
      
        $post['spbill_create_ip'] = $spbill_create_ip;//终端的ip
      
        $post['total_fee'] = $total_fee;//总金额 最低为一块钱 必须是整数
     
        $post['trade_type'] = $trade_type;
        $sign = $this->sign($post);//签名
        $post_xml = &#39;<xml>
           <appid>&#39;.$appid.&#39;</appid>
           <body>&#39;.$body.&#39;</body>
           <mch_id>&#39;.$mch_id.&#39;</mch_id>
           <nonce_str>&#39;.$nonce_str.&#39;</nonce_str>
           <notify_url>&#39;.$notify_url.&#39;</notify_url>
           <openid>&#39;.$openid.&#39;</openid>
           <out_trade_no>&#39;.$out_trade_no.&#39;</out_trade_no>
           <spbill_create_ip>&#39;.$spbill_create_ip.&#39;</spbill_create_ip>
           <total_fee>&#39;.$total_fee.&#39;</total_fee>
           <trade_type>&#39;.$trade_type.&#39;</trade_type>
           <sign>&#39;.$sign.&#39;</sign>
        </xml> &#39;;
        //统一接口prepay_id
        $url = &#39;https://api.mch.weixin.qq.com/pay/unifiedorder&#39;;
        $xml = $this->http_request($url,$post_xml);
        $array = $this->xml($xml);//全要大写
        if($array[&#39;RETURN_CODE&#39;] == &#39;SUCCESS&#39; && $array[&#39;RESULT_CODE&#39;] == &#39;SUCCESS&#39;){
            $time = time();
            $tmp=&#39;&#39;;//临时数组用于签名
            $tmp[&#39;appId&#39;] = $appid;
            $tmp[&#39;nonceStr&#39;] = $nonce_str;
            $tmp[&#39;package&#39;] = &#39;prepay_id=&#39;.$array[&#39;PREPAY_ID&#39;];
            $tmp[&#39;signType&#39;] = &#39;MD5&#39;;
            $tmp[&#39;timeStamp&#39;] = "$time";
            $data[&#39;state&#39;] = 1;
            $data[&#39;timeStamp&#39;] = "$time";//时间戳
            $data[&#39;nonceStr&#39;] = $nonce_str;//随机字符串
            $data[&#39;signType&#39;] = &#39;MD5&#39;;//签名算法,暂支持 MD5
            $data[&#39;package&#39;] = &#39;prepay_id=&#39;.$array[&#39;PREPAY_ID&#39;];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
            $data[&#39;paySign&#39;] = $this->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
            $data[&#39;out_trade_no&#39;] = $out_trade_no;
        }else{
            $data[&#39;state&#39;] = 0;
            $data[&#39;text&#39;] = "错误";
            $data[&#39;RETURN_CODE&#39;] = $array[&#39;RETURN_CODE&#39;];
            $data[&#39;RETURN_MSG&#39;] = $array[&#39;RETURN_MSG&#39;];
        }
      echo json_encode($data);
    }
//随机32位字符串
    private function nonce_str(){
        $result = &#39;&#39;;
        $str = &#39;QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz&#39;;
        for ($i=0;$i<32;$i++){
            $result .= $str[rand(0,48)];
        }
        return $result;
    }
//生成订单号
    private function order_number($openid){
        //date(&#39;Ymd&#39;,time()).time().rand(10,99);//18位
        return md5($openid.time().rand(10,99));//32位
    }
//签名 $data要先排好顺序
    public function sign($data)
    {
        $stringA = &#39;&#39;;
        foreach ($data as $key => $value) {
            if (!$value) continue;
            if ($stringA) $stringA .= &#39;&&#39; . $key . "=" . $value;
            else $stringA = $key . "=" . $value;
        }
        $wx_key = &#39;Zhangyusheng19810318015729366660&#39;;//申请支付后有给予一个商户账号和密码,登陆后自己设置key
        $stringSignTemp = $stringA . &#39;&key=&#39; . $wx_key;//申请支付后有给予一个商户账号和密码,登陆后自己设置key 
      return strtoupper(md5($stringSignTemp));
    }
//curl请求啊
        function http_request($url, $data = null, $headers = array())
        {
            $curl = curl_init();
            if (count($headers) >= 1) {
                curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            }
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
            if (!empty($data)) {
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $output = curl_exec($curl);
            curl_close($curl);
            return $output;
        }
//获取xml
        private function xml($xml){
            $p = xml_parser_create();
            xml_parse_into_struct($p, $xml, $vals, $index);
            xml_parser_free($p);
            $data = "";
            foreach ($index as $key=>$value) {
                if($key == &#39;xml&#39; || $key == &#39;XML&#39;) continue;
                $tag = $vals[$value[0]][&#39;tag&#39;];
                $value = $vals[$value[0]][&#39;value&#39;];
                $data[$tag] = $value;
            }
            return $data;
        }
//微信支付结束
로그인 후 복사
🎜🎜프로그래밍에 대해 더 자세히 알고 싶다면 🎜php training🎜 칼럼을 주목해주세요! 🎜🎜🎜

위 내용은 미니프로그램 결제 기능 구현 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!