先分清幾個概念:微信公衆平臺、微信開放平臺、微信商戶平臺
1.微信公衆平臺、微信開放平臺、微信商戶平臺是三個不同的平臺
2.微信公衆平臺:用於公衆號、小程序等等的設置平臺,包括APPID、APPSECRET(注:每個公衆號、每個小程序的APPID都是獨立的、不一樣的,所以如果是要用某個小程序支付,那就要用那個小程序的APPID、APPSECRET,不能混淆)。也就是用於微信這個APP本身的設置
3.微信開放平臺:用於微信APP與其他APP的“連接”、“溝通”,爲其他APP提供瞭如微信登錄、微信分享、微信支付等功能(比如在使用12306APP買票的時候可以選擇用微信支付)
4.微信商戶平臺:是用於微信商戶支付設置,因爲支付功能屬於一個大的模塊,所以微信單獨分離出了這個平臺,微信商戶的賬號就是MCHID,進入微信商戶平臺後,設置的支付的密鑰就是KEY,設置支付密鑰前要安裝操作證書以及設置操作密碼等
4.微信支付目前有下面這幾種,小程序支付實際調用的是公衆號支付
5.微信號可以用來登錄微信公衆平臺和微信商戶平臺,一個微信號可以申請多個公衆號、多個小程序,多個微信商戶號,所以在配置支付的時候一定要注意哪個小程序對應的哪個微信商戶號,一旦配置錯誤,經常在程序中校驗簽名的時候返回“簽名錯誤”(個人覺得微信還可以再提示的詳細一些,到底是什麼錯誤,避免N次的Debug)
6.官方提供了簽名校驗工具:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1
把生成好的xml及商戶key對應填入,即可校驗,如果校驗失敗,說明xml格式不正確或者sign與商戶KEY不匹配,xml格式不正確請參閱:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1,商戶KEY不匹配請重新比對並設置商戶KEY
(特別說明:xml校驗通過,只能說明xml的格式以及sign簽名與商戶KEY是匹配的,並不代表APPID、MCHID、KEY、APPSECRET配置的是正確的,這句話一定好好理解一下)
綜上,只要是使用的官方sdk(https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1)開發的,xml校驗通過了,並且配置對了APPID、MCHID、KEY、APPSECRET的,絕大多數的“簽名錯誤”都可以解決了。
-----------------------------------------------------------------------------------------------------------------
以下是網上轉載的代碼,僅供參考:https://blog.csdn.net/ufo00001/article/details/75712479
前端:比較簡單,在對應的支付事件上進行網絡請求就好:
view_moneysure:function(){ var code = this.data.code; console.log('code是' +code) wx.request({ url: 'https://...com/pay.php',//這個鏈接是後端寫的 header: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: { code: code, }, method: 'POST', success: function (response) { console.log( response.data); // 發起支付 wx.requestPayment({ 'appId': response.data.appId, 'timeStamp': response.data.timeStamp, 'nonceStr': response.data.nonceStr, 'package': response.data.package, 'signType': 'MD5', 'paySign': response.data.paySign, 'success': function (res) { wx.showToast({ title: '支付成功' }); console.log(res); }, 'fail': function (res) { console.log(res) } }); }, fail: function (res) { console.log(res) } }) },
後端代碼:
1. pay.php //小程序請求的後端地址
<?php /** * Created by PhpStorm. * User: UFO * Date: 17/7/18 * Time: 下午5:31 */ require_once ('WxPay.Api.php'); class WXPay { function index() { // 初始化值對象 $input = new WxPayUnifiedOrder(); // 文檔提及的參數規範:商家名稱-銷售商品類目 $input->SetBody("testceshi"); // 訂單號應該是由小程序端傳給服務端的,在用戶下單時即生成,demo中取值是一個生成的時間戳 $input->SetOut_trade_no(time().''); // 費用應該是由小程序端傳給服務端的,在用戶下單時告知服務端應付金額,demo中取值是1,即1分錢 $input->SetTotal_fee("1"); $input->SetNotify_url("https://...com/notify.php");//需要自己寫的notify.php $input->SetTrade_type("JSAPI"); // 由小程序端傳給後端或者後端自己獲取,寫自己獲取到的, $input->SetOpenid('UdhncondJcnkJnjknkcssdcAbckn'); //$input->SetOpenid($this->getSession()->openid); // 向微信統一下單,並返回order,它是一個array數組 $order = WxPayApi::unifiedOrder($input); // json化返回給小程序端 header("Content-Type: application/json"); echo $this->getJsApiParameters($order); } private function getJsApiParameters($UnifiedOrderResult) { //判斷是否統一下單返回了prepay_id if(!array_key_exists("appid", $UnifiedOrderResult) || !array_key_exists("prepay_id", $UnifiedOrderResult) || $UnifiedOrderResult['prepay_id'] == "") { throw new WxPayException("參數錯誤"); } $jsapi = new WxPayJsApiPay(); $jsapi->SetAppid($UnifiedOrderResult["appid"]); $timeStamp = time(); $jsapi->SetTimeStamp("$timeStamp"); $jsapi->SetNonceStr(WxPayApi::getNonceStr()); $jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']); $jsapi->SetSignType("MD5"); $jsapi->SetPaySign($jsapi->MakeSign()); $parameters = json_encode($jsapi->GetValues()); return $parameters; } //這裏是服務器端獲取openid的函數 // private function getSession() { // $code = $this->input->post('code'); // $url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.WxPayConfig::APPID.'&secret='.WxPayConfig::APPSECRET.'&js_code='.$code.'&grant_type=authorization_code'; // $response = json_decode(file_get_contents($url)); // return $response; // } } $WxPay = new WXPay(); $WxPay->index();
2. 微信SDK 下載鏈接:https://pay.weixin.qq.com/wiki/doc/api/download/WxpayAPI_php_v3.zip
解壓在lib文件夾下可以看到:
放到服務端可訪問的目錄下。
在WxPayConfig.php裏面配置賬號信息:
class WxPayConfig { //=======【基本信息設置】===================================== // /** * TODO: 修改這裏配置爲您自己申請的商戶信息 * 微信公衆號信息配置 * * APPID:綁定支付的APPID(必須配置,開戶郵件中可查看) * * MCHID:商戶號(必須配置,開戶郵件中可查看) * * KEY:商戶支付密鑰,參考開戶郵件設置(必須配置,登錄商戶平臺自行設置) * 設置地址:https://pay.weixin.qq.com/index.php/account/api_cert * * APPSECRET:公衆帳號secert(僅JSAPI支付的時候需要配置, 登錄公衆平臺,進入開發者中心可設置), * 獲取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN * @var string */ const APPID = 'wx123456789...';//這裏填上自己的對應信息 const MCHID = '14151666888'; const KEY = '11223344556677889900'; const APPSECRET = '828bfsdibfsiubfikdbfik'; const NOTIFY_URL='https://...com/notify.php';
注:
期間遇到一個簽名錯誤,一直不好,使用微信支付接口簽名校驗工具校驗也沒有錯,像網上說的漏寫錯寫參數都查了,就是一直返回<return_code><![CDATA[FAIL]]></return_code>
<return_msg><![CDATA[簽名錯誤]]></return_msg>
這樣的信息,最後解決辦法是:重置了KEY (商戶支付密鑰),重置的和之前的一模一樣,但竟然就可以了...
問題主要都是報簽名錯誤,仔細檢查就好,比如XML格式不對,MD5加密後的位數,字典排序沒排好,缺少參數等...
https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1&index=1
3.最後附上notify.php
<?php /** * Created by PhpStorm. * User: UFO * Date: 17/7/13 * Time: 下午6:42 */ require_once ('WxPay.Api.php'); require_once ('WxPay.Notify.php'); class PayNotifyCallBack extends WxPayNotify { //查詢訂單 public function Queryorder($transaction_id) { $input = new WxPayOrderQuery(); $input->SetTransaction_id($transaction_id); $result = WxPayApi::orderQuery($input); if(array_key_exists("return_code", $result) && array_key_exists("result_code", $result) && $result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS") { return true; } return false; } //重寫回調處理函數 public function NotifyProcess($data, &$msg) { $notfiyOutput = array(); if(!array_key_exists("transaction_id", $data)){ $msg = "輸入參數不正確"; return false; } //查詢訂單,判斷訂單真實性 if(!$this->Queryorder($data["transaction_id"])){ $msg = "訂單查詢失敗"; return false; } return true; } } $notify = new PayNotifyCallBack(); $notify->Handle(false);