Method to implement the mini program payment function: first request payment on the front end, and request the WeChat server on the back end; then the back end accepts the WeChat server and returns the data; then the front end initiates payment; finally the back end accepts the WeChat server callback That’s it.
【Related learning recommendations: 小program development tutorial】
Methods to implement the mini program payment function:
1. Front-end request for payment
Front-end request for payment is to simply carry the payment requirements Data, such as user ID, payment amount, payment order ID, etc. are related to your business logic or related to the data required for the next step of requesting the WeChat server payment unified order interface**, use the of the WeChat applet wx.request( )
To request the backend payment interface.
2. The backend requests the WeChat server
After the backend receives the payment request sent by the frontend, it can perform related verifications, such as determining whether the user has any problems. Is the payment amount correct, etc.? After verifying that there is no problem and you can apply for payment to the WeChat server, the backend needs to use the data format specified by WeChat to request WeChat's unified payment order interface.
After processing all the data, organize the data in XML format and send it to the WeChat payment unified ordering interface using the POST method
3. The backend accepts the data returned by the WeChat server
After the WeChat server receives the payment data, if there is no problem with the data, it will return the corresponding data for payment. The most important one is the data field named prepay_id, which needs to be returned. Front-end, the front-end can continue to pay.
Therefore, after the back-end receives the return data from the WeChat server, it needs to perform corresponding processing and finally return the data to the front-end. The back-end payment interface has completed receiving the front-end payment request and returned the front-end payment request. Functions that require data.
4. Front-end initiates payment
After receiving the returned data, the front-end uses wx.requestPayment()
to request payment initiation. The values of the object parameters required by this API are the data returned in the previous step.
5. The backend accepts the WeChat server callback
After the frontend completes the payment, the WeChat server confirms that the payment has been completed. A notification will be sent to the callback address set in the first step. After receiving the notification, the back-end receiving callback interface can determine whether the payment is completed and determine subsequent actions.
After confirming the payment, the WeChat server will determine whether the payment was successful based on the notification result_code
field. After receiving the successful notification, the backend needs to return success data to the WeChat server to inform the WeChat server that a callback notification has been received to complete the payment process. Otherwise, the WeChat server will continue to send messages to the backend.
After comparison, it can be found that in fact, payment in the mini program is much easier than payment with the official account, because there is no need to pay for the authorized directory or authorized domain name, but the payment process has one more step than the official account. That is, the unified order is prepaid, and then the prepaid result needs to be signed again before payment can be initiated.
The complete code is as follows:
//小程序端代码: 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 = '<xml> <appid>'.$appid.'</appid> <body>'.$body.'</body> <mch_id>'.$mch_id.'</mch_id> <nonce_str>'.$nonce_str.'</nonce_str> <notify_url>'.$notify_url.'</notify_url> <openid>'.$openid.'</openid> <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> <sign>'.$sign.'</sign> </xml> '; //统一接口prepay_id $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; $xml = $this->http_request($url,$post_xml); $array = $this->xml($xml);//全要大写 if($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS'){ $time = time(); $tmp='';//临时数组用于签名 $tmp['appId'] = $appid; $tmp['nonceStr'] = $nonce_str; $tmp['package'] = 'prepay_id='.$array['PREPAY_ID']; $tmp['signType'] = 'MD5'; $tmp['timeStamp'] = "$time"; $data['state'] = 1; $data['timeStamp'] = "$time";//时间戳 $data['nonceStr'] = $nonce_str;//随机字符串 $data['signType'] = 'MD5';//签名算法,暂支持 MD5 $data['package'] = 'prepay_id='.$array['PREPAY_ID'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=* $data['paySign'] = $this->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档; $data['out_trade_no'] = $out_trade_no; }else{ $data['state'] = 0; $data['text'] = "错误"; $data['RETURN_CODE'] = $array['RETURN_CODE']; $data['RETURN_MSG'] = $array['RETURN_MSG']; } echo json_encode($data); } //随机32位字符串 private function nonce_str(){ $result = ''; $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz'; for ($i=0;$i<32;$i++){ $result .= $str[rand(0,48)]; } return $result; } //生成订单号 private function order_number($openid){ //date('Ymd',time()).time().rand(10,99);//18位 return md5($openid.time().rand(10,99));//32位 } //签名 $data要先排好顺序 public function sign($data) { $stringA = ''; foreach ($data as $key => $value) { if (!$value) continue; if ($stringA) $stringA .= '&' . $key . "=" . $value; else $stringA = $key . "=" . $value; } $wx_key = 'Zhangyusheng19810318015729366660';//申请支付后有给予一个商户账号和密码,登陆后自己设置key $stringSignTemp = $stringA . '&key=' . $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 == 'xml' || $key == 'XML') continue; $tag = $vals[$value[0]]['tag']; $value = $vals[$value[0]]['value']; $data[$tag] = $value; } return $data; } //微信支付结束
If you want to learn more about programming, please pay attention to the php training column!
The above is the detailed content of How to implement mini program payment function. For more information, please follow other related articles on the PHP Chinese website!