前台代码:
参数解释:
用户点击对应等级时,对应获取到需要支付的金额,在获取到用户的对应id和openid
这里的openid和user_id都是在用户登录授权后获取的信息
/* * author:咔咔 * address:陕西西安 * wechat:fangkangfk * content:微信小程序支付 * */ pay: function (e) { // 获取到需要支付的价钱 var price = e.currentTarget.dataset.price; var user_id = wx.getStorageSync('user_id'); // 验证是否获取到值 if (typeof (price) == "undefined") { wx.showToast({ title: '支付数据错误' }) return false; } //后台订单生成 wxb.Post('/api/automatic.pay/creatOrder', { openid: wxb.getOpenId(), price: price, user_id: user_id }, function (data) { var data = JSON.parse(data); console.log(data) wx.requestPayment({ 'timeStamp': data.timeStamp, 'nonceStr': data.nonceStr, 'package': data.package, 'signType': 'MD5', 'paySign': data.paySign, 'success': function (res) { wxb.Post('/api/cards.member/confirm_integral', { // 支付成功的业务逻辑代码 }, function (datas) { wx.redirectTo({ url: '/pages/mine/index' }) }); }, 'fail': function (res) { wxb.Post('/api/cards.member/confirm_integral', { // 支付失败或者取消支付代码 }, function (datas) { }); } }); }); },
后台代码:
获取到前台传的数据,进行创建订单,在进行请求获取统一下单的数据
public function creatOrder(){ $orderData = $this->request->param(); $opneid = $orderData['openid']; if($orderData['user_id']){ //appid $data['member_miniapp_id'] = $orderData['appid']; //支付金额 $data['pay_money'] = $orderData['price']; //用户id $data['user_id'] = $orderData['user_id']; $orderModel = new OrderModel(); $order = $orderModel->save($data); if($order){ //获取到订单id $orderId = $orderModel->order_id; //支付的金额 $orderPrice = $orderModel->pay_money; } if($orderId>=0){ $orderinfo = $this->buy($opneid); $this->result($orderinfo, 200, '订单生成成功', 'json'); } } } public function buy($opneid){ $params = [ 'appid' => '小程序id', 'mch_id' => '商户号', // 随机串,32字符以内 'nonce_str' => (string) mt_rand(10000, 99999), // 商品名 'body' => '购买vip', // 订单号,自定义,32字符以内。多次支付时如果重复的话,微信会返回“重复下单” 'out_trade_no' => '20170823001' . time(), // 订单费用,单位:分 'total_fee' => 1, 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], // 支付成功后的回调地址,服务端不一定真得有这个地址 'notify_url' => 'https://myserver.com/notify.php', 'trade_type' => 'JSAPI', // 小程序传来的OpenID 'openid' =>$opneid, ]; // 按照要求计算sign ksort($params); $sequence = ''; foreach ($params as $key => $value) { $sequence .= "$key=$value&"; } $sequence = $sequence . "key=你的秘钥"; $params['sign'] = strtoupper(md5($sequence)); // 给微信发出的请求,整个参数是个XML $xml = '<xml>' . PHP_EOL; foreach ($params as $key => $value) { $xml .= "<$key>$value</$key>" . PHP_EOL; } $xml .= '</xml>'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://api.mch.weixin.qq.com/pay/unifiedorder'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $output = curl_exec($ch); if (false === $output) { echo 'CURL Error:' . curl_error($ch); } // 下单成功的话,微信返回个XML,里面包含prepayID,提取出来 if (0 === preg_match('/<prepay_id><\!\[CDATA\[(\w+)\]\]><\/prepay_id>/', $output, $match)) { echo $output; exit(0); } // 这里不是给小程序返回个prepayID,而是返回一个包含其他字段的JSON // 这个JSON小程序自己也可以生成,放在服务端生成是出于两个考虑: // // 1. 小程序的appid不用写在小程序的代码里,appid、secret信息全部由服务器管理,比较安全 // 2. 计算paySign需要用到md5,小程序端使用的是JavaScript,没有内置的md5函数,放在服务端计算md5比较方便 $prepayId = $match[1]; $response= [ 'appId' => '小程序id', // 随机串,32个字符以内 'nonceStr' => (string) mt_rand(10000, 99999), // 微信规定 'package' => 'prepay_id=' . $prepayId, 'signType' => 'MD5', // 时间戳,注意得是字符串形式的 'timeStamp' => (string) time(), ]; $sequence = ''; foreach ($response as $key => $value) { $sequence .= "$key=$value&"; } $response['paySign'] = strtoupper(md5("{$sequence}key=你的秘钥")); return json_encode($response); }
测试结果: