# 1 Background
# 1.1 Concepts
Non-tax revenue (NTR): Non-tax revenue is the financial fund other than tax revenue collected by governments and public institutions at all levels from public services, which includes service fees like entry-exit pass fees and ID card fees, penalties and confiscations from administrative departments of traffic, industry and commerce, and price, as well as ticket income from municipal parks and national scenic areas. Taking Guangzhou for example, 10 million NTR transactions were reported last year, generating a revenue of over 100 billion CNY. In 2016, the local NTR across the country hit 6 trillion CNY, while the central NTR reached 400 billion CNY. Management mode: Separation between revenue and expenditure. Generally, only one revenue account and one expenditure account are allowed per entity. The revenue account is dedicated for collecting money, except for financial transfers, whereas the expenditure account is dedicated for spending money, except for financial allocations. No transition account shall be established, and NTR payable shall be paid directly into the government's financial account for NTR that is opened at the designated agency bank, enforcing a system whereby "the entity produces the invoice, the bank collects the receivables, and the revenue is paid into the treasury (or revenue account) on a real-time basis".
# 1.2 Challenges
Payment model: Payment is made at a different window from where the service is provided with credit card only, or made through the bank. Most public services can only be queried online, but not get paid. Even if the service can be processed online, payment must be made via the Official Account or offline. Information exchange: In addition to the special payment method, business units also need to connect with banks to exchange business information, which is costly for both the banks and the business units. These problems have made it difficult to improve the public service ability.
# 1.3 Solutions
An NTR payment platform will be built to establish and simplify the connection between business units, finance authorities, and banks. After connecting the bank's NTR account to WeChat Pay, a flexible mechanism for revenue account selection will be established, and a standardized information exchange API will be developed to facilitate the access to different business units and solve the problems restricting the closed-loop development of public platform services.
# 2 Roles
# 2.1 Bank
The bank serves as the payment channel. The user's payment will go to the merchant account at the bank, and the NTR platform will update the payment status by calling the API provided by the bank. WeChat Pay will transfer the revenues to the bank account on a regular basis (T+1).
# 2.2 Finance Authorities
The finance authorities are responsible for recording the payment status. After the payment is made, the NTR platform will, by calling the API provided by the finance, update the payment status, which shall be the one as indicated on the financial record.
However, the financial role may also be played by the bank. Taking Guangdong for example, it is CCB that serves as the collector and the recorder in some places. For more information, see Direct Bank Connection in Business Mode.
# 2.3 Government Unit
The government unit, here referring to the business party, is responsible for placing orders for users by calling the order API provided by the NTR platform.
# 3 Business Mode Description
This section provides an overview of the three business modes in Weixin NTR Pay, and the information flow and APIs will be described in detail later (see Service Process, Special Cases, and APIs).
# 3.1 Direct Bank Connection
This is the mode where the NTR payment is connected to the finance system via the bank to facilitate information flow. It works great when the local finance does not arrange access or lacks development resources. Workflow chart for NTR payment in the frontend/backend in Direct Bank Connection mode
# 3.2 Direct Finance Connection
This is the mode where the NTR payment is connected to the finance system directly to facilitate information flow. It works great when the local finance arranges access and has strong development capabilities. Workflow chart for NTR payment in the frontend/backend in Direct Finance Connection mode
# 3.3 Direct Business Connection
The NTR payment is made based on the receivables of the business unit and connected to the finance system to facilitate information flow. It works great when there is no direct connection between the local business unit and the finance system. Workflow chart for NTR payment in the frontend/backend in Direct Business Connection mode
# 4 Account and Configurations
# 4.1 Preparations for the Accessing Party
# 4.1.1 APPID and APPSECRET of the Official Account
- The APPID and APPSECRET are used to get access_token, which can be found in the Official Accounts Platform. For more information, see this page.
- Developers need to provide the APPID of the Official Account to the person responsible for Weixin NTR Pay to configure API permissions. In case of one Official Account for test environment and one for production environment, provide the APPIDs separately.
# Introduction to access_token
How to get it:
HTTP request method: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
access_token is the globally unique credential for calling APIs in the Official Account. access_token is required for calls to all APIs, please save it properly. To store access_token, you need to reserve space for at least 512 characters. access_token is valid for 2 hours and needs to be updated periodically. Repeated acquisition will invalidate the access_token obtained last time. It is recommended to obtain and update access_token by using a central control server. All the access_token used by other business logic servers come from this central control server and should not be updated separately. Otherwise, access_token may be overwritten, which affects services.
For more information on access_token , see the Official Account development documentation.
For information on how to check the APPID and APPSECRET of the Official Account, see this page.
For information on how to set the IP whitelist of "Get access_token", see this page.
# 4.1.2 Weixin webpage authorization
By getting Weixin webpage authorization, the Official Account can obtain the user's openid to uniquely identify the user.
1. Setting webpage authorization callback domain
Before requesting the user's webpage authorization in the Weixin Official Account, please set the authorization callback domain name in Development > API Permissions > Webpage Services > Webpage Accounts > Get the basic user information via the webpage authorization on the Official Accounts Platform. Note that the domain name (a string) rather than the URL (starting with http://) should be entered here.
The authorization callback domain name should be configured to a fully qualified domain name. For example, if the domain requesting webpage authorization is www.qq.com, the pages under this domain such as http://www.qq.com/music.html and http://www.qq.com/login.html can be OAuth2.0 authenticated. However, pages like http://pay.qq.com, http://music.qq.com or http://qq.com may not get authenticated.
2. Webpage authorization process
- Guide the user to the authorization page to obtain the permission and code
- Get the webpage authorization access_token (different from the access_token in Basic Support) using the code
- Refresh the webpage authorization access_token if necessary to prevent it from expiring
- Get the basic user information via the webpage authorization access_token and openid (UnionID Mechanism is supported)
For more information on Weixin webpage authorization, see Weixin Webpage Authorization.
# 4.1.3 Payment Status Notification API
Payment Status Notification API is used to receive the payment status of the order. For more information, see Payment Status Notification section.
Please provide the Payment Status Notification APIs for test environment and production environment separately to the person responsible for Weixin NTR Pay for configuration.
# 4.1.4 Receivables Query API
Developers for the bank/finance authorities need to provide an API for querying receivables information. For more information, see Query Receivables section.
Please provide the Payment Status Notification APIs for test environment and production environment separately to the person responsible for Weixin NTR Pay for configuration.
# 4.1.5 Calling the IP address of the Refund API
The Refund API in Weixin NTR Pay has IP restrictions, which requires the caller to provide the IP list.
Please provide the Refund IPs for test environment and production environment separately to the person responsible for Weixin NTR Pay for configuration.
# 4.2 Test accounts of the Official Account
# 4.2.1 Test Merchant ID
Test Merchant ID for Weixin NTR Pay is 1900016021.
All the payments from test orders will go to this merchant account, and statements can be downloaded based on the Merchant ID.
# 4.2.2 Test Bank ID
test_bank_id is a special test bank ID in Weixin NTR Pay.
It can be used to test the order placement and payment process, regardless of the Payment Status Notification API and the Receivables Query API.
# 4.3 Outgoing IPs for Weixin NTR Pay
The outgoing IPs for calling the Payment Status Notification API and Receivables Query API in Weixin NTR Pay are as follows:
101.227.131.239
101.227.169.13
182.254.90.117
121.51.76.135
101.89.14.152
180.97.118.178
223.167.253.106
58.246.221.98
117.184.239.113
183.192.201.151
Please add these IPs to the firewall whitelist.
# 5 Business Process
Currently, Weixin NTR Pay supports a wide range of business scenarios. More information can be found in the description of the Order Placement API. Listed below are the most common payment scenarios.
# 5.1 Overall Architecture
A payment request is sent from the frontend to the backend of the business party. The latter then gets the access_token from its own-built access_token central control server, appends request parameters as required and calls the API for Weixin NTR Pay using the access_token. The access_token central control server updates access_token periodically (for example, once per hour). ### 5.2 Workflow Chart for Order Placement and Payment Multiple payment methods are supported in Weixin NTR Pay to meet the needs of different scenarios. The workflow for order placement and payment is described below, taking the most frequently used JSAPI Payment as an example. Other scenarios may show slight differences in the request parameters and response parameters for order placement. Workflow chart for order placement and payment The user confirms the order on the business page or the payment receipt (by tapping the button or scanning the QR code), after which the business party gets the user's open_id and sends an order request. After checking the information on the payment receipt, Weixin NTR Pay places the order and returns Order No. and payment link. The business party then sends the payment link to the frontend (or HTTP302 directly), where the link will be opened. After the user completes payment on the payment page, Weixin NTR Pay calls the Payment Status Notification APIs of the finance authorities, bank, and government unit to update the payment status. The user can now refresh the payment status on the payment page (the record of the finance authorities shall prevail). ### 5.3 Special Cases #### 5.3.1 NTR payment in Mini Programs In Mini Programs, order is placed using the AppID of the caller's Mini Program. In this process, the API will fetch the parameters (appId and path) required for NTR payment. For more information, see Results Returned by the Order Placement API.
Calling wx.navigateToMiniProgram in Mini Programs invokes the Mini Program for NTR payment. For more information, see Mini Program's APIs (appId and path are necessary parameters returned by the Order Placement API).
wx.navigateToMiniProgram({
appId: '',
path: 'pages/index/index?id=123',
success(res) {
// Opened successfully
}
})
After user payment or other operations, it returns to the caller's Mini Program, where the caller calls the Order Query API with the orderId returned by the Order Placement API to confirm payment status.
# 5.3.2 NTR payment in H5 pages in non-Weixin browsers
Openid can not be obtained in H5 pages opened using non-Weixin browsers. In this case, order is placed with trade_type set to MWEB and no openid.
Notes on web payment in H5 pages:
User IP: The user IP passed upon order placement must match with that used for payment via WeChat Pay. This IP should be obtained using the API on the user page. Otherwise, an error will occur (as shown below). For browsers that access the Internet using a proxy such as Huawei Browser and UC Browser, IP may change from request to request. Referer: When making payment via WeChat Pay, the Referer parameter will be checked to make sure the request is initiated under a valid domain name. Referer is often automatically included in browsers. In this case, capture the packet to check it.
Referer is used to determine the source of the request. When H5 payment calls the Weixin app, it checks whether the request is initiated from https://mp.weixin.qq.com. Therefore, when making H5 payment in apps, set the referer to https://mp.weixin.qq.com for requests initiated from pages under https://mp.weixin.qq.com, as well as a User-Agent that identifies the app (redirecting to the app after payment, which will be explained later).
For information on how to set Referer in iOS Webview, see this document.
For information on how to set Referer in Android Webview, see this document.
App redirecting: When the payment request on H5 pages is initiated from the app, by default, it may redirect to the default browser rather than the app after payment is made via Weixin. To redirect to the app, set a User-Agent that identifies the app when opening Webview, and provide the keyword and Url Scheme used for identification to us for configuration. In this way, the User-Agent will redirect based on the Url Scheme after payment.
For more information on Url Scheme, see this document. For information on how to set User-Agent in Android Webview, see this document. For information on how to set User-Agent in iOS Webview, see this document. If an error "The page cannot be found net:err_unknown_url_scheme" occurs when loading a page in Webview, see this document for solution.
# 5.3.3 NTR payment initiated from apps
The NTR payment initiated from apps is different from the workflow chart for order placement and payment shown in section 5.2 in that the Weixin SDK is called to launch Weixin, in which the payment link will be opened.
Example SDK called for Weixin NTR Pay in iOS:
WXNontaxPayReq *req = [[WXNontaxPayReq alloc] init];
req.urlString = "https://mp.weixin.qq.com/intp/nontax/pay?action=page&order_id=AQCApa-n9q8vjeoKDJ7fvb4X7d8W#wechat_redirect";
[WXApi sendReq:req];
Example SDK called for Weixin NTR Pay in Android:
WXNontaxPay.Req req = new WXNontaxPay.Req();
req.url = "https://mp.weixin.qq.com/intp/nontax/pay?action=page&order_id=AQCApa-n9q8vjeoKDJ7fvb4X7d8W#wechat_redirect";
api.sendReq(req);
For more information on the Weixin SDK, see:
Weixin SDK Access Guide Weixin SDK Download Weixin SDK sample codes for Android and iOS, focusing on XXXX (TODO)
# 6 APIs
# 6.1 APIs in Weixin NTR Platform
# 6.1.1 Receivables Query (for the government unit)
https://api.weixin.qq.com/nontax/queryfee?access_token=$AccessToken
(The request parameters and response parameters of all APIs must be in JSON format)
Request parameters
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | AppID |
service_id | int | Yes | Service ID |
bank_id | string | No | Bank ID (the globally unique ID assigned by Weixin NTR Platform), which, if not specified, is selected randomly from the list of banks configured |
payment_notice_no | string | Yes | No. of the payment notice |
department_code | string | Yes | Code of the collection entity |
payment_notice_type | int | No | Type of the payment notice 1: General notice 2: Penalty notice |
region_code | string | Yes | Code of the region |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
user_name | string | No | Name of the user |
fee | int | Yes | Total amount (in cents) |
items | json | Yes | Details on the payment items |
payment_notice_no | string | Yes | No. of the payment notice |
department_code | string | No | Code of the collection entity |
department_name | string | Yes | Name of the collection entity |
payment_notice_type | int | No | Type of the payment notice |
region_code | string | Yes | Code of the region |
payment_notice_create_time | int | No | Creation time of the payment notice (timestamp expressed in sec) |
payment_expire_date | string | No | Deadline for payment in YYYYMMDD |
The internal fields for items are as follows:
Field | Type | Required | Description |
---|---|---|---|
no | int | Yes | Item number, such as 1, 2, and 3 |
item_id | string | Yes | Item ID |
item_name | string | Yes | Item name |
overdue | int | No | Overdue payment (in cents) |
penalty | int | No | Penalties (in cents) |
fee | int | Yes | Amount (including overdue payment and penalties in cents) |
Example
Request parameters
{
"appid":"wx5f6e43071809a9dd",
"service_id": 123,
"bank_id":"470690268",
"payment_notice_no":"440204190185356",
"department_code":"143605002004",
"payment_notice_type":1,
"region_code":"440000"
}
Response
{
"department_code":"143605002004",
"department_name":"Detachment 1 of Traffic Police of Shaoguan Public Security Bureau",
"errcode":0,
"errmsg":"Payment overdue",
"fee":20000,
"items":[
{
"fee":20000,
"item_id":"103050101200",
"item_name":"Penalties for traffic violation",
"no":1,
"overdue":0
}
],
"payment_notice_create_time":1508806661,
"payment_notice_no":"440204190185356",
"payment_notice_type":1,
"region_code":"440000",
"user_name":"Ye*Mei"
}
# 6.1.2 Order Placement (for the government unit)
https://api.weixin.qq.com/nontax/unifiedorder?access_token=$AccessToken
Request parameters
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | AppID |
service_id | int | No | Service ID |
bank_id | string | No | Bank ID (the globally unique ID assigned by Weixin NTR Platform), which, if not specified, is selected randomly from the list of banks configured; it is left empty for the production environment while required for the test environment |
bank_account | string | No | Sorting bank account (left empty if sorting mechanism is not used) |
mch_id | string | No | Specifies the mch_id to which the payment is settled. Only the mch_ids linked with bank_id are available. If not specified, the system will automatically choose one from those linked. |
openid | string | No | User ID. It is only optional when trade_type is MWEB. |
desc | string | Yes | Description (service name) |
fee | int | Yes | Total amount (in cents) |
return_url | string | No | The page redirected to after payment is made at the intermediate page (It is only optional when the order is placed in Mini Programs) |
ip | string | Yes | The IP of the user |
order_no | string | No | Order No. (Either the payment notice No. or the order No. must be provided. If the payment notice No. is not specified, the order No. is required) |
payment_notice_no | string | No | Payment notice No. (Either the payment notice No. or the order No. must be provided. If the payment notice No. is not specified, the order No. is required) |
department_code | string | Yes | Code of the collection entity |
department_name | string | Yes | Name of the collection entity |
payment_notice_type | int | No | Type of the payment notice |
region_code | string | Yes | Code of the region |
user_name | string | No | Name of the user |
items | json | Yes | Details on the payment items |
payment_notice_create_time | int | Yes | Creation time of the payment notice (timestamp, in sec) |
payment_expire_date | string | No | Deadline for payment in YYYYMMDD |
scene | string | Yes | Scene. "biz": Weixin Official Accounts "ctiyservice": City services "miniprogram": Mini Programs |
app_appid | string | No | The AppID of the app. It is only required when order is placed in apps. |
trade_type | string | No | It defaults to JSAPI. Set it to MWEB when placing order on H5 pages in non-Weixin browsers. |
auto_call_pay | bool | No | Specifies whether to call payment automatically at the intermediate page or in the Mini Program |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
order_id | string | Yes | Order No. |
pay_url | string | No | The payment link returned when placing order in Official Accounts or apps |
miniprogram | string | No | The parameter invoked by the Mini Program and returned when placing order in the Mini Program |
The internal fields for miniprogram are as follows:
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | The AppID of the Mini Program for payment |
pagepath | string | Yes | The page path of the Mini Program for payment |
business_type | string | Yes | The business type of the Mini Program for payment |
query_string | string | Yes | The parameter of the Mini Program for payment |
Example
Request parameters
{
"appid":"wx5f6e43071809a9dd",
"bank_account":"",
"bank_id":"test_bank_id",
"department_code":"1",
"department_name":"test",
"desc":"Test payment",
"fee": 2,
"ip":"113.68.115.241",
"items":[
{
"fee":2,
"item_id":"103050101200",
"item_name":"Test payment2",
"no":1,
"overdue":0
}
],
"openid": "ont-9vjAcIdSU-LgB7ubALAVJO9U",
"payment_expire_date":"",
"payment_notice_no":"08111639088",
"payment_notice_type": 1,
"region_code":"440000",
"return_url":"http://cockpouncher.55555.io/nontax-wxpay/pay_demand_result.html?type=showPayResult®ion_code=44000&unitNo=1&payNoticeNo=1",
"service_id":0,
"user_name":"Zhang*Feng"
}
Response
{
"errcode": 0,
"errmsg": "ok",
"order_id": "AQCAzieFp6-dC8EKDJ7fvb6x3dZt",
"pay_url": "https://mp.weixin.qq.com/intp/nontax/pay?action=page&order_id=AQCAzieFp6-dC8EKDJ7fvb6x3dZt#wechat_redirect"
}
# 6.1.3 Order Query (for the government unit, bank and finance authorities)
https://api.weixin.qq.com/nontax/getorder?access_token=$AccessToken
Request parameters
Field | Required | Description |
---|---|---|
appid | string | Yes |
service_id | int | No |
order_id | string | Yes |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
appid | string | Yes | AppID |
openid | string | Yes | User ID |
order_id | string | Yes | Order No. |
create_time | int | Yes | Creation time of the order (timestamp, in sec) |
pay_finish_time | int | Yes | Finish time of order payment (timestamp, in sec) |
desc | string | Yes | Description (service name) |
fee | int | Yes | Total amount (in cents) |
fee_type | int | Yes | Currency 1: CNY 2: US Dollar |
trans_id | string | Yes | Payment transaction order number |
status | int | Yes | Order status 1: To be paid 3 or 4: Payment successful 5: Refunded 6: Awaiting refund 12: Order canceled due to payment timeout (In case of partial refund, the order status will not change to Refunded until all refunds are completed) |
bank_id | string | Yes | Bank ID (the globally unique ID assigned by Weixin NTR Platform) |
bank_name | string | Yes | Bank name |
bank_account | string | Yes | Bank account number |
refund_finish_time | int | No | Finish time of refund (timestamp, in sec) |
refund_reason | string | No | Refund reasons |
refund_order_id | string | No | Refund order No. |
refund_out_id | string | No | External order No. entered during refund |
payment_notice_no | string | No | Payment notice No. (returned based on the parameter requested upon order placement) |
order_no | string | No | Order No. (returned based on the parameter requested upon order placement) |
department_code | string | No | Code of the collection entity |
department_name | string | Yes | Name of the collection entity |
payment_notice_type | int | No | Type of the payment notice |
region_code | string | Yes | Code of the region |
items | json | Yes | Details on the payment items |
bill_type_code | string | No | Bill type code |
bill_no | string | No | Bill No. |
payment_info_source | int | Yes | Source of information on receivables 1: Finance authorities 2: Government unit |
partial_refund_info | json | No | Information on partial refund |
notify_history | json | Yes | Notification history |
scene | string | Yes | Scene. "biz": Weixin Official Accounts "ctiyservice": Ctiy services "miniprogram": Mini Programs "offline": Offline QR codes "pc": PC "app": Mobile apps "other": Others |
The internal fields for partial_refund_info are as follows:
Field | Type | Required | Description |
---|---|---|---|
refund_order_id | string | Yes | Refund order No. |
refund_reason | string | Yes | Refund reasons |
refund_fee | int | Yes | Refund amount (in cents) |
refund_finish_time | int | Yes | Finish time of refund (timestamp, in sec) |
refund_out_id | string | Yes | External order No. entered during refund |
refund_status | int | Yes | Refund status 5: Refunded 6: Awaiting refund |
The internal fields for notify_history are as follows:
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | Third-party platform's AppID |
name | string | Yes | Third-party platform's name |
notify_detail | json | No | Details on the notification (the first and last notification) |
notify_cnt | int | Yes | Number of notifications |
The internal fields for notify_detail are as follows:
Field | Type | Required | Description |
---|---|---|---|
notify_time | int | Yes | Time of notification (timestamp, in sec) |
ret | int | Yes | Error codes for notifications in the Weixin backend |
ret_errmsg | string | Error messages for notifications in the Weixin backend | |
cost_time | int | Yes | Time spent (in ms) |
wxnontaxstr | string | Yes | Random string appended to the url parameter per request |
status | int | Yes | Order status 3 or 4: Payment successful 5: Refunded |
url | string | Yes | The URL to receive the notification by the third-party platform |
errcode | int | No | Error code from the third-party platform 0 - Successful 210 - Invalid data format 232 - Payment completed 236 - Payment through this bank is not supported 298 - Decryption fails 299 - System error 300 - Invalid signature |
errmsg | string | No | Error message from the third-party platform. A non-NULL value indicates the error cause. |
third_resp | string | No | Response from the third-party platform |
third_resp_data | string | No | Data decrypted from the response of the third-party platform |
Example
Request parameters
{
"appid": "wx5f6e43071809a9dd",
"order_id": "AQCAGxwqp6-aBeIKDJ7fvb6x3dZt",
}
Response
{
"errcode": 0,
"errmsg": "ok",
"appid": "wx5f6e43071809a9dd",
"openid": "ont-9vjAcIdSU-LgB7ubALAVJO9U",
"order_id": "AQCAGxwqp6-aBeIKDJ7fvb6x3dZt",
"create_time": 1508847678,
"pay_finish_time": 0,
"desc": "Test service payment",
"fee": 1,
"fee_type": 1,
"trans_id": "",
"status": 12,
"bank_id": "test_bank_id",
"bank_name": "Test_bank",
"bank_account": "6215385809487657",
"refund_finish_time": 0,
"items": [
{
"no": 1,
"item_id": "000001",
"item_name": "Test service payment1",
"overdue": 0,
"fee": 1
},
{
"no": 2,
"item_id": "000002",
"item_name": "Test service payment2",
"overdue": 0,
"fee": 0
}
],
"bill_type_code": "",
"bill_no": "",
"payment_info_source": 2,
"payment_notice_no": "08111639088",
"department_code": "118610002",
"department_name": "Test collection entity",
"payment_notice_type": 1,
"region_code": "440000",
"notify_history": [
{
"appid": "wx5f6e43071809a9dd",
"name": "Test finance authorities",
"notify_detail": [
{
"notify_time": 1524023367,
"ret": 0,
"cost_time": 39,
"wxnontaxstr": "2ba37f90d155d390",
"status": 3,
"errcode": 0,
"errmsg": ""
}
],
"notify_cnt": 1
},
{
"appid": "wxefd0818f53b9b82f",
"name": "Test the government unit",
"notify_detail": [
{
"notify_time": 1524023367,
"ret": 0,
"cost_time": 20,
"wxnontaxstr": "f7ad824e08ac4bc5",
"status": 3,
"errcode": 0,
"errmsg": ""
}
],
"notify_cnt": 1
},
{
"appid": "wxf1bfa94c33668abf",
"name": "Test bank",
"notify_detail": [
{
"notify_time": 1524023367,
"ret": 0,
"cost_time": 18,
"wxnontaxstr": "2e628b6f1e3e9bf3",
"status": 3,
"errcode": 0,
"errmsg": ""
}
],
"notify_cnt": 1
}
]
}
6.1.4 Refund Request (for banks) https://api.weixin.qq.com/nontax/refund?access_token=$AccessToken
Request parameters
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | AppID |
order_id | string | Yes | Order No. |
reason | string | Yes | Refund reasons |
refund_fee | int | No | Refund amount (in cents). It is required for partial refund. |
refund_out_id | string | No | Refund order No. (unique per partial refund). It is required for partial refund. |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
refund_order_id | string | Yes | Refund order No. |
Example
Request parameters
{
"appid":"wx6cc9648de104270d",
"order_id":"AQCAGxwqp6-aBeIKDJ7fvb6x3dZt",
"reason":"Duplicate payments online and offline. The canceled bill No. is DA01651861"
}
Response
{
"errcode": 0,
"errmsg": "ok"
}
6.1.5 Statement Download (for banks) https://api.weixin.qq.com/nontax/downloadbill?access_token=$AccessToken
Note: Please obtain it after 6:00 am every day.
Request parameters
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | AppID |
mch_id | string | No | Merchant ID. The specific statement will be returned if Merchant ID is provided. Otherwise, all statements packaged in a zip file will be returned. |
bill_date | string | Yes | Bill date, for example 20170903 |
bill_type | string | No | ALL (default) returns all orders on the current day; SUCCESS returns the orders paid successfully on the current day; REFUND returns the orders refunded on the current day. |
In case of failure, the following fields are returned:
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
In case of success, the data is returned in csv format, with the first row as the header and the following rows containing field contents. (Fields may be added or deleted, please refer to the actual situation)
The first row, i.e. the header, varies by the type of the statements to be downloaded (depending on bill_type). The currently available ones are listed below:
All orders on the current day
Transaction time, Official Account ID, merchant ID, sub-merchant ID, Weixin order No., merchant order No., user ID, transaction type, transaction status, paying bank, currency type, total amount, amount of company red packets, Weixin refund order No., merchant refund order No., refund amount, refund amount of company red packets, refund type, refund status, product name, service fee, rate, code of the region, payment notice No. (or platform order No.), code of the collection entity, type of the payment notice, bank ID
Orders paid successfully on the current day
Transaction time, Official Account ID, merchant ID, sub-merchant ID, Weixin order No., merchant order No., user ID, transaction type, transaction status, paying bank, currency type, total amount, amount of company red packets, Weixin refund order No., merchant refund order No., refund amount, refund amount of company red packets, refund type, refund status, product name, service fee, rate, code of the region, payment notice No. (or platform order No.), code of the collection entity, type of the payment notice, bank ID
Orders refunded on the current day
Transaction time, Official Account ID, merchant ID, sub-merchant ID, Weixin order No., merchant order No., user ID, transaction type, transaction status, paying bank, currency type, total amount, amount of company red packets, Weixin refund order No., merchant refund order No., refund amount, refund amount of company red packets, refund type, refund status, product name, service fee, rate, code of the region, payment notice No. (or platform order No.), code of the collection entity, type of the payment notice, bank ID
Data records start from the second row. Parameters are separated by a comma and start with "`", the character to the left of key 1 in standard keyboard. The order of fields matches with the header.
The last but one row shows order titles, while the last row provides statistical data.
Total transaction numbers, total transaction amount, total refund amount, total refund amount of company red packets, total service fees
For example:
Transaction time, Official Account ID, merchant ID, sub-merchant ID, Weixin order No., merchant order No., user ID, transaction type, transaction status, paying bank, currency type, total amount, amount of company red packets, Weixin refund order No., merchant refund order No., refund amount, refund amount of company red packets, refund type, refund status, product name, service fee, rate, code of the region, payment notice No. (or platform order No.), code of the collection entity, type of the payment notice, bank ID
`2017-06-01 15:33:10,`wxc971985892358997,`1800004561,`1900016021,`4004332001201706013698057350,`AQCA6cNHMa5QlD4KDJ7fvb6x3dZt,`oFkLxtyJswfbex9crZWHGDYG5NIw,`JSAPI,`SUCCESS,`CMB_CREDIT,`CNY,`0.01,`0.00,`0,`0,`0.00,`0.00,`,`,`service payment,`0.00000,`0.00%,`440100,`17001122412,`000000,`1
`2017-06-01 15:44:30,`wxc971985892358997,`1800004561,`1900016021,`4004332001201706013704498976,`AQCAlxpOMa5QlD4KDJ7fvb6x3dZt,`oFkLxtyJswfbex9crZWHGDYG5NIw,`JSAPI,`SUCCESS,`CMB_CREDIT,`CNY,`0.01,`0.00,`0,`0,`0.00,`0.00,`,`,`service payment,`0.00000,`0.00%,`440100,`17001122413,`000000,`1
Total transaction numbers, total transaction amount, total refund amount, total service fees
`2,`0.02,`0.0,`0
Example
Request parameters:
{
"appid": "wx6cc9648de104270d",
"mch_id": "1900016021",
"bill_date": "20170925",
"bill_type": "ALL",
}
Response:
Transaction time, Official Account ID, merchant ID, sub-merchant ID, Weixin order No., merchant order No., user ID, transaction type, transaction status, paying bank, currency type, total amount, amount of company red packets, Weixin refund order No., merchant refund order No., refund amount, refund amount of company red packets, refund type, refund status, product name, service fee, rate, code of the region, payment notice No. (or platform order No.), code of the collection entity, type of the payment notice, bank ID
`2017-09-25 09:39:03,`wxc971985892358997,`1800004561,`1900016021,`4200000022201709254109017673,`AQAAc_FXW6_CCUtkDNP0Z7csEgVD,`,`JSAPI,`SUCCESS,`CFT,`CNY,`0.02,`0.00,`0,`0,`0.00,`0.00,`,`,`NTR payment via WeChat Pay in Guangdong,`0.00000,`0.00%,`440000,`1713372142,`118610002,`1,`test_470690267
`2017-09-25 10:05:01,`wxc971985892358997,`1800004561,`1900016021,`4200000022201709254114686941,`AQCA7tdjW6-aAFhkDNP0Z7csEgVD,`,`JSAPI,`SUCCESS,`CFT,`CNY,`0.02,`0.00,`0,`0,`0.00,`0.00,`,`,`NTR payment via WeChat Pay in Guangdong,`0.00000,`0.00%,`440000,`1713372144,`118610002,`1,`test_470690267
`2017-09-25 10:08:37,`wxc971985892358997,`1800004561,`1900016021,`4200000023201709254110290403,`AQCARHplW6-PTDcKDNP0Z7c4qUGm,`,`JSAPI,`SUCCESS,`CFT,`CNY,`0.02,`0.00,`0,`0,`0.00,`0.00,`,`,`NTR payment via WeChat Pay in Guangdong,`0.00000,`0.00%,`440000,`1713372146,`118610002,`1,`test_470690267
`2017-09-25 10:22:18,`wxc971985892358997,`1800004561,`1900016021,`4200000010201709254114144003,`AQCAD8BrW68VlT4KDNP0Z7c4qUGm,`,`JSAPI,`SUCCESS,`CFT,`CNY,`0.02,`0.00,`0,`0,`0.00,`0.00,`,`,`NTR payment via WeChat Pay in Guangdong,`0.00000,`0.00%,`440000,`1713372150,`118610002,`1,`test_470690267
`2017-09-25 11:58:35,`wxc971985892358997,`1800004561,`1900016021,`4200000012201709254136555152,`AQCAkL-XW69fTTcKDNP0Z7dYl29t,`,`JSAPI,`SUCCESS,`CFT,`CNY,`0.02,`0.00,`0,`0,`0.00,`0.00,`,`,`NTR payment via WeChat Pay in Guangdong,`0.00000,`0.00%,`440000,`1713372148,`118610002,`1,`test_470690266
`2017-09-25 14:33:16,`wxc971985892358997,`1800004561,`1900016021,`4200000023201709254163519598,`AQCA9J_eW68VlT4KDNP0Z7c4qUGm,`,`JSAPI,`SUCCESS,`CFT,`CNY,`0.02,`0.00,`0,`0,`0.00,`0.00,`,`,`NTR payment via WeChat Pay in Guangdong,`0.00000,`0.00%,`440000,`1713372154,`118610002,`1,`test_470690267
Total transaction numbers, total transaction amount, total refund amount, total refund amount of company red packets, total service fees
`6,`0.12,`0.00,`0.00,`0.00000
6.1.6 Inconsistent Order Notification (for finance authorities) https://api.weixin.qq.com/nontax/notifyinconsistentorder?access_token=$AccessToken
Note: Calling this API triggers the Weixin backend to call Payment Status Notification API (if the previous notification failed).
Common use case: During account checking, if an order is found in Weixin statement but not in your system, this API can be called to trigger Weixin to send another notification.
Request parameters
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | AppID |
order_id | string | Yes | Order No. |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
Example
Request parameters
{
"appid":"wx6cc9648de104270d",
"order_id":"AQCAGxwqp6-aBeIKDJ7fvb6x3dZt"
}
Response
{
"errcode": 0,
"errmsg": "ok"
}
6.1.7 Test Payment Status Notification https://api.weixin.qq.com/nontax/mocknotification?access_token=$AccessToken
Note: This API is used by the accessing party to debug the encryption/decryption feature and other basic logics of the Payment Status Notification API before integration test. If version is 1, notification will be sent twice to test whether encryption/decryption works properly and whether signature has been verified. Calling this API triggers the Weixin backend to send the test data for payment status notification to url .
Request parameters
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | AppID |
url | string | Yes | The URL to receive the notification |
version | int | Yes | Protocol version number, which defaults to 1 |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
6.1.8 Test Receivables Query https://api.weixin.qq.com/nontax/mockqueryfee?access_token=$AccessToken
Note: This API is used by the accessing party to debug the encryption/decryption feature and other basic logics of the Receivables Query API before integration test. If version is 1, notification will be sent twice to test whether encryption/decryption works properly and whether signature has been verified. Calling this API triggers the Weixin backend to send the test data for receivables query to url .
Request parameters
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | AppID |
url | string | Yes | The URL to receive the notification |
version | int | Yes | Protocol version number, which defaults to 1 |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
6.1.9 Quick Pay Submission After payment request is submitted, Weixin will return the payment status synchronously. If the API returns a system failed message, call it again after 5 seconds and check the error code. If it indicates password is required for payment, call the API on a regular basis (recommended every 10 seconds), until success, failure, or timeout (recommended 30 seconds) is determined.
https://api.weixin.qq.com/nontax/micropay?access_token=$AccessToken
Request parameters
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | AppID |
bank_id | string | No | Bank ID (the globally unique ID assigned by Weixin NTR Platform), which, if not specified, is selected randomly from the list of banks configured; it is left empty for the production environment while required for the test environment |
bank_account | string | No | Sorting bank account (left empty if sorting mechanism is not used) |
mch_id | string | No | Specifies the mch_id to which the payment is settled. Only the mch_ids linked with bank_id are available. If not specified, the system will automatically choose one from those linked. |
desc | string | Yes | Description (service name) |
fee | int | Yes | Total amount (in cents) |
user_name | string | No | Name of the user |
items | json | Yes | Details on the payment items |
payment_notice_create_time | int | Yes | Creation time of the payment notice (timestamp, in sec) |
payment_expire_date | string | No | Deadline for payment in YYYYMMDD |
payment_notice_no | string | No | Payment notice No. (Either the payment notice No. or the order No. must be provided. If the payment notice No. is not specified, the order No. is required) |
order_no | string | No | Order No. (Either the payment notice No. or the order No. must be provided. If the payment notice No. is not specified, the order No. is required) |
department_code | string | Yes | Code of the collection entity |
department_name | string | Yes | Name of the collection entity |
payment_notice_type | int | No | Type of the payment notice |
region_code | string | Yes | Code of the region |
auth_code | string | Yes | Authorization code for payment by scanning the code. The barcode or QR code in Weixin will be read. (Note: The standard barcode for Quick Pay is a 18-digit number starting with 10, 11, 12, 13, 14, or 15) |
order_id | string | No | Order No. (required if the order No. is returned for the previous request) |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
order_id | string | Yes | Order No. |
Example
Request parameters
{
"appid": "wx5f6e43071809a9dd",
"bank_id": "test_bank_id",
"bank_account": "",
"desc": "Test service payment",
"fee": 1,
"user_name": "*Sanqiang",
"items": [
{
"no": 1,
"item_id": "000001",
"item_name": "Test service payment1",
"overdue": 0,
"fee": 1
},
{
"no": 2,
"item_id": "000002",
"item_name": "Test service payment2",
"overdue": 0,
"fee": 0
}
],
"payment_notice_create_time": 1500967298,
"payment_expire_date": "20190102",
"payment_notice_no": " 08111639088",
"department_code": "118610002",
"department_name": "Test collection entity",
"region_code": "440000",
"auth_code": " 134971951305811268"
}
Response
{
"errcode": 0,
"errmsg": "ok",
"order_id": "AQAA_UjjdbLiUjMKDJ7fvb4AAAAA"
}
Error Codes
Error Code | Description |
---|---|
-1 | System failure |
9201033 | Empty authorization code |
9207003 | Payment failed. Try again. |
9207004 | The QR code has expired. Refresh it in Weixin and try again. |
9207005 | Insufficient balance. Try again with another card. |
9207006 | The current payment is not supported by this card. Try again with another card or link a new card. |
9207007 | The current order status is "Order Canceled". Pay again. |
9207008 | Password is required for payment. |
9207009 | Invalid parameter for the authorization code. Each QR code can only be used once. Refresh and try again. |
9207010 | Invalid authorization code. It is not a WeChat Pay barcode that the cashier scanned. |
# 6.1.10 Order List Query
https://api.weixin.qq.com/nontax/getorderlist?access_token=$AccessToken
Request parameters
| Field | Type | Required | Description | | --- | --- || --- | --- | |appid|string| Yes | AppID | |region_code|string| Yes | Code of the region | |department_code|string| Yes | Code of the collection entity | |payment_notice_no|string| No | Payment notice No. (Either the payment notice No. or the order No. must be provided. If the payment notice No. is not specified, the order No. is required) | |order_no|string| No | Order No. (Either the payment notice No. or the order No. must be provided. If the payment notice No. is not specified, the order No. is required) |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | Error code |
errmsg | string | No | Description of the error code |
In case of success, the following fields are returned:
Field | Type | Required | Description |
---|---|---|---|
order_id_list | json | No | The ID list of the orders placed |
paid_order_id | string | No | The ID of the orders paid |
Example
Request parameters
{
"appid": "wx5f6e43071809a9dd",
"payment_notice_no": "34000019081115065040",
"department_code": "065080906",
"region_code": "340000"
}
Response
{
"errcode": 0,
"errmsg": "ok",
"order_id_list": [
"AQCAxFJwcrQqI2BkDAqRH-UhDq2D",
"AQAAgrVxcrRuhXBkDAqRH-UhDq2D",
"AQCAFxFzcrQqI2BkDAqRH-UhDq2D",
"AQCA5_3kcrSQCxMJDAGMadMAAAAA",
"AQCA6ADlcrQqI2BkDAGMadMAAAAA",
"AQCA62hwdbQqI2BkDAqRH-U4tE4p"
],
"paid_order_id": "AQCA62hwdbQqI2BkDAqRH-U4tE4p"
}
# 6.2 APIs Provided by Banks/Finance Authorities
# 6.2.1 Receivables Query
Request parameters
Field | Type | Required | Description |
---|---|---|---|
appid | string | Yes | AppID |
region_code | string | Yes | Code of the region |
payment_notice_no | string | Yes | No. of the payment notice |
department_code | string | No | Code of the collection entity |
payment_notice_type | int | No | Type of the payment notice |
bank_id | string | Yes | Bank ID (the globally unique ID assigned by Weixin NTR Platform) |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | 0 - Payment overdue; 210 - Invalid data format; 211 - Payment is not supported (the entity or project is suspended); 231 - Payment notice does not exist; 232 - Payment completed; 233 - Payment notice is canceled; 235 - Late payment is not allowed; 236 - Payment through this bank is not supported; 296 - Payment notice error; 297 - Payment is suspended; 298 - Decryption failed; 299 - System error; 300 - Invalid signature |
errmsg | string | No | Error message |
If errcode is 0, the following fields are returned:
Field | Type | Required | Description |
---|---|---|---|
region_code | string | Yes | Code of the region |
payment_notice_no | string | Yes | No. of the payment notice |
department_code | string | No | Code of the collection entity |
department_name | string | Yes | Name of the collection entity |
payment_notice_type | int | Yes | Type of the payment notice |
user_name | string | No | Name of the payer |
payment_notice_create_time | int | No | Creation time of the payment notice (timestamp, in sec) |
payment_expire_date | string | No | Deadline for payment in YYYYMMDD |
fee | int | Yes | Amount, in cents |
items | json | Yes | Details on the payment items |
If errcode is 232 , the following fields are returned when payment has been completed:
Field | Type | Required | Description |
---|---|---|---|
pay_channel | string | No | Payment channel, and "wx_nontax" represents Weixin NTR Platform. |
order_id | string | No | The No. of the order already paid will be returned when the payment channel is Weixin NTR Platform. |
Example
Request parameters
{
"appid": "wx_appid",
"bank_id":"470690268",
"payment_notice_no":"440204190185356",
"department_code":"143605002004",
"payment_notice_type":1,
"region_code":"440000"
}
Response
{
"department_code":"143605002004",
"department_name":"Detachment 1 of Traffic Police of Shaoguan Public Security Bureau",
"errcode":0,
"errmsg":"Payment overdue",
"fee":20000,
"items":[
{
"fee":20000,
"item_id":"103050101200",
"item_name":"Penalties for traffic violation",
"no":1,
"overdue":0
}
],
"payment_notice_create_time":1508806661,
"payment_notice_no":"440204190185356",
"payment_notice_type":1,
"region_code":"440000",
"user_name":"Ye*Mei"
}
6.2.2 Status Notification Request parameters
Field | Type | Required | Description |
---|---|---|---|
order_id | string | Yes | Order No. in the Weixin NTR Platform |
status | int | Yes | Status: 3 or 4: Paid 5: Refunded |
pay_channel | string | Yes | Payment channel, and "wx_nontax" represents Weixin NTR Platform. |
pay_finish_time | int | Yes | Finish time of order payment (timestamp, in sec) |
Response (returned by the finance authorities in Direct Finance Connection mode, or otherwise by the bank)
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | 0 - Successful; 210 - Invalid data format; 211 - Payment is not supported (the entity or project is suspended) (Refund is triggered automatically); 231 - Payment notice does not exist (Refund is triggered automatically); 232 - Payment completed (Refund is triggered automatically when the order_id returned does not match the order_id in the notice); 233 - Payment notice is canceled (Refund is triggered automatically) ;235 - Late payment is not allowed (Refund is triggered automatically); 236 - Payment through this bank is not supported (Refund is triggered automatically); 296 - Payment notice error (Refund is triggered automatically); 297 - Payment is suspended for now; 298 - Decryption failed; 299 - System error; 300 - Invalid signature. |
errmsg | string | No | Error message. A non-NULL value indicates the error cause. |
Response (returned by the bank in Direct Finance Connection mode)
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | 0 - Successful; 299 - System error |
errmsg | string | No | Error message. A non-NULL value indicates the error cause. |
Example
Request parameters
{
"order_id":"AQCADTPupa-aBeIKDD96k7MbdosN",
"status":3,
"pay_channel":"wx_nontax",
"pay_finish_time":1508806264
}
Response
{
"bill_no":"AB00002027",
"bill_type_code":"333333",
"errcode":0,
"errmsg":"Successful",
}
6.3 APIs Provided by the Government Unit
6.3.1 Status Notification Request parameters
Field | Type | Required | Description |
---|---|---|---|
order_id | string | Yes | Order No. in the Weixin NTR Platform |
status | int | Yes | Status: |
3 or 4: Paid | |||
5: Refunded | |||
pay_channel | string | Yes | Payment channel, and "wx_nontax" represents Weixin NTR Platform. |
pay_finish_time | int | No | Finish time of order payment, only available when the status is Paid (timestamp, in sec). |
refund_finish_time | int | No | Finish time of order refund, only available when the status is Refunded (timestamp, in sec). |
refund_fee | int | No | Refund amount. It is required for partial refund. |
refund_order_id | string | No | Refund order No. It is required for partial refund. |
Response
Field | Type | Required | Description |
---|---|---|---|
errcode | int | Yes | 0 - Successful; 210 - Invalid data format; 298 - Decryption failed; 299 - System error; 300 - Invalid signature. |
errmsg | string | No | Error message. A non-NULL value indicates the error cause. |
Example
Request parameters
{
"order_id":"AQCAXCfypa-dC8EKDD96k7NeiEFb",
"status":3,
"pay_channel":"wx_nontax",
"pay_finish_time":1508806792
}
Response
{
"errcode":0,
"errmsg":"Successful"
}
# 7 Data Encryption and Decryption
When calling Payment Status Notification API and Receivables Query API, Weixin NTR Pay transmits the data after encryption at the application layer for enhanced security.
# 7.1 Key Management
1.The static key used for symmetric encryption, containing 256 characters, is preset to the Weixin NTR Pay backend by the third party. (Automatic key configuration will be available in the Weixin Official Accounts Platform later, but for now it has to be configured manually.) 2.The key pair (public key and private key) used for asymmetric encryption is generated and assigned by Weixin NTR Pay. The public key is assigned to the accessing party, while the private key is saved at the Weixin NTR Pay backend. 3. For more information on encryption/decryption methods and process, see below.
# 7.2 Methods and Description of Encryption and Decryption
Request parameters
Field | Type | Required | Description |
---|---|---|---|
data | string | Yes | The data encrypted using symmetric encryption algorithm and Base64 encoded. It is originally a JSON string. |
base64( iv + AES(plaintext, key, iv) ) | |||
(where iv refers to the first 16 bytes after base64 decoding) | |||
data_encrypt_type | string | Yes | The symmetric encryption algorithm of data: AES/CBC/PKCS7Padding |
sign | string | Yes | Signature (a digest of the original data encrypted with the private key) |
sign_type | string | Yes | The signature type is "SHA256withRSA" |
version | int | Yes | Protocol version number |
appid | string | Yes | The AppID of the Official Account for notification |
Response
Field | Type | Required | Description |
---|---|---|---|
data | string | Yes | The data encrypted using the symmetric encryption algorithm and Base64 encoded. It is originally a JSON string. base64( iv + AES(plaintext, key, iv) ) |
data_encrypt_type | string | Yes | The symmetric encryption algorithm of data (as requested) |
Example
Test public key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6gQV44C65NrdmeqJVAw
GPPd7+8JyE6brZlHsNtsbE+P9yJOaz68KbLcygmf67abtASEHWAGre1ju32t2+NY
rkaMu5DUyJ7ROJJpmUkv1D1y7GhuIfANvnTr8/a29AFwx2HZZvuoOi9mGq6iNi/H
+PoFTGbmTyatl+D10rFCCM2oHiS/8mC+2xfCGm6pmKaVocekVUOOQYHHGNO3OpeU
s+Cn0cukhuNt03iWsZ5KOx9qy7QbletNoriymi3NI9Gb/6mfx7k+d0sJMg8aLz/F
GSBOp0JSyAmjjSdO85Jhe1PCiOMwMBJgMi1711RFz09LrOZZxdEoyCVddWg/ynzP
mQIDAQAB
-----END PUBLIC KEY-----
Test symmetric key
UBmCt8sJzEXBJKpt0F5C0POrMMrbaCQx
Request parameters:
{
"data":"apckvM3mqLEeFF9qGhXHR/1MPpI8gi58aZA+KpumHPRIAYSBaSuIGM6iWCagZSoPRi39aEFUPOoEI5WdQXmPSJ2KdiO8+h47CNn3n++fQrPYephr/pucl2PARtiOcDeoqHaolgzgwMCjnPYCSIGVlfE3yrSz8CNwMv0JuO4OmTvCwROlCH2LiDn9D6R2GFEovgapyzwLqp/za4SyF84Ulun0hkN8wSAJuZnpdkGcekQ=",
"data_encrypt_type":"AES/CBC/PKCS7Padding",
"appid":"wx5f6e43071809a9dd",
"sign":"kzh/xptOlrRlF5bkxt322JtQzeeTn3rHElyLf3IWCzUsa6m2Y7iBAGbuev+P/g6UJw7GUoZm1hiAoItRLlZMKUFB5sHIP9Th90fnX9scZMKZLjwwKNRMa3R/Q9OcuK623put30leW6KSF10m+9u00JNjpN/yKyABT6nGIQCK1qUmJHK5r4wenF3wo+ELvWsIhZytpfFs9ALt9JKFXYsrOgggN4lLt/omNB60H71OuR+6itMYqk8KTUNYrFA7dOvvhJouG6maHr9ShGZQegQN6fpQouDdz+hnD8WCqSPmS3gtrxGBfQ2+OpOvl4mwFMHmEkUVSplmPnP4lBJrcdDxXg==",
"sign_type":"SHA256withRSA",
"version":1
}
Decryption process:
Decrypt the contents in the data field using AES symmetric encryption algorithm (AES/CBC/PKCS7Padding) to get the plaintext of the notification. The plaintext here refers to the request parameters of the Receivables Query API or Payment Status Notification API.
Verify sign based on the encryption result of the data field and the public key. (Weixin NTR Platform performs signature verification and dial test on a regular basis.)
Test the decryption code using the above public key, symmetric key, and request parameters before integration test.
Response:
{
"data":"OX88ov0nRiEgjkV580XoE5V+lhXzb+8CAEu9jRIfQzat1NK6um+t6+NxL86DLMPH",
"data_encrypt_type":"AES/CBC/PKCS7Padding"
}
Encryption process:
- Return the data encrypted using AES symmetric encryption algorithm (AES/CBC/PKCS7Padding). The cipher text here refers to the data field.
The processing logics for the Payment Status Notification API and the Receivables Query API are as follows:
# 8 Getting the User's IP
https://mp.weixin.qq.com/intp/getuserclientip
How to use: Call this API directly on the user page to get user IP. Request method: GET.
Response:
{
"base_resp": {
"ret": 0,
"err_msg": "OK"
},
"client_ip": "14.17.22.37"
}
# 9 Getting the User's Real Name
Note: The real name of the payer is required for certain business, which can be obtained using the API and process provided here (upon user authorization).
# 9.1 Service Process
Two API are used in 1/2:
The first API gets the real name authorization link, which can be opened on the user's phone for user authorization (payment password for WeChat Pay is required).
Using the token obtained through user authorization, the second API is called to get the real name of the user.
For more information, see below.
# 9.2 Getting the Authorization Link
POST https://api.weixin.qq.com/intp/realname/getauthurl?access_token=ACCESS_TOKEN
Request:
Field | Type | Required | Description |
---|---|---|---|
redirect_url | string | Yes | The URL that is redirected to after user authorization. The wx_realname_token parameter will be appended to redirect_url to call the API to get the real name of the user. |
Response:
Field | Type | Required | Description |
---|---|---|---|
errcode | int32 | Yes | 0: Successful; others values: Failed |
errmsg | string | No | Error message |
auth_url | string | No | The authorization link to be opened by the user |
expires_in | uint32 | No | Validity period (in sec) |
auth_appid | string | No | The Mini Program that is redirected to after authorization will be returned if the government unit uses a Mini Program. |
Example:
Request parameters
{
"redirect_url":"https://mp.weixin.qq.com"
}
Response
{
"errcode": 0,
"errmsg": "ok",
"expires_in":7200,
"auth_url": "https://mp.weixin.qq.com/insurance/card/getpwdconfig?auth_param=5c9f05#wechat_redirect"
}
# 9.3 Getting Real Name
POST https://api.weixin.qq.com/nontax/getrealname?access_token=ACCESS_TOKEN
Note: The data returned by this API is encrypted. For more information on the encryption/decryption methods, see Data Encryption and Decryption section. Request:
Field | Type | Required | Description |
---|---|---|---|
wx_realname_token | string | Yes | The wx_realname_token parameter appended to the URL that is redirected to after user authorization |
Response:
Field | Type | Required | Description |
---|---|---|---|
errcode | int32 | Yes | 0: Successful; others values: Failed |
errmsg | string | No | Error message |
key_encrypt_type | string | No | The asymmetric encryption algorithm of the key |
key | string | No | The dynamic key encrypted using the asymmetric encryption algorithm (with the private key) and Base64 encoded. |
data_encrypt_type | string | No | The symmetric encryption algorithm of data |
data | string | No | The symmetric encryption algorithm of data: AES/ECB/PKCS5Padding |
Example:
Request parameters:
{
"wx_realname_token": "8e1e219ec15953101515058721",
}
Response parameters:
{
"errcode": 0,
"errmsg": "ok",
"key_encrypt_type": "RSA"
"data_encrypt_type": "AES_ECB"
"data": "f06i5EaQQiBV5uXoKcfjYFkT/UKGGuU77sVlMjpC0kKea/wz9Ow1WPlD19w3g1vXFgBqHykP1s+Iy3LjfiqYNQ=="
"key": "V60tpxnZPsBfFQhEnCWVeetm07OUk3PyH4PYozNlK1WxaYqbLAnKld/sMN+pjo8Td6mhAImcOq7Sue8h0SxGzTA4o3Wf32ff2IoUbTHPO0AgkpZJy36eECkY/TklgaVqPtqE9iJ66Qt+0/GM3pdQ3f8FYMVmkvK6m53aHn1u6cX6mL0nbYBfVOpyGOh3iIuHnBCW3IeXXa41D6DbHrzmeKbBi6T56wxHLYnmMB7P20+EzSdCQZzeY1MtdT0TT1KrlkZsL2fYKcjg/ytvGiEewH/jY4zf83AVJW3KjSDJaLZGXYsPvNHopAQTP9jz/hUtIa2fDgSAi3mGdxDsJcesmQ=="
}
# 10 Error Codes for APIs in Weixin NTR Platform
Error Code | Description |
---|---|
9200002 | The order does not match with the AppID |
9200211 | Payment notice is suspended |
9200231 | Payment notice does not exist |
9200232 | Payment completed |
9200233 | Payment notice is canceled |
9200235 | Late payment is not allowed |
9200236 | Payment through this bank is not supported |
9200297 | Payment is suspended for now |
9201000 | The desc parameter is empty |
9201001 | The total amount is not equal to the sum of the amounts of all sub-items |
9201003 | The total amount is 0 |
9201004 | The payment_expire_date parameter is invalid |
9201005 | The appid parameter is invalid |
9201007 | The useruin parameter is invalid |
9201008 | The return_url parameter is invalid |
9201009 | The ip parameter is invalid |
9201010 | The order_id parameter is invalid |
9201011 | The refund_reason parameter is invalid |
9201012 | The mch_id parameter is invalid |
9201013 | The bill_date parameter is invalid |
9201014 | The bill_type parameter is invalid |
9201015 | The trade_type parameter is invalid |
9201016 | The bank_id parameter is invalid |
9201017 | The bank_account parameter is invalid |
9201018 | The payment_notice_no parameter is invalid |
9201019 | The department_code parameter is invalid |
9201020 | The payment_notice_type parameter is invalid |
9201021 | The region_code parameter is invalid |
9201022 | The department_name parameter is invalid |
9201023 | The total amount does not match that queried from the finance authorities |
9201024 | The refund_out_id parameter is invalid |
9202001 | No refund is allowed before the payment is completed |
9202002 | The AppID is not authorized to refund the order |
9202003 | The IP is restricted |
9202004 | API is called at a high frequency |
9202005 | Failed to refund the order due to Weixin account error |
9202006 | Failed to refund the order due to insufficient balance |
9202011 | Refunded |
9202012 | Failed to refund the order. The amount to be refunded plus the amount already refunded exceeds the total amount. |
9202013 | Duplicate refund_busi_id with different refund_fee |
9202016 | The signature is not verified |
9203000 | Failed to notify of the inconsistent order. Failed to notify the finance authorities. |
9203001 | Failed to notify of the test result. Failed to send the request . |
9203002 | Failed to notify of the test result. Failed to return the data. |
9203004 | Failed to notify of the test result. Failed to return the decrypted data. |
9204000 | Failed to get the real name. Invalid parameter. |
9204002 | Failed to get the real name. The parameter does not match with the AppID. |
9205000 | The information on the finance authorities is not configured |
9205001 | The information on the bank is not configured |
9205002 | The information on the government unit is not configured |
9205010 | The key is not configured |
9205201 | The statement does not exist |
9210000 | Failed to query information from the finance authorities |
9291000 | The openid parameter is invalid |
9291001 | The openid does not match with the appid |
9291002 | app_appid does not exist |
9291003 | The type of app_appid is not app |
9291004 | The appid is empty |
9291005 | The appid does not match with the access_token |
For the list of common error codes, see: Common Error Codes
# 11. FAQ
11.1 The status shown after payment is made at the intermediate page is Processing.
A: The finance authorities haven't got the payment status notification yet.
Details on the notification can be found with the Order Query API (see section 6.1.3).
11.2 Error placing order:
A: One possible cause is the openid for order placement is different from that for payment.
11.3 How long is the order returned by NTR payment valid for? A: 10 mins.
11.4 How do I add the IP whitelist when calling AccessToken? A: Go to Page Settings > Security Center > IP Whitelist on the Weixin Official Accounts Platform.
11.5 The access_token is invalid when calling the APIs in the NTR documentation. A: 1. Check whether the appid of the access_token for calling APIs match that for obtaining APIs. 2. Check whether the access_token for calling APIs has expired in the same way as the cache access_token: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
11.6 In what format will the downloaded statement data be returned? A: The data will be returned in csv format.
11.7 How do I check for duplicate payments? A: Check whether the No. of the payment notice, the code of the collection entity, and the code of the region are unique.
11.8 How long is the refund period? A: One year for now.
11.9 How do I get the openid when calling the payment API on PC? A: After the user scans the QR code provided by the business party, a page will be opened for webpage authorization. After authorization, the openid can be obtained.
11.10 The frontend API does not return the order status after successful payment in Mini Programs. Why? A: Many operations that trigger the returning to the caller's Mini Program does not trigger API wx.navigateBackMiniProgram. Therefore, this API cannot be used to pass parameters.