半枝莲 發表於 2019-10-29 16:25:00

小程序开发 —— 微信支付

<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>&nbsp;</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>&nbsp;</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)">&lt;</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)">&gt;</span>付款<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">button</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></span></pre>
</div>
<p><strong><span style="font-size: 16px">2、编写 pay 方法</span></strong></p>
<p><span style="font-size: 16px">思路:调用后台接口返回一些数据,然后在小程序端调用&nbsp;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>&nbsp;</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">在第一步生成的&nbsp;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' =&gt;<span style="color: rgba(0, 0, 0, 1)"> [
    </span>'default' =&gt;<span style="color: rgba(0, 0, 0, 1)"> [
      </span>'app_id'=&gt; env('WECHAT_MINI_PROGRAM_APPID', ''),
      'secret'=&gt; env('WECHAT_MINI_PROGRAM_SECRET', ''),
      'token'   =&gt; env('WECHAT_MINI_PROGRAM_TOKEN', ''),
      'aes_key' =&gt; 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' =&gt;<span style="color: rgba(0, 0, 0, 1)"> [
    </span>'default' =&gt;<span style="color: rgba(0, 0, 0, 1)"> [
      </span>'sandbox'            =&gt; env('WECHAT_PAYMENT_SANDBOX', <span style="color: rgba(0, 0, 255, 1)">false</span>),
      'app_id'             =&gt; env('WECHAT_PAYMENT_APPID', ''),
      'mch_id'             =&gt; env('WECHAT_PAYMENT_MCH_ID', 'your-mch-id'),
      'key'                =&gt; env('WECHAT_PAYMENT_KEY', 'key-for-signature'),
      'cert_path'          =&gt; env('WECHAT_PAYMENT_CERT_PATH', 'path/to/cert/apiclient_cert.pem'),
      'key_path'         =&gt; env('WECHAT_PAYMENT_KEY_PATH', 'path/to/cert/apiclient_key.pem'),
      'notify_url'         =&gt; '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>-&gt;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>-&gt;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>-&gt;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>-&gt;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>-&gt;request-&gt;<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>-&gt;wechat-&gt;auth-&gt;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>-&gt;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>-&gt;request-&gt;<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>-&gt;request-&gt;<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>-&gt;request-&gt;<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>-&gt;order-&gt;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>-&gt;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>-&gt;pay-&gt;order-&gt;<span style="color: rgba(0, 0, 0, 1)">unify([
      </span>'body'          =&gt; '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'=&gt; <span style="color: rgba(128, 0, 128, 1)">$order</span>-&gt;order_num,       <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> order number</span>
      'trade_type'    =&gt; 'JSAPI',               <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> must 'JSAPI'</span>
      'openid'      =&gt; <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'   =&gt; <span style="color: rgba(128, 0, 128, 1)">$order</span>-&gt;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'   =&gt; <span style="color: rgba(128, 0, 128, 1)">$appid</span>,
            'timeStamp' =&gt; <span style="color: rgba(0, 128, 128, 1)">time</span>(),
            'nonceStr'=&gt; <span style="color: rgba(128, 0, 128, 1)">$out</span>['nonce_str'],
            'package'   =&gt; 'prepay_id=' . <span style="color: rgba(128, 0, 128, 1)">$out</span>['prepay_id'],
            'signType'=&gt; '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>-&gt;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>-&gt;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>-&gt;wechat-&gt;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>-&gt;order-&gt;where('order_num', <span style="color: rgba(128, 0, 128, 1)">$message</span>['out_trade_no'])-&gt;<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>-&gt;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>-&gt;status = 3<span style="color: rgba(0, 0, 0, 1)">;
                  </span><span style="color: rgba(128, 0, 128, 1)">$order</span>-&gt;<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>-&gt;<span style="color: rgba(0, 0, 0, 1)">send();
    }</span></span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 18px"><strong><span style="color: rgba(51, 102, 255, 1)">四、调试</span></strong></span></p>
<p>。。</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/rendd/p/11759506.html
頁: [1]
查看完整版本: 小程序开发 —— 微信支付