企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 服务器端PHP: ~~~ // 根据业务逻辑组装订单保存订单数据 $order = [ 'member_id' => $member->id, 'amount' => $amount, 'status' => 1, 'prepay_id' => 0, 'prepay_result' => '' ]; $order = ChargeOrder::create($order); // 补充订单序列号 // 根据业务逻辑生成订单序列号 $serial = $this->generateChargeOrderSerial($order->id); $order->serial = $serial; $order->save(); // 生成微信预支付订单 $payment = EasyWeChat::payment(); $result = $payment->order->unify([ 'body' => '聊播会员充值', 'out_trade_no' => $order->serial, 'total_fee' => $amount * 100, // 金额,单位是分,不是元 'spbill_create_ip' => null, // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址 'notify_url' => route('wx.pay.notify'), // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 'openid' => $member->wx_open_id, ]); // 生成微信订单 $payment = EasyWeChat::payment(); // 微信支付 $result = $payment->order->unify([ 'body' => '聊播会员充值', 'out_trade_no' => $order->serial, 'total_fee' => $amount * 100, 'spbill_create_ip' => null, // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址 'notify_url' => route('wx.pay.notify'), // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 'openid' => $member->wx_open_id, ]); if (strtoupper($result['return_code']) != 'SUCCESS') { $errorMessage = $result['return_msg']; Log::error('创建微信预支付订单失败,错误信息:' . $errorMessage); return $this->responseError(ERROR_UNKNOWN, '创建订单失败'); } if (strtoupper($result['result_code']) != 'SUCCESS') { $errorCode = $result['err_code']; $errorMessage = $result['err_code_des']; Log::error('创建微信预支付订单失败,错误码:' . $errorCode . ',错误信息:' . $errorMessage); return $this->responseError(ERROR_UNKNOWN, '创建订单失败'); } $prepayId = $result['prepay_id']; $order->prepay_id = $prepayId; $order->prepay_result = json_encode($result); $order->save(); ~~~ 接下来的服务器端程序有以下两种选择: ### 一、如果前端准备使用JSSDK,服务器端接着写下面的PHP代码 ~~~ // 配置参数 $officialAccount = EasyWeChat::officialAccount(); $apis = ['chooseWxPay']; $wxConfig = $officialAccount->jssdk->buildConfig($apis, false, false, false); // 支付参数 $payConfig = $payment->jssdk->sdkConfig($prepayId); // 返回数组 return $this->responseData(compact('payConfig', 'wxConfig')); ~~~ 返回的payConfig和wxConfig的格式如下: payConfig: ~~~ { appId:"wx86e4f20564c2f17e", beta:false, debug:false, jsApiList:["chooseWxPay"], nonceStr:"KPzKlY6QpD", signature:"767d1164d879a3c4e0a9ac69b16921de19fcdfb5", timestamp:1556085560, // 此处不是驼峰命名 url:"http://liaobo.com/member/charge" } ~~~ wxConfig ~~~ { appId:"wx86e4f20564c2f17e", beta:false, debug:false, jsApiList:["chooseWxPay"], nonceStr:"KPzKlY6QpD", signature:"767d1164d879a3c4e0a9ac69b16921de19fcdfb5", timestamp:1556085560, url:"http://liaobo.com/member/charge" } ~~~ ### 二、如果前端准备使用WeixinJSBridge,服务器端接着写下面的PHP代码 ~~~ $payConfig = $payment->jssdk->sdkConfig($prepayId); // 因为WeixinJSBridge使用的支付参数中,时间戳字段的键名是驼峰命名的timeStamp, // 所以这里要重新组装一下数据 $payConfig['timeStamp'] = $payConfig['timestamp']; unset($payConfig['timestamp']); return $this->responseData(compact('payConfig')); ~~~ 返回的payConfig数据格式如下: payConfig ~~~ { appId:"wx86e4f20564c2f17e", beta:false, debug:false, jsApiList:["chooseWxPay"], nonceStr:"KPzKlY6QpD", signature:"767d1164d879a3c4e0a9ac69b16921de19fcdfb5", timeStamp:1556085560, // 此处是驼峰命名 url:"http://liaobo.com/member/charge" } ~~~ ## 前端JS 如上所述,前端JS有两种方法: ### 前端使用JSSDK ~~~ <script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script> <script> $(function () { // 充值 $('#btn-charge').on('click', function () { showInputBox('充值', '100', function (amount, index) { if (amount < 0.01) { alert('充值金额太小'); return false; } var url = '{{route('member.charge.save')}}'; var row = {amount: amount, _token: token}; $.post(url, row, function (data, status, xhr) { if (data.code != 200) { var message = data.message; alert(message); return false; } var payConfig = data.data.payConfig; payConfig.success = function (res) { if (res.errMsg == 'chooseWXPay:ok') { alert('支付成功'); layer.close(index); window.location.reload(); } else { alert('支付失败,请重试:' + res.errMsg); } }; payConfig.fail = function (res) { alert('支付失败:' + JSON.stringify(res)); }; payConfig.cancel = function (res) { alert('用户取消付款'); }; wx.config(data.data.wxConfig); wx.chooseWXPay(payConfig); }, 'json'); }) }); }); </script> ~~~ ### 前端使用WeixinJSBridge > 不需要引入JSSDK了 ~~~ <script> $(function () { // 充值 $('#btn-charge').on('click', function () { showInputBox('充值', '100', function (amount, index) { if (amount < 0.01) { alert('充值金额太小'); return false; } var url = '{{route('member.charge.save')}}'; var row = {amount: amount, _token: token}; $.post(url, row, function (data, status, xhr) { if (data.code != 200) { var message = data.message; alert(message); return false; } var payConfig = data.data.payConfig; payConfig.timeStamp = payConfig.timestamp; WeixinJSBridge.invoke('getBrandWCPayRequest', payConfig, function(res){ if(res.err_msg == 'get_brand_wcpay_request:ok' ){ alert('支付成功'); layer.close(index); window.location.reload(); } else if (res.err_msg == 'get_brand_wcpay_request:cancel') { alert('用户取消支付'); } else { alert('支付失败'); } }); }, 'json'); }) }); }); </script> ~~~