WeChat Mini Program Payment (PHP) - Signature Error

 

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=326061432&siteId=291194637