In order to provide a simple, consistent and easy-to-use development experience to merchants while ensuring payment security, we have launched the latest WeChat Pay APIv3 interface. Please refer to “APIv3 Interface Rules” for the specific rules of this API version.
2. Development Environment Setup
To help developers call the open interface, the development libraries of Java、PHP、GO are provided, encapsulating the basic functions such as signature generation, signature verification, encryption/decryption of sensitive information, and media document upload
JAVA
2.1.1. Conditions of Use
WechatPay merchant account
Java 1.8 or later
Maven or Gradle;
0.4.6 or later version of the Java httpClient SDK
2.1.2. Installation
Gradle:Add the following dependencies to your build.gradle document
Initialize WechatPayHttpClientBuilder to create an httpClient, which will be used to send requests to call the WeChatPay interface. Initialize a verifier instance with CertificatesManager to verify the signature.
12privateCloseableHttpClienthttpClient;3privateCertificatesManagercertificatesManager;4privateVerifierverifier;56@Before7//initialize verifier and build httpClient8publicvoidsetup()throwsGeneralSecurityException,IOException,HttpCodeException,NotFoundException{910PrivateKeymerchantPrivateKey=PemUtil.loadPrivateKey(privateKey);11certificatesManager=CertificatesManager.getInstance();12certificatesManager.putMerchant(merchantId,newWechatPay2Credentials(merchantId,13newPrivateKeySigner(merchantSerialNumber,merchantPrivateKey)),14apiV3Key.getBytes(StandardCharsets.UTF_8));15verifier=certificatesManager.getVerifier(merchantId);16WechatPayHttpClientBuilderbuilder=WechatPayHttpClientBuilder.create()17.withMerchant(merchantId,merchantSerialNumber,merchantPrivateKey)18.withValidator(newWechatPay2Validator(verifier));19httpClient=builder.build();20}21
Initialize Client and load the merchant account, private key, API V3 key, merchant certificate and serial number to Client for sending an interface request later.
12import(3"context"4"crypto/rand"5"crypto/rsa"6"crypto/x509"7"encoding/base64"8"fmt"9"github.com/wechatpay-apiv3/wechatpay-go/core"10"github.com/wechatpay-apiv3/wechatpay-go/core/option"11"github.com/wechatpay-apiv3/wechatpay-go/utils"12"log"13"net/http"14)1516var(17mchID=""// merchant id18mchCertificateSerialNumber=""// merchant certificate serial number19mchAPIv3Key=""// merchant api v3 key20header=make(http.Header)21ctx=context.Background()22cert*x509.Certificate23mchPrivateKey*rsa.PrivateKey24client*core.Client25errerror26)2728funcsetup(){29//Load platform certificate30cert,err=utils.LoadCertificateWithPath("Path/To/Platform/Cert")31iferr!=nil{32log.Fatal(err)33}34// Load private key35mchPrivateKey,err=utils.LoadPrivateKeyWithPath("Path/To/Private/Key")36iferr!=nil{37log.Fatal("load merchant private key error")38}39// Initialize client which is capable to update platform certificate periodically40opts:=[]core.ClientOption{41option.WithWechatPayAutoAuthCipher(mchID,mchCertificateSerialNumber,mchPrivateKey,mchAPIv3Key),42}43client,err=core.NewClient(ctx,opts...)44iferr!=nil{45log.Fatalf("new wechat pay client err:%s",err)46}47}48
2.2.4. General Functions
Encrypting Sensitive Information
12funcEncryption(t*testing.T){3vartestRSACryptoUtilMchCertificateStr=`-----BEGIN CERTIFICATE-----4-----END CERTIFICATE-----`5testRSACryptoUtilCertificate,_=LoadCertificate(testRSACryptoUtilMchCertificateStr)6constmessage="hello world"78// Encrypt the certificate by OAEP padding9ciphertext,_:=EncryptOAEPWithCertificate(message,testRSACryptoUtilCertificate)1011// Encrypt the certificate by PKCS1 padding12ciphertext,_:=EncryptPKCS1v15WithCertificate(message,testRSACryptoUtilCertificate)13}14
Decrypting Sensitive Information
12funcTestDecryption(t*testing.T){3vartestRSACryptoUtilPrivateKeyStr=`-----BEGIN PRIVATE KEY-----4-----END PRIVATE KEY-----`5testRSACryptoUtilPrivateKey,_=LoadPrivateKey(testingKey(testRSACryptoUtilPrivateKeyStr))6constciphertext=""78// Decrypt the private key by PKCS1 padding9decryptMessage,_:=DecryptPKCS1v15(ciphertext,testRSACryptoUtilPrivateKey)1011// Decrypt the private key by OAEP padding12decryptMessage,_:=DecryptOAEP(ciphertext,testRSACryptoUtilPrivateKey)13}
PHP
2.3.1. Conditions of Use
Guzzle 7.0,PHP >= 7.2.5
Guzzle 6.5,PHP >= 7.1.2
PHP 8 is supported.
2.3.2. Installation
It is recommended to use the PHP package management tool Composer to install SDK:
composer require wechatpay/wechatpay
2.3.3. Initialization
Initialize Client and load the merchant account, private key, API V3 key, merchant certificate and serial number to Client in order to send an interface request later.
12require_once('vendor/autoload.php');34useWeChatPay\Builder;5useWeChatPay\Crypto\Rsa;6useWeChatPay\Util\PemUtil;78$merchantId='190000****';9$merchantPrivateKeyFilePath='file:///path/to/merchant/apiclient_key.pem';10$merchantPrivateKeyInstance=Rsa::from($merchantPrivateKeyFilePath,Rsa::KEY_TYPE_PRIVATE);11$merchantCertificateSerial='3775B6A45ACD588826D15E583A95F5DD********';12$platformCertificateFilePath='file:///path/to/wechatpay/cert.pem';13$platformPublicKeyInstance=Rsa::from($platformCertificateFilePath,Rsa::KEY_TYPE_PUBLIC);14$platformCertificateSerial=PemUtil::parseCertificateSerialNo($platformCertificateFilePath);1516// init a API V3 instance17$instance=Builder::factory([18'mchid'=>$merchantId,19'serial'=>$merchantCertificateSerial,20'privateKey'=>$merchantPrivateKeyInstance,21'certs'=>[22$platformCertificateSerial=>$platformPublicKeyInstance,23],24]);25
The document shows how to use the WeChat Pay server SDK to In-App Payment by scanning code and interface with WeChat Pay.
Notice
The code examples in the document illustrate the basic usage of API. Before running the code, the example parameters in the code need to be replaced with the merchant's own account and request parameters.
The access steps below are for your information, and should be evaluated and modified according to the merchant’s own business demands.
3.2.1 Place an order
Procedure: Submit a pre-order request for mini program payment through this interface, obtain the prepay_id to call payment.
12// Call Unified Order API3publicfunctionunifiedOrder($instance){4try{5$resp=$instance6->chain('v3/global/transactions/jsapi')7->post(['json'=>[8'sp_appid'=>'wxdace645e0bc2c424',9'sp_mchid'=>'10000100',10'sub_mchid'=>'20000100',11'out_trade_no'=>'YX201710140020Z',12'merchant_category_code'=>'4111',13'notify_url'=>'https://weixin.qq.com/',14'trade_type'=>'JSAPI',15'amount'=>[16'total'=>1,17'currency'=>'USD'18],19'payer'=>[20'sub_openid'=>'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o'21],22'attach'=>'mini-program payment test',23'description'=>'Image形象店-深圳腾大-QQ公仔',24'goods_tag'=>'001'25]]);2627echo$resp->getStatusCode(),PHP_EOL;28echo$resp->getBody(),PHP_EOL;29}catch(Exception$e){30// EXception handling31echo$e->getMessage(),PHP_EOL;32if($einstanceof\GuzzleHttp\Exception\RequestException&&$e->hasResponse()){33$r=$e->getResponse();34echo$r->getStatusCode().' '.$r->getReasonPhrase(),PHP_EOL;35echo$r->getBody(),PHP_EOL,PHP_EOL,PHP_EOL;36}37echo$e->getTraceAsString(),PHP_EOL;38}39}
Critical parameters:
out_trade_no: internal order ID in merchant’s system
notify_url: For the address used to receive the asynchronous payment result callback notification, the notification URL must be a URL that is accessible by the external network and cannot carry any parameters. Please use an HTTPS protocol link
openid: User’s unique ID under the corresponding merchant appid will be returned only when appid is passed. For details on how to retrieve openid, see Obtaining openid
sub_openid: It is the user’s unique ID under the sub-merchant sub_appid, and either sp_openid or sub_openid can be selected. If sub_openid is selected, sub_appid must be passed in. Before an order is placed, the【Web Authorization】interface needs to be called to obtain the user’s openid.
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.2 Mini Program Pull-up Payment
Procedure: The merchant needs to return the payment transaction ID received and paySign to the mini program, and then pull up the WeChat payment cashier in the mini program for the user to confirm the order information and payment.
Constructing Signature String
1There are four lines in the signature string, and each line is a parameter. Each line ends with \n (Newline character; the ASCII code value is 0x0A), and even the last line shall ends with \n.If the parameter itself ends with \n, an additional \n is also required2
Fields and formats involved in the signature:
1 Mini Program id2 Time stamp3 Random string4 An extension string for order details5
Sign in the same way as the request data signature , use the merchant's private key to sign the signature string with SHA256 with RSA, and perform Base64 encoding on the signature result to obtain the signature value.
package:The value of the prepay_id parameter returned by the unified order placement API, in the format of prepay_id=***
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.3 Query
Procedure: The merchant is required to take the initiative to check the order status after placing an order for a certain period of time.
Code example-JAVA
12@Test3//Call query order API4publicvoidqueryOrderTest()throwsIOException{5HttpGethttpGet=newHttpGet("https://apihk.mch.weixin.qq.com/v3/global/transactions/id/"+6"4200123456789000?sub_mchid=100012321&sp_mchid=1900000000");7httpGet.addHeader("Accept","application/json");8httpGet.addHeader("Content-type","application/json; charset=utf-8");9CloseableHttpResponseresponse=httpClient.execute(httpGet);10//Process the response 11}12
Code example-Go
12//Call query order API3funcqueryOrder(){4result,err:=client.Get(ctx,"https://apihk.mch.weixin.qq.com/v3/global/transactions/id/4200000000000000?sub_mchid=100012321&sp_mchid=1900000000")5iferr!=nil{6// Process error7}8log.Printf("status=%d resp=%s",result.Response.StatusCode,result.Response.Body)9}
Code example-PHP
12// Call query order API3publicfunctionqueryOrder($instance)4{5try{6$resp=$instance7->v3->global->transactions->outTradeNo->_out_trade_no_8->get([9'query'=>[10'sp_mchid'=>'1900000000',11'sub_mchid'=>'100012321',12],13'out_trade_no'=>'YX0001'14]15);1617echo$resp->getStatusCode(),PHP_EOL;18echo$resp->getBody(),PHP_EOL;19}catch(Exception$e){20// Exception handling21}22}
Critical parameters:
id: WeChat payment order ID
out_trade_no: internal order ID in merchant’s system
Query with any order ID above. Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.4 Refund
Procedure: After the payment is completed and the payment status is SUCCESS, call this interface to submit a refund request.
Code example-JAVA
12@Test3//Call Refund API4publicvoidrefundTest()throwsIOException{5StringrefundBody=String.join("\n",6"{",7"'sp_appid': 'wx2421b1c4370ec43b', ",8"'sp_mchid': '10000100',",9"'sub_mchid': '20000100',",10"'transaction_id': '1008450740201411110005820873',",11"'out_refund_no': 'R20150806125346',",12" 'amount' : {",13" 'refund': 5,",14" 'total':10,",15" 'currency':'HKD'",16" },",17" 'reason': 'The item has been sold out.',",18" 'source': 'REFUND_SOURCE_UNSETTLED_FUNDS'",19"}").replace("'","\"");20HttpPosthttpPost=newHttpPost("https://apihk.mch.weixin.qq.com/v3/global/refunds");21httpPost.addHeader("Accept","application/json");22httpPost.addHeader("Content-type","application/json; charset=utf-8");23httpPost.setEntity(newStringEntity(refundBody));24CloseableHttpResponseresponse=httpClient.execute(httpPost);25//Process the response 26}27
Code example-Go
12funcrefund(){3refundRequestBody:=`{4"sp_appid": "wx2421b1c4370ec43b",5"sp_mchid": "10000100",6"sub_mchid": "20000100",7"transaction_id": "1008450740201411110005820873",8"out_refund_no": "R20150806125346",9"amount" : {10"refund": 50,11"total":100,12"currency":"HKD"13},14"reason": "The item has been sold out",15"source": "REFUND_SOURCE_UNSETTLED_FUNDS"16}`17result,err:=client.Post(ctx,"https://apihk.mch.weixin.qq.com/v3/global/refunds",refundRequestBody)18iferr!=nil{19// Process error20}21log.Printf("status=%d resp=%s",result.Response.StatusCode,result.Response.Body)22}
out_trade_no: internal order ID in merchant’s system
transaction_id: WeChat order ID
out_refund_no: internal refund No. in merchant’s system, which should correspond to order ID
notify_url: address for receiving refund results
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.5 Query one refund
Procedure: After submitting a refund request, query the refund status by calling this interface.
Code example-JAVA
12@Test3//Call Query Refund API4publicvoidquerySingleRefundTest()throwsIOException{5HttpGethttpGet=newHttpGet("https://apihk.mch.weixin.qq.com/v3/global/refunds/out-refund-no/RYX001?sub_mchid=100012321&sp_mchid=1900000000");6httpGet.addHeader("Accept","application/json");7httpGet.addHeader("Content-type","application/json; charset=utf-8");8CloseableHttpResponseresponse=httpClient.execute(httpGet);9//Process the response 10}11
Code example-Go
12//Query single refund API3funcquerySingleRefund(){4result,err:=client.Get(ctx,"https://apihk.mch.weixin.qq.com/v3/global/refunds/out-refund-no/REFUNDYX001?sub_mchid=100012321&sp_mchid=1900000000")5iferr!=nil{6// Process error7}8log.Printf("status=%d resp=%s",result.Response.StatusCode,result.Response.Body)9}
Code example-PHP
Critical parameters:
out_trade_no: internal refund No. in merchant’s system
refund_id:WeChat payment refund order ID
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.6 Query all refunds
Procedure: After submitting a refund request, query all refund information corresponding to one payment order.
Code example-JAVA
12@Test3//Call Query All Refund API4publicvoidqueryAllRefundTest()throwsIOException{5HttpGethttpGet=newHttpGet("https://apihk.mch.weixin.qq.com/v3/global/refunds"+6"?out_trade_no=YX202111100020&count=10&offset=0&sp_mchid=1900000000&sub_mchid=100012321");7httpGet.addHeader("Accept","application/json");8httpGet.addHeader("Content-type","application/json; charset=utf-8");9CloseableHttpResponseresponse=httpClient.execute(httpGet);10//Process the response 11}12
Code example-Go
12//Query all refund API3funcqueryAllRefund(){4result,err:=client.Get(ctx,"https://apihk.mch.weixin.qq.com/v3/global/refunds/out-refund-no/out_trade_no=YX001&count=10&offset=0&sp_mchid=1900000000&sub_mchid=100012321")5iferr!=nil{6// Process error7}8log.Printf("status=%d resp=%s",result.Response.StatusCode,result.Response.Body)9}
Code example-PHP
12// Call Query All Refund API3publicfunctionqueryAllRefund($instance){4try{5$resp=$instance6->v3->global->refunds7->get([8'query'=>[9'out_trade_no'=>'YX001',10'count'=>10,11'offset'=>0,12'sp_mchid'=>'1900000000',13'sub_mchid'=>'100012321'14]15]);1617echo$resp->getStatusCode(),PHP_EOL;18echo$resp->getBody(),PHP_EOL;19}catch(Exception$e){20// Exception handling21}22}
Critical parameters:
out_trade_no: Internal order ID in merchant’s system
transaction_id: WeChat order ID
offset: Start position of paging
count: Number of records returned in a single page, up to 20 records.
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.7 Download statement of account
Procedure: Merchants can download the historical transaction statements by calling this interface on a daily basis, and correct the payment information by reconciling the statements.
Code example-JAVA
12@Test3//Downloading Reconciliation API4publicvoiddownloadReconTest()throwsIOException{5HttpGethttpGet=newHttpGet("https://apihk.mch.weixin.qq.com/v3/global/statements?date=20220401&mchid=1900000000");6httpGet.addHeader("Accept","application/json");7httpGet.addHeader("Content-type","application/json; charset=utf-8");8CloseableHttpResponseresponse=httpClient.execute(httpGet);9//Process the response 10}11
Code example-Go
12//Download recon file API3funcdownloadReconFile(){4result,err:=client.Get(ctx,"https://apihk.mch.weixin.qq.com/v3/global/statements?date=20220401&mchid=1900000000")5iferr!=nil{6// Process error7}8log.Printf("status=%d resp=%s",result.Response.StatusCode,result.Response.Body)9}
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.8 Close and order
Procedure: After placing an order, call this interface to close the orders not paid, allowing the merchant replace the order ID to re-order and initiate payment or avoid repeated payment by the user after quiting merchant's system without accepting the order.
Code example-JAVA
12@Test3//Call close order API4publicvoidcloseOrderTest()throwsIOException{5StringcloseBody=String.join("\n",6"{",7" 'sp_mchid': '10000100',",8" 'sub_mchid': '20000100'",9"}").replace("'","\"");10HttpPosthttpPost=newHttpPost("https://apihk.mch.weixin.qq.com/v3/global/transactions/out-trade-no/YX001/close");11httpPost.addHeader("Accept","application/json");12httpPost.addHeader("Content-type","application/json; charset=utf-8");13httpPost.setEntity(newStringEntity(closeBody));14CloseableHttpResponseresponse=httpClient.execute(httpPost);15System.out.println(response.getStatusLine().getStatusCode());16}17
Code example-Go
12//Call close order API3funccloseOrder(){4closeOrderBody:=`{5"sp_mchid": "10000100",6"sub_mchid": "20000100"7}`8result,err:=client.Post(ctx,"https://apihk.mch.weixin.qq.com/v3/global/transactions/out-trade-no/YX001/close",closeOrderBody)9iferr!=nil{10// Process error11}12log.Printf("status=%d resp=%s",result.Response.StatusCode,result.Response.Body)13}
Code example-PHP
12// Call close order API3publicfunctioncloseOrder($instance){4try{5$resp=$instance6->v3->global->transactions->outTradeNo->_out_trade_no_->close7->post([8'json'=>[9'sp_mchid'=>'10000100',10'sub_mchid'=>'20000100'11],12'out_trade_no'=>'YX0001'13]);14echo$resp->getStatusCode(),PHP_EOL;15echo$resp->getBody(),PHP_EOL;16}catch(Exception$e){17// Exception handling18}19}
Critical parameters:
out_trade_no: Internal order ID in merchant’s system
transaction_id: WeChat order ID
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.9 Download platform certificate
Procedure: Before calling other interfaces, call this interface to download the platform certificate to verify the signature of the returned message and decrypt the encrypted fields therein.
Code example-JAVA
12@Test3//Call certificate downloading API4publicvoidcertDownloadingTest()throwsIOException{5HttpGethttpGet=newHttpGet("https://apihk.mch.weixin.qq.com/v3/global/certificates");6httpGet.addHeader("Accept","application/json");7httpGet.addHeader("Content-type","application/json; charset=utf-8");89CloseableHttpResponseresponse=httpClient.execute(httpGet);10//Process the response 11//Get the response body: EntityUtils.toString(response.getEntity());12//Get the response status code: response.getStatusLine().getStatusCode();1314//Instead of calling the API to download platform certificate,15//We also recommend use the certificateMenager to get the valid certificate16verifier.getValidCertificate();17}18
Code example-Go
12//Calling download certificate API3funcdownloadCert(){4result,err:=client.Get((ctx,"https://apihk.mch.weixin.qq.com/v3/global/certificates"))5iferr!=nil{6ifcore.IsAPIError(err,"INVALID_REQUEST"){7//Process invalid request8}9// Process other error10}11log.Printf("status=%d resp=%s",result.Response.StatusCode,result.Response.Body)12}
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.10 Notification of payment results
Procedure: After the user makes the payment, WeChat Pay will push the payment result notification to the notify_url introduced while placing the order, and the merchant needs to feed back accordingly after receiving the notification.
Notes:
The same notification may be sent to the merchant system multiple times. The merchant system must be able to process duplicate notifications properly. It is recommended to first check the status of the corresponding business data when receiving a notification for processing, and determine whether the notification has been processed. If it has not been processed, the notification should be processed once again; if it has been processed, the success result should be returned. Before status checking and processing of the business data, a data lock should be used to implement concurrency control and avoid data confusion caused by function reentry.
If no callback is received from WeChat side after all notification frequencies (4 hours), the merchant shall call the Query Order interface to confirm the order status.
Special reminder: The merchant system must perform signature verification for the content of the notification of payment results, and verify whether the returned order amount is consistent with that of the merchant side, thus preventing any "false notifications" and even loss of funds caused by data leakage.
3.2.10.1 Notification Rules
After the payment is made, WeChat will send the related payment result and user information to the merchant. The merchant needs to receive and process the information, and return the response successfully. Only the successful payments will be notified.
When interacting with the background notification, if the response received by WeChat from the merchant is not success or timed out, WeChat thinks the notification fails. WeChat will periodically resend the notification according to the specified policy to maximize the success rate of the notification, but WeChat does not guarantee final success of the notification. ((Notification frequency is 15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - total 24h and 4m)) for repeated notification.
3.2.10.2 Notification Message
The payment result notification accesses the notification URL set by the merchant using the POST method, and the notification data is transmitted through the request body (BODY) in the JSON format. The data in the notification includes the encrypted payment result details.
The certificate decryption process is detailed as follows
1、Obtain the merchant's key from the merchant platform, and record it as “key”.
2、Get the corresponding parameters “nonce” and “associated_data” for the algorithm described in “algorithm” (currently AEAD_AES_256_GCM).
3、Decrypt “ciphertext” with “key”, “nonce” and “associated_data” (decode base64 for ciphertext first, and then decrypt it) to obtain the certificate content
Notes:
For the interface details of the AEAD_AES_256_GCM algorithm, please refer to rfc5116. The length of the key used in Wechat Pay is 32 bytes, the length of the random string nonce is 12 bytes, and the length of associated_data is less than 16 bytes and may be empty.
3.2.10.3 Notification Signature
Encryption does not guarantee that the notification requests come from WeChat. WeChat will sign the notification sent to the merchant and put the signature value in the HTTP header Wechatpay-Signature of the notification. Merchants should verify the signature to confirm that the request comes from WeChat, and not any other third parties. For the signature verification algorithm, please refer to WeChat Pay API V3 Signature Verification.
The http response code of the payment notification should be either 200 or 204 for normal receipt. In case of any callback processing error, the HTTP status code of the response should be 500 or 4xx.
Notes:
When the merchant background returns the failure response to Weixin Pay, Weixin Pay will record the response message. It is recommended that the merchant return the message in the following format.
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.11 Refund notification
Procedure: After the user makes the payment, WeChat Pay will push the payment result notification to the notify_url introduced while placing the order, and the merchant needs to feed back accordingly after receiving the notification.
Notes:
The same notification may be sent to the merchant system multiple times. The merchant system must be able to process duplicate notifications properly. It is recommended to first check the status of the corresponding business data when receiving a notification for processing, and determine whether the notification has been processed. If not, the notification should be processed; if it has been processed, the success result should be returned. Before status checking and processing of the business data, a data lock should be used to implement concurrency control and avoid data confusion caused by function reentry.
If no callback is received from WeChat side after all notification frequencies (4 hours), the merchant shall call the Query Order interface to confirm the order status.
Special reminder: The merchant system must perform signature verification for the content of the notification of payment results, and verify whether the returned order amount is consistent with that of the merchant side, thus preventing any "false notification" and even capital loss caused by data leakage.
3.2.11.1 Notification Rules
In case of any refund status changes, WeChat will send the related refund results to the merchant.
When interacting with the background notification, if the response received by WeChat from the merchant is not success or timed out, WeChat thinks the notification fails. WeChat will periodically resend the notification according to the specified policy to maximize the success rate of the notification, but WeChat does not guarantee final success of the notification. ((Notification frequency is 15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - total 24h and 4m))
3.2.11.2 Notification Message
The deduction result notification accesses the notification URL set by the merchant using the POST method, and the notification data is transmitted through the request body (BODY) in the JSON format. The data in the notification includes the details about the encrypted refund result.
The certificate decryption process is detailed as follows
1、Obtain the merchant's key from the merchant platform, and record it as “key”.
2、Get the corresponding parameters “nonce” and “associated_data” for the algorithm described in “algorithm” (currently AEAD_AES_256_GCM).
3、Decrypt “ciphertext” with “key”, “nonce” and “associated_data” (perfomr base64 decoding for ciphertext first, and then decrypt it) to obtain the certificate content
Notice
For the interface details of the AEAD_AES_256_GCM algorithm, please refer to rfc5116. The length of the key used in Wechat Pay is 32 bytes, the length of the random string nonce is 12 bytes, and the length of associated_data is less than 16 bytes and may be empty.
3.2.11.3 Notification Signature
Encryption does not guarantee that the notification requests come from WeChat. WeChat will sign the notification sent to the merchant and put the signature value in the HTTP header Wechatpay-Signature of the notification. Merchants should verify the signature to confirm that the request comes from WeChat, and not any other third parties. For the signature verification algorithm, please refer to WeChat Pay API V3 Signature Verification.
The http response code of the refund notification should be either 200 or 204 for normal receipt. In case of any callback processing error, the HTTP status code of the response should be 500 or 4xx.
Note:
When the merchant background returns the failure response to Weixin Pay, Weixin Pay will record the response message. It is recommended that the merchant return the message in the following format.
Please refer to the API document for ordering by scanning code for other critical parameters.
3.2.12 API for querying fund settlement details
Procedure: After transactions are completed, the merchant can query the settled fund details (sette_state is SETTLED) or the unsettled fund details (sette_state is UNSETTLE) by settlement date.
Note:
This API is designed for the cross-border acquiring institutions/direct merchants. In particular, if institutions/merchants in Japan and Macao have enabled Hong Kong Wallet services, they need to connect this API.
Code example-JAVA
12@Test3//Query Settlement API4publicvoidquerySettlementTest()throwsIOException{5HttpGethttpGet=newHttpGet("https://apihk.mch.weixin.qq.com/v3/global/settle/settlements"+6"?sub_mchid=100012321&settle_state=SETTLED&settle_start_date=20221225"+7"&settle_end_date=20221226&offset=10&limit=5");8httpGet.addHeader("Accept","application/json");9httpGet.addHeader("Content-type","application/json; charset=utf-8");10CloseableHttpResponseresponse=httpClient.execute(httpGet);11//Process the response 12}13
Code example-Go
12//Query settlement API3funcquerySettlement(){4result,err:=client.Get(ctx,"https://apihk.mch.weixin.qq.com/v3/global/settle/settlements?sub_mchid=100012321&settle_state=SETTLED&settle_start_date=20221225&settle_end_date=20221226&offset=10&limit=5")5iferr!=nil{6// Process error7}8log.Printf("status=%d resp=%s",result.Response.StatusCode,result.Response.Body)9}
Code example-Go
12//Querying Settlement Info API3publicfunctionquerySettlementInfo($instance){4try{5$resp=$instance6->v3->global->settle->settlements7->get(['query'=>[8'sub_mchid'=>'100012321',9'settle_state'=>'SETTLED',10'settle_start_date'=>'20221225',11'settle_end_date'=>'20221226',12'offset'=>'10',13'limit'=>'5'14]]);1516echo$resp->getStatusCode(),PHP_EOL;17echo$resp->getBody(),PHP_EOL;18}catch(\Exception$e){19// Exception handling20}21}
Critical parameters:
settle_state: Fund settlement status, enumeration value:
SETTLED:settled
UNSETTLE:not settled
Please refer to the API document for ordering by scanning code for other critical parameters.