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.
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
Password-free payment:
Password-based payment:
The document shows how to use the WeChat Pay server SDK to quickly pay by scanning code and interface with WeChat Pay.
• 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.
Procedure: Submit a WeChat payment code to pay for the order through this API. Scan the user's payment code to call this feature.
Code example:
@Test
//Call Quick Pay Order API
public void quickPayOrderTest() throws IOException {
String requestBody = String.join("\n" ,
"{" ,
"'sp_appid': 'wxdace645e0bc2c424'," ,
"'sp_mchid': '10000100'," ,
"'sub_mchid': '20000100'," ,
"'out_trade_no': '20150806125346'," ,
"'merchant_category_code': '4111'," ,
"'payer': {" ,
"'auth_code': '134650720866361395'" ,
"}," ,
"'trade_type': 'MICROPAY'," ,
"'amount': {" ,
"'total': 1," ,
"'currency': 'HKD'" ,
"}," ,
"'attach': 'Payment Test'," ,
"'description': 'Image Store - Tencent Building in Shenzhen - QQ Doll'," ,
"'goods_tag': '1234'," ,
"'limit_pay': 'no_credit'," ,
"'detail': {" ,
"'cost_price': 1," ,
"'receipt_id': '1234'," ,
"'goods_detail': [{" ,
"'goods_id': 'iphone6s_16G'," ,
"'wxpay_goods_id': '3405'," ,
"'goods_name': 'iPhone6s 16G'," ,
"'quantity': 1," ,
"'price': 1" ,
"}]" ,
"}," ,
"'scene_info': {" ,
"'payer_client_ip': '14.23.150.211'," ,
"'device_ip': '59.37.125.32'," ,
"'device_id': '013467007045764'," ,
"'operator_id': 'P001'," ,
"'store_info': {" ,
"'id': 'SZTX001'," ,
"'name': 'Tencent Building Branch'," ,
"'address': 'Nanshan District, Shenzhen, Guangdong'" ,
"}" ,
"}" ,
"}").replace("'","\"");
HttpPost httpPost = new HttpPost("https://apihk.mch.weixin.qq.com/v3/global/micropay/transactions/pay");
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-type", "application/json; charset=utf-8");
httpPost.setEntity(new StringEntity(requestBody));
CloseableHttpResponse response = httpClient.execute(httpPost);
//Process the response
}
Critical parameters:
out_trade_no: Internal order ID in merchant’s system
auth_code: Scan the payment authorization code, i.e., the digits corresponding to the payment displayed in the WeChat Wallet
Please refer to the API document for ordering by scanning code for other critical parameters.
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:
@Test
//Call query order API
public void queryOrderTest() throws IOException {
HttpGet httpGet = new HttpGet("https://apihk.mch.weixin.qq.com/v3/global/transactions/id/" +
"4200123456789000?sub_mchid=100012321&sp_mchid=1900000000");
httpGet.addHeader("Accept", "application/json");
httpGet.addHeader("Content-type", "application/json; charset=utf-8");
CloseableHttpResponse response = httpClient.execute(httpGet);
//Process the response
}
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.
Procedure: After the payment is completed and the payment status is SUCCESS, call this interface to submit a refund request.
Code example
@Test
//Call Refund API
public void refundTest() throws IOException {
String refundBody = String.join("\n" ,
"{" ,
"'sp_appid': 'wx2421b1c4370ec43b', " ,
"'sp_mchid': '10000100'," ,
"'sub_mchid': '20000100'," ,
"'transaction_id': '1008450740201411110005820873'," ,
"'out_refund_no': 'R20150806125346'," ,
" 'amount' : {" ,
" 'refund': 5," ,
" 'total':10," ,
" 'currency':'HKD'" ,
" }," ,
" 'reason': 'The item has been sold out.'," ,
" 'source': 'REFUND_SOURCE_UNSETTLED_FUNDS'" ,
"}").replace("'","\"");
HttpPost httpPost = new HttpPost("https://apihk.mch.weixin.qq.com/v3/global/refunds");
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-type", "application/json; charset=utf-8");
httpPost.setEntity(new StringEntity(refundBody));
CloseableHttpResponse response = httpClient.execute(httpPost);
//Process the response
}
Critical parameters:
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.
Procedure: After submitting a refund request, query the refund status by calling this interface.
Code example
@Test
//Call Query Refund API
public void querySingleRefundTest() throws IOException {
HttpGet httpGet = new HttpGet("https://apihk.mch.weixin.qq.com/v3/global/refunds/out-refund-no/RYX001?sub_mchid=100012321&sp_mchid=1900000000");
httpGet.addHeader("Accept", "application/json");
httpGet.addHeader("Content-type", "application/json; charset=utf-8");
CloseableHttpResponse response = httpClient.execute(httpGet);
//Process the response
}
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.
Procedure: After submitting a refund request, query all refund information corresponding to one payment order.
Code example
@Test
//Call Query All Refund API
public void queryAllRefundTest() throws IOException {
HttpGet httpGet = new HttpGet("https://apihk.mch.weixin.qq.com/v3/global/refunds" +
"?out_trade_no=YX202111100020&count=10&offset=0&sp_mchid=1900000000&sub_mchid=100012321");
httpGet.addHeader("Accept", "application/json");
httpGet.addHeader("Content-type", "application/json; charset=utf-8");
CloseableHttpResponse response = httpClient.execute(httpGet);
//Process the response
}
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.
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
@Test
//Downloading Reconciliation API
public void downloadReconTest() throws IOException {
HttpGet httpGet = new HttpGet("https://apihk.mch.weixin.qq.com/v3/global/statements?date=20220401&mchid=1900000000");
httpGet.addHeader("Accept", "application/json");
httpGet.addHeader("Content-type", "application/json; charset=utf-8");
CloseableHttpResponse response = httpClient.execute(httpGet);
//Process the response
}
Critical parameters:
date: Statement date, format: 20180103
Please refer to the API document for ordering by scanning code for other critical parameters.
Procedure: Call the payment interface to cancel the order after minimum 15 seconds. If the user fails to pay for this order, the WeChat payment system will close the order; otherwise, the WeChat payment system will refund the order to the user.
Code example
@Test
//Call revoke order API
public void RevokeOrderTest() throws IOException {
String revokeBody = String.join("\n" ,
"{" ,
" 'sp_mchid': '10000100'," ,
" 'sub_mchid': '20000100'" ,
"}").replace("'","\"");
HttpPost httpPost = new HttpPost("https://apihk.mch.weixin.qq.com/v3/global/micropay/transactions/out-trade-no/YX001/reverse");
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-type", "application/json; charset=utf-8");
httpPost.setEntity(new StringEntity(revokeBody));
CloseableHttpResponse response = httpClient.execute(httpPost);
//Process the response
}
Critical parameters:
out_trade_no: WeChat payment order ID
transaction_id: internal order ID in merchant’s system
Please refer to the API document for ordering by scanning code for other critical parameters.
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
@Test
//Call certificate downloading API
public void certDownloadingTest() throws IOException {
HttpGet httpGet = new HttpGet("https://apihk.mch.weixin.qq.com/v3/global/certificates");
httpGet.addHeader("Accept", "application/json");
httpGet.addHeader("Content-type", "application/json; charset=utf-8");
CloseableHttpResponse response = httpClient.execute(httpGet);
//Process the response
//Get the response body: EntityUtils.toString(response.getEntity());
//Get the response status code: response.getStatusLine().getStatusCode();
//Instead of calling the API to download platform certificate,
//We also recommend use the certificateMenager to get the valid certificate
verifier.getValidCertificate();
}
Critical parameters: None
Please refer to the API document for ordering by scanning code for other critical parameters.
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.
• 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.
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))
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
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.
Notification of Refund Result
{
"id": "EV-2018022511223320873",
"create_time": "2018-06-08T10:34:56+08:00",
"resource_type": "encrypt-resource",
"event_type": "REFUND.SUCCESS",
"summary": "退款成功",
"resource": {
"original_type": "refund",
"algorithm": "AEAD_AES_256_GCM",
"ciphertext": "...",
"associated_data": "",
"nonce": "..."
}
}
An example of the resource object obtained after the merchant decrypts the resource object
{
"sp_mchid": "1900000100",
"sub_mchid": "1900000109",
"transaction_id": "1008450740201411110005820873",
"out_trade_no": "20150806125346",
"refund_id": "50200207182018070300011301001",
"out_refund_no": "7752501201407033233368018",
"refund_status": "SUCCESS",
"success_time": "2018-06-08T10:34:56+08:00",
"recv_account": "招商银行信用卡0403",
"fund_source": "REFUND_SOURCE_UNSETTLED_FUNDS",
"amount" : {
"total": 528800,
"currency": "HKD",
"refund": 528800,
"payer_total": 528800,
"payer_refund": 528800,
"payer_currency": "HKD",
"exchange_rate" : {
"type": "SETTLEMENT_RATE",
"rate": 100000000
}
}
}
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.
Please refer to the API document for ordering by scanning code for other critical parameters.
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.
Code example
@Test
//Query Settlement API
public void querySettlementTest() throws IOException {
HttpGet httpGet = new HttpGet("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");
httpGet.addHeader("Accept", "application/json");
httpGet.addHeader("Content-type", "application/json; charset=utf-8");
CloseableHttpResponse response = httpClient.execute(httpGet);
//Process the response
}
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.
Customer Service Tel
Business Development
9:00-18:00
Monday-Friday GMT+8
Technical Support
WeChat Pay Global
ICP证