WeChat Pay APIv3 Integration in Practice: Signing, Callback Verification, and Idempotency
WeChat Pay APIv3 was a ground-up redesign. Signing moved from MD5 or HMAC to SHA256-RSA2048, callback payloads are now encrypted end to end, and the platform side moved to a certificate model. Teams that migrate by adapting their v2 code typically stall on signature failures or decryption errors and spend hours finding nothing, because the error messages say almost nothing.
If you have not yet completed a basic payment, start with the onboarding and account sections of the guide to adding Alipay and WeChat Pay to a website. This article begins at the point where the account is live and code is about to be written. For product positioning and capability boundaries, see WeChat Pay.
1. How APIv3 Differs From Legacy v2
Putting the differences up front makes every later step map to something concrete:
| Dimension | Legacy v2 | APIv3 |
|---|---|---|
| Request signing | MD5 or HMAC-SHA256 over a concatenated string | SHA256-RSA2048 using the merchant private key |
| Request format | XML | JSON |
| Callback payload | Plaintext XML | Fully encrypted, decrypted with the APIv3 key |
| Identity verification | A single API key | Platform certificate plus merchant private key |
| Certificate rotation | Manual key swap | Platform certificates expire and must be refreshed |
That table explains most migration failures: v2 required remembering one key, while v3 requires placing three things correctly, and using any one of them wrongly surfaces as signature error or decryption failure, both of which carry almost no diagnostic information.
2. Preparation: The Three Key Materials
2.1 Account and product activation
After the merchant account is opened on the WeChat Pay merchant platform, each payment product must be applied for separately: JSAPI, Native, H5, APP and so on. Note that product permissions are granted per scenario, so calling a JSAPI endpoint with only Native activated returns a no-permission error. The APPID must also be bound. Merchant IDs and APPIDs have a many-to-many relationship, and misconfiguration yields an appid and mchid mismatch error.
2.2 What each material governs
- Merchant API private key (apiclient_key.pem): generated locally, held locally, never uploaded to a third party. Used to sign every request and to decrypt merchant-side content in callbacks.
- Merchant certificate serial number: issued alongside the merchant certificate and placed in the
Authorizationheader so WeChat Pay knows which public key verifies your signature. - APIv3 key: a 32-byte symmetric key you set yourself in the merchant platform. Used for AES-256-GCM decryption of callback payloads and for encrypting sensitive fields.
- Platform certificate: the WeChat Pay public key certificate used to prove a callback genuinely came from WeChat Pay. It has an expiry date and must be refreshed on a schedule, never downloaded once and hardcoded.
The most common production incident is confusing the APIv3 key with the merchant private key. The former is symmetric and used for decryption; the latter is asymmetric and used for signing. They are not interchangeable.
3. Request Signing: SHA256-RSA2048
The construction rule is fixed: assemble the HTTP method, request path including query string, timestamp, random string, and request body into a five-line string, sign it with SHA256-RSA using the merchant private key, and place the result into the Authorization header in the prescribed format.
Three details that break in practice:
- The request path must include the query string and match the URL actually sent exactly, including parameter order.
- The request body must be the exact bytes sent when signing. Serializing again and mutating a field invalidates the signature.
- The timestamp must stay close to server time. Clock drift causes signatures to expire.
Extract the signing logic into its own module with unit tests using fixed inputs and expected outputs. Once this part is wrong, every endpoint fails, and the only feedback is a signature error.
4. Callback Verification and Resource Decryption
Payment result notification is where the chain most often goes wrong. The standard order is:
- Collect the
Wechatpay-Timestamp,Wechatpay-Nonce,Wechatpay-SignatureandWechatpay-Serialheaders. - Verify the signature with the matching platform certificate public key to confirm the payload was not altered.
- Decrypt the
resourcefield with AES-256-GCM using the APIv3 key to obtain plaintext business data. - Validate that the decrypted
mchid,appid, amount and order number match local records. - Process the business logic, then return a success response in the required format.
Failures cluster in two places. First, the platform certificate matching Wechatpay-Serial has not been refreshed, so verification fails outright. Second, treating a passed signature check as "already processed" without cross-checking amount and order number, which leaves room for forged callbacks.
5. Choosing Among the Four Payment Products
| Product | Scenario | Key constraint |
|---|---|---|
| JSAPI | In-app H5 and official accounts | Requires the user's openid and a configured payment authorization directory |
| Native | Desktop website QR code | Returns a code link you render yourself |
| H5 | Mobile browser outside WeChat | Domain must be registered; some scenarios restricted |
| APP | Your own mobile app | App signature and package name must be bound |
The rule is simple: JSAPI inside WeChat, Native at the desktop, H5 in an external mobile browser, APP in a native app. Mismatches cause failures or broken experiences, such as H5 payment being blocked inside WeChat.
6. Order State Machine and Idempotency
Correctness comes from the state machine. Allow only these transitions: pending, processing, paid, closed, refunded. And only the server may drive state changes. The front-end redirect is for display only and is never proof of payment.
Idempotency must sit in three places: callback handling, since the same notification can be delivered repeatedly, deduplicated by order number plus notification ID; active querying, since a gateway timeout requires a status query rather than an assumption of failure; and retry tolerance, because the WeChat Pay side resends notifications and your endpoint must withstand duplicate calls.
A practical approach is a unique index on the callback handler: build a unique constraint on merchant order number plus event type in the transaction log table, and treat a conflict as already processed by returning success immediately. This is more reliable than read-then-write and avoids duplicate posting under concurrency.
7. Integration and Launch Checklist
- The merchant private key, APIv3 key and platform certificate are stored separately with least privilege.
- A scheduled job refreshes platform certificates, with alerting on failure.
- The callback endpoint is publicly reachable over HTTPS with no authentication intercepting it, so do not add session checks.
- Callback handling has a unique index or idempotency key.
- Active querying is implemented and covers timeout scenarios.
- Amount validation compares the same unit on both sides, avoiding a factor-of-100 error.
- Logs are masked and never print full keys or user-sensitive data.
- A sandbox or small live transaction has exercised the full chain including refunds.
For testing methodology, see payment gateway sandbox testing. For the general sequence, see payment transaction flow basics.
8. Five Common Traps
First, amount units: WeChat Pay uses cents while interfaces display yuan, and a missing multiply by 100 is the most frequent source of reconciliation differences. Second, duplicate callback handling, where missing idempotency ships goods twice. Third, stale certificates, after which every callback fails verification with no immediate alert. Fourth, treating the front-end redirect as success, so a user who closes the page never resolves the order; rely on server notification or active query. Fifth, an unconfigured authorization directory, where the JSAPI payment directory does not match the actual page path and payment fails on invocation.
For reconciliation and discrepancy handling, see the reconciliation and bill download handbook. For refunds and settlement, see the refund and settlement operations handbook. For risk strategy, see payment fraud prevention strategies. More options are collected under the Payment category.
Source: 16IDC original. Product capabilities, pricing and eligibility requirements follow pay.weixin.qq.com and related official documentation and contract terms.