小程序开发 —— 微信支付
<p><span style="color: rgba(51, 102, 255, 1); font-size: 18px">小程序很好入门,做一个完整的商城也很方便。</span></p><p><span style="color: rgba(51, 102, 255, 1); font-size: 18px">对于微信产品,用微信支付也是顺理成章的。</span></p>
<p><span style="color: rgba(51, 102, 255, 1); font-size: 18px">本文的后台用 Laravel 实现(easywechat)。</span></p>
<p> </p>
<p><span style="font-size: 18px"><strong><span style="color: rgba(51, 102, 255, 1)">一、前期准备</span></strong></span></p>
<p><strong><span style="font-size: 16px">1、小程序 appid;</span></strong></p>
<p><strong><span style="font-size: 16px">2、微信商户号;</span></strong></p>
<p><strong><span style="font-size: 16px">3、商户秘钥;</span></strong></p>
<p> </p>
<p><span style="font-size: 18px"><strong><span style="color: rgba(51, 102, 255, 1)">二、小程序部分</span></strong></span></p>
<p><span style="font-size: 16px"><strong>1、支付按钮绑定 pay 事件</strong></span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 15px"><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">button </span><span style="color: rgba(255, 0, 0, 1)">bindtap</span><span style="color: rgba(0, 0, 255, 1)">="pay"</span><span style="color: rgba(255, 0, 0, 1)"> data-oid</span><span style="color: rgba(0, 0, 255, 1)">="{{item.order_id}}"</span><span style="color: rgba(0, 0, 255, 1)">></span>付款<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">button</span><span style="color: rgba(0, 0, 255, 1)">></span></span></pre>
</div>
<p><strong><span style="font-size: 16px">2、编写 pay 方法</span></strong></p>
<p><span style="font-size: 16px">思路:调用后台接口返回一些数据,然后在小程序端调用 wx.requestPayment 返回支付结果是否成功。</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 15px"><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* 付款
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
pay: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (e) {
wx.request({
url: app.globalData.baseUrl </span>+ 'api/wechat/pay'<span style="color: rgba(0, 0, 0, 1)">,
method: </span>'POST'<span style="color: rgba(0, 0, 0, 1)">,
data: {
openId: app.globalData.openid,
orderId: e.currentTarget.dataset.oid,
appId: app.globalData.appId
},
header: {
</span>'Content-Type': 'application/json'<span style="color: rgba(0, 0, 0, 1)">
},
success: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (res) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> data =<span style="color: rgba(0, 0, 0, 1)"> res.data.data;
wx.requestPayment({
</span>'timeStamp'<span style="color: rgba(0, 0, 0, 1)">: data.timeStamp,
</span>'nonceStr'<span style="color: rgba(0, 0, 0, 1)">: data.nonceStr,
</span>'package'<span style="color: rgba(0, 0, 0, 1)">: data.package,
</span>'signType'<span style="color: rgba(0, 0, 0, 1)">: data.signType,
</span>'paySign'<span style="color: rgba(0, 0, 0, 1)">: data.paySign,
</span>'success': <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (res) {
wx.showToast({
title: </span>'支付成功'<span style="color: rgba(0, 0, 0, 1)">,
icon: </span>'success'<span style="color: rgba(0, 0, 0, 1)">,
duration: </span>2000<span style="color: rgba(0, 0, 0, 1)">
});
},
</span>'fail': <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (res) {
wx.showToast({
title: </span>'支付失败'<span style="color: rgba(0, 0, 0, 1)">,
icon: </span>'none'<span style="color: rgba(0, 0, 0, 1)">,
duration: </span>2000<span style="color: rgba(0, 0, 0, 1)">
});
}
});
}
})
},</span></span></pre>
</div>
<p> </p>
<p><span style="color: rgba(51, 102, 255, 1); font-size: 18px"><strong>三、后台部分</strong></span></p>
<p><span style="font-size: 16px">思路:安装 wechat 开发包,配置小程序及支付信息,调用方法生成支付订单,进行二次签名返回数据给小程序。</span></p>
<p><strong><span style="font-size: 16px">1、安装 wechat 开发包</span></strong></p>
<div class="cnblogs_code">
<pre><span style="font-size: 15px">composer require overtrue/wechat -<span style="color: rgba(0, 0, 0, 1)">vvv
php artisan vendor:publish </span>--provider=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Overtrue\LaravelWeChat\ServiceProvider</span><span style="color: rgba(128, 0, 0, 1)">"</span></span></pre>
</div>
<p><strong><span style="font-size: 16px">2、配置基本信息</span></strong></p>
<p><span style="font-size: 16px">在第一步生成的 config/wechat.php 文件中,修改成自己的信息。</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 15px"><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
* 小程序配置
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
'mini_program' =><span style="color: rgba(0, 0, 0, 1)"> [
</span>'default' =><span style="color: rgba(0, 0, 0, 1)"> [
</span>'app_id'=> env('WECHAT_MINI_PROGRAM_APPID', ''),
'secret'=> env('WECHAT_MINI_PROGRAM_SECRET', ''),
'token' => env('WECHAT_MINI_PROGRAM_TOKEN', ''),
'aes_key' => env('WECHAT_MINI_PROGRAM_AES_KEY', ''),<span style="color: rgba(0, 0, 0, 1)">
]</span>,<span style="color: rgba(0, 0, 0, 1)">
]</span>,
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
* 微信支付配置
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
'payment' =><span style="color: rgba(0, 0, 0, 1)"> [
</span>'default' =><span style="color: rgba(0, 0, 0, 1)"> [
</span>'sandbox' => env('WECHAT_PAYMENT_SANDBOX', <span style="color: rgba(0, 0, 255, 1)">false</span>),
'app_id' => env('WECHAT_PAYMENT_APPID', ''),
'mch_id' => env('WECHAT_PAYMENT_MCH_ID', 'your-mch-id'),
'key' => env('WECHAT_PAYMENT_KEY', 'key-for-signature'),
'cert_path' => env('WECHAT_PAYMENT_CERT_PATH', 'path/to/cert/apiclient_cert.pem'),
'key_path' => env('WECHAT_PAYMENT_KEY_PATH', 'path/to/cert/apiclient_key.pem'),
'notify_url' => 'http://example.com/payments/wechat-notify', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Default payment result notification address</span>
],
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...</span>
],</span></pre>
</div>
<p><strong><span style="font-size: 16px">3、支付功能</span></strong></p>
<div class="cnblogs_code">
<pre><span style="font-size: 15px"><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> __construct(Request <span style="color: rgba(128, 0, 128, 1)">$request</span>
, Order <span style="color: rgba(128, 0, 128, 1)">$order</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(128, 0, 128, 1)">$wechat</span> = \EasyWeChat::<span style="color: rgba(0, 0, 0, 1)">miniProgram();
</span><span style="color: rgba(128, 0, 128, 1)">$pay</span> = \EasyWeChat::<span style="color: rgba(0, 0, 0, 1)">payment();
</span><span style="color: rgba(128, 0, 128, 1)">$this</span>->wechat = <span style="color: rgba(128, 0, 128, 1)">$wechat</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$this</span>->pay = <span style="color: rgba(128, 0, 128, 1)">$pay</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$this</span>->request = <span style="color: rgba(128, 0, 128, 1)">$request</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$this</span>->order = <span style="color: rgba(128, 0, 128, 1)">$order</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* 通过 js_code 获取 openid
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getOpenId(){
</span><span style="color: rgba(128, 0, 128, 1)">$code</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->request-><span style="color: rgba(0, 0, 0, 1)">js_code;
</span><span style="color: rgba(128, 0, 128, 1)">$out</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->wechat->auth->session(<span style="color: rgba(128, 0, 128, 1)">$code</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->success(<span style="color: rgba(128, 0, 128, 1)">$out</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* wechat pay
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> pay(){
</span><span style="color: rgba(128, 0, 128, 1)">$appid</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->request-><span style="color: rgba(0, 0, 0, 1)">appId;
</span><span style="color: rgba(128, 0, 128, 1)">$openid</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->request-><span style="color: rgba(0, 0, 0, 1)">openId;
</span><span style="color: rgba(128, 0, 128, 1)">$orderid</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->request-><span style="color: rgba(0, 0, 0, 1)">orderId;
</span><span style="color: rgba(128, 0, 128, 1)">$order</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->order->findOrFail(<span style="color: rgba(128, 0, 128, 1)">$orderid</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(! <span style="color: rgba(128, 0, 128, 1)">$order</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->failed('order is not exist!'<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> generate order</span>
<span style="color: rgba(128, 0, 128, 1)">$out</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->pay->order-><span style="color: rgba(0, 0, 0, 1)">unify([
</span>'body' => 'order name', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> order name</span>
'out_trade_no'=> <span style="color: rgba(128, 0, 128, 1)">$order</span>->order_num, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> order number</span>
'trade_type' => 'JSAPI', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> must 'JSAPI'</span>
'openid' => <span style="color: rgba(128, 0, 128, 1)">$openid</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> user openid</span>
'total_fee' => <span style="color: rgba(128, 0, 128, 1)">$order</span>->price, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> order total price</span>
<span style="color: rgba(0, 0, 0, 1)"> ]);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> second sign</span>
<span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(128, 0, 128, 1)">$out</span>['return_code'] == 'success'<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(128, 0, 128, 1)">$param</span> =<span style="color: rgba(0, 0, 0, 1)"> [
</span>'appId' => <span style="color: rgba(128, 0, 128, 1)">$appid</span>,
'timeStamp' => <span style="color: rgba(0, 128, 128, 1)">time</span>(),
'nonceStr'=> <span style="color: rgba(128, 0, 128, 1)">$out</span>['nonce_str'],
'package' => 'prepay_id=' . <span style="color: rgba(128, 0, 128, 1)">$out</span>['prepay_id'],
'signType'=> 'MD5',<span style="color: rgba(0, 0, 0, 1)">
];
<br> // 注意文件最上面添加 use function EasyWeChat\Kernel\Support\generate_sign;
</span><span style="color: rgba(128, 0, 128, 1)">$params</span>['paySign'] = generate_sign(<span style="color: rgba(128, 0, 128, 1)">$params</span>, config('wechat.payment.default.key'<span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->success(<span style="color: rgba(128, 0, 128, 1)">$param</span><span style="color: rgba(0, 0, 0, 1)">);
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->failed('wechat pay failed!'<span style="color: rgba(0, 0, 0, 1)">);
}
}</span></span></pre>
</div>
<p><strong><span style="font-size: 16px">4、支付结果通知</span></strong></p>
<p><span style="font-size: 16px">支付回调路径在上面配置文件中已经设置好了。</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 15px"> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* payment result notify
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> notify(){
</span><span style="color: rgba(128, 0, 128, 1)">$res</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->wechat->handlePaidNotify(<span style="color: rgba(0, 0, 255, 1)">function</span>(<span style="color: rgba(128, 0, 128, 1)">$message</span>, <span style="color: rgba(128, 0, 128, 1)">$fail</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> find order</span>
<span style="color: rgba(128, 0, 128, 1)">$order</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->order->where('order_num', <span style="color: rgba(128, 0, 128, 1)">$message</span>['out_trade_no'])-><span style="color: rgba(0, 0, 0, 1)">get();
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(128, 0, 128, 1)">$order</span> || <span style="color: rgba(128, 0, 128, 1)">$order</span>->status == 3<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> payment finish</span>
<span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(128, 0, 128, 1)">$message</span>['return_code'] == 'SUCCESS'<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> payment success</span>
<span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(128, 0, 128, 1)">$message</span>['result_code'] == 'SUCCESS'<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(128, 0, 128, 1)">$order</span>->status = 3<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(128, 0, 128, 1)">$order</span>-><span style="color: rgba(0, 0, 0, 1)">save();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> payment fail</span>
}<span style="color: rgba(0, 0, 255, 1)">elseif</span>(<span style="color: rgba(128, 0, 128, 1)">$message</span>['result_code'] == 'FAIL'<span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$fail</span>('payment fail'<span style="color: rgba(0, 0, 0, 1)">);
}
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$fail</span>('connect fail'<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
});
</span><span style="color: rgba(128, 0, 128, 1)">$res</span>-><span style="color: rgba(0, 0, 0, 1)">send();
}</span></span></pre>
</div>
<p> </p>
<p><span style="font-size: 18px"><strong><span style="color: rgba(51, 102, 255, 1)">四、调试</span></strong></span></p>
<p>。。</p>
<p> </p><br><br>
来源:https://www.cnblogs.com/rendd/p/11759506.html
頁:
[1]