PHP WeChat applet payment - signature error

First distinguish a few concepts:

1. WeChat public platform and WeChat merchant platform are two different platforms

2. WeChat public platform is used for setting platform for public accounts, small programs, etc., including APPID, APPSECRET (Note: the APPID of each public account and each small program is independent and different, so if you want to use it To pay for a certain applet, use the APPID and APPSECRET of that applet, which should not be confused)

3. The WeChat merchant platform is used for merchant payment settings. The WeChat merchant account is MCHID. After entering the WeChat merchant platform, the set payment key is KEY. Before setting the payment key, you need to install the operation certificate and set the operation password, etc.

4. Wechat payment currently has the following types, the mini program payment actually calls the official account payment

5. WeChat account can be used to log in WeChat public platform and WeChat merchant platform. One WeChat account can apply for multiple official accounts, multiple mini programs, and multiple WeChat merchant accounts, so when configuring payment, you must pay attention to which mini program corresponds to Which WeChat Merchant Account is set, once the configuration is wrong, it often returns "Signature Error" when verifying the signature in the program (personally, WeChat can prompt more details, what is the error, and avoid N times of Debug)

 

6. The official signature verification tool is provided: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1

Fill in the generated xml and the merchant key correspondingly, and then the verification can be performed. If the verification fails, it means that the xml format is incorrect or the sign does not match the merchant key, and the xml format is incorrect, please refer to: https://pay.weixin. qq.com/wiki/doc/api/jsapi.php?chapter=9_1 , the merchant KEY does not match, please re-match and set the merchant KEY

(Special note: If the xml verification is passed, it only means that the format of the xml and the sign signature match the merchant KEY. It does not mean that APPID, MCHID, KEY, and APPSECRET are configured correctly. This sentence must be well understood)

 

In summary, as long as it is developed using the official sdk ( https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 ), the xml verification has passed, and APPID is configured correctly , MCHID, KEY, APPSECRET, most of the "signature errors" can be solved.

-----------------------------------------------------------------------------------------------------------------

 

The following is the code reproduced online, for reference only: https://blog.csdn.net/ufo00001/article/details/75712479

Front-end: relatively simple, just make a network request on the corresponding payment event:

view_moneysure:function(){

    var code = this.data.code;
    console.log('code是' +code)
    wx.request({
      url: 'https://...com/pay.php',//This link is written by the backend
      header: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      data: {
        code: code,
      },
      method: 'POST',
      success: function (response) {
        console.log( response.data);
        // initiate payment
        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: 'Payment successful'
            });
            console.log(res);
          },
          'fail': function (res) {
            console.log(res)
          }
        });
      },
      fail: function (res) {
        console.log(res)
      }
    })
  },

 

 

Backend code:

1. pay.php //The backend address requested by the applet

<?php
/**
 * Created by PhpStorm.
 * User: UFO
 * Date: 17/7/18
 * Time: 5:31 pm
 */
require_once  ('WxPay.Api.php');

class WXPay  {
    function index() {
        // initialize the value object
        $input = new WxPayUnifiedOrder();
        // Parameter specification mentioned in the document: Merchant Name - Sales Product Category
        $input->SetBody("testceshi");
        // The order number should be passed from the applet to the server, which is generated when the user places an order, and the value in the demo is a generated timestamp
        $input->SetOut_trade_no(time().'');
        // The fee should be passed from the applet to the server. When the user places an order, the server is informed of the amount payable. The value in the demo is 1, which is 1 cent
        $input->SetTotal_fee("1");
        $input->SetNotify_url("https://...com/notify.php");//You need to write your own notify.php
        $input->SetTrade_type("JSAPI");
        // Pass it from the applet to the backend or get it by the backend, write what it got by itself,
        $input->SetOpenid('UdhncondJcnkJnjknkcssdcAbckn');
        //$input->SetOpenid($this->getSession()->openid);
        // Place an order with WeChat and return the order, which is an array
        $order = WxPayApi::unifiedOrder($input);
        // jsonized and returned to the applet
        header("Content-Type: application/json");
        echo $this->getJsApiParameters($order);
    }

    private function getJsApiParameters($UnifiedOrderResult)
    { //Determine whether the unified order returns the prepay_id
        if(!array_key_exists("appid", $UnifiedOrderResult)
            || !array_key_exists("prepay_id", $UnifiedOrderResult)
            || $UnifiedOrderResult['prepay_id'] == "")
        {
            throw new WxPayException("Parameter error");
        }
        $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;
    }
//Here is the function to get the openid on the server side
//    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. WeChat SDK download link: https://pay.weixin.qq.com/wiki/doc/api/download/WxpayAPI_php_v3.zip

 

 Unzip it in the lib folder and you can see:

Put it in a directory accessible by the server.

Configure account information in WxPayConfig.php:

class WxPayConfig
{
	//========[Basic information settings]====================================== =
	//
	/**
	 * TODO: Modify this configuration to apply for your own business information
	 * WeChat public account information configuration
	 *
	 * APPID: APPID for binding payment (must be configured, can be viewed in the account opening email)
	 *
	 * MCHID: Merchant ID (must be configured, can be viewed in the account opening email)
	 *
	 * KEY: Merchant payment key, refer to account opening email settings (must be configured, log in to the merchant platform to set by yourself)
	 * Setting address: https://pay.weixin.qq.com/index.php/account/api_cert
	 *
	 * APPSECRET: public account secert (only when JSAPI payment needs to be configured, log in to the public platform, enter the developer center to set),
	 * Get address: https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
	 * @var string
	 */
	const APPID = 'wx123456789...';//Fill in your own corresponding information here
	const MCHID = '14151666888';
	const KEY = '11223344556677889900';
	const APPSECRET = '828bfsdibfsiubfikdbfik';
	const NOTIFY_URL='https://...com/notify.php';

 

 

Note:

During the period, I encountered a signature error, which has been bad. It is not wrong to use the WeChat payment interface signature verification tool to verify that there is nothing wrong with the verification. As mentioned on the Internet, I have checked the missing and wrongly written parameters, but it keeps returning <return_code><![CDATA[FAIL ]]></return_code>

 

<return_msg><![CDATA[signature error]]></return_msg>
For such information, the final solution is: reset the KEY (merchant payment key), the reset is exactly the same as the previous one, but it works...

The main problem is that the signature error is reported, just check carefully, such as the wrong XML format, the number of digits after MD5 encryption, the dictionary sorting is not well arranged, the parameters are missing, etc...

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1&index=1

3. Finally attach notify.php

<?php
/**
 * Created by PhpStorm.
 * User: UFO
 * Date: 17/7/13
 * Time: 6:42 pm
 */
require_once ('WxPay.Api.php');
require_once ('WxPay.Notify.php');
class PayNotifyCallBack extends WxPayNotify
{
    //checking order
    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;
    }

    //Override the callback handler
    public function NotifyProcess($data, &$msg)
    {
        $notfiyOutput = array();

        if(!array_key_exists("transaction_id", $data)){
            $msg = "Incorrect input parameter";
            return false;
        }
        //Query the order to determine the authenticity of the order
        if(!$this->Queryorder($data["transaction_id"])){
            $msg = "Order query failed";
            return false;
        }
        return true;
    }
}
$notify = new PayNotifyCallBack();
$notify->Handle(false);

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326178654&siteId=291194637