Integrate WeChat Pay Skill
Scenario
Enable AI to handle the complete WeChat Pay workflow within a Mini Program: placing orders, querying orders, closing orders, refunds, querying refunds, merchant transfers, and querying transfers. Users simply say "Pay 25 yuan for coffee" or "Check the order status", and AI will call the corresponding interface to complete the operation and display result cards.
This guide uses the pre-built payment-skill template for quick WeChat Pay integration: install template → configure merchant credentials → deploy, with payment logic processed through HTTP cloud functions.
Prerequisites
- Completed Building an AI Mini Program from Scratch, project runs normally in DevTools
- Mini Program has enabled AI Development Mode (WeChat Official Platform → Basic Features → AI Capabilities → Access Mode: "Development Mode")
- WeChat DevTools Nightly version installed
- Node.js ≥ 18
-
npx mp-skills --versionoutputs version number correctly - WeChat Pay merchant account activated (Merchant Platform)
- CloudBase environment activated (WeChat Official Platform → Development → CloudBase)
- Merchant credentials prepared (Merchant ID, certificate serial number, APIv3 key, merchant private key, WeChat Pay public key)
Implementation Steps
Step 1: Install payment-skill Template
# Run in the project root directory
npx mp-skills add TencentCloudBase/awesome-miniprogram-skills --skill payment-skill
Expected output:
Fetching from TencentCloudBase/awesome-miniprogram-skills...
* Installing Skill: payment-skill
* skills/payment-skill/
* skills/_shared/mp-skills-shared/
* Version recorded
* See skills/payment-skill/README.md for feature details
[OK] Installation complete!
Setup scripts pending, recommend running:
mp-skills setup
Installed file structure:
miniprogram/skills/payment-skill/
├── config.js # ⚡ CONFIGURE: cloud function name + env ID
├── cloudbaserc.json # ⚡ CONFIGURE: deployment credentials + env variables
├── SKILL.md # ✅ READY: Skill description (AI engine reads this to determine triggers)
├── mcp.json # ✅ READY: Atomic API declaration (7 payment APIs with parameters and returns)
├── index.js # ✅ READY: Entry (registers all atomic APIs)
├── apis/ # ✅ READY: Atomic API implementations
│ ├── createOrder.js # Create order + invoke payment
│ ├── queryOrder.js # Query order
│ ├── closeOrder.js # Close order
│ ├── refundOrder.js # Apply for refund
│ ├── queryRefund.js # Query refund
│ ├── transferMoney.js # Merchant transfer
│ └── queryTransfer.js # Query transfer
├── components/ # ✅ READY: UI components
│ ├── payment-card/ # Payment result card
│ ├── order-status-card/ # Order status card
│ ├── refund-card/ # Refund result card
│ └── transfer-card/ # Transfer result card
├── cloudfunctions/ # ✅ READY: Backend cloud functions
│ └── pay-common/ # HTTP cloud function (WeChat Pay V3 service)
└── utils/ # ✅ READY: Frontend utilities
├── util.js # Cloud function call wrapper
├── id.js # Order number generation
└── storage.js # Local storage
💡 The template includes complete API implementations, UI components, and cloud function code. You only need to complete the credential configuration below to get started.
Step 2: Configure Backend Credentials
2.1 Prepare Merchant Credentials
Obtain the following from WeChat Pay Merchant Platform:
| Credential | Location | Format |
|---|---|---|
Merchant ID (merchantId) | Merchant Platform homepage | 10-digit number |
Certificate Serial Number (merchantSerialNumber) | Account Center → API Security → API Certificate | 40-char hex |
APIv3 Key (apiV3Key) | Account Center → API Security → Set APIv3 Key | 32-byte string |
Merchant Private Key (privateKey) | apiclient_key.pem downloaded during certificate application | PEM format |
WeChat Pay Public Key (wxPayPublicKey) | Account Center → API Security → WeChat Pay Public Key | PEM format |
Public Key ID (wxPayPublicKeyId) | Same as above | Paired with public key |
⚠️ WeChat Pay Public Key ≠ Merchant API Public Key. Make sure to use the "WeChat Pay Public Key", not the merchant public key generated during certificate application.
2.2 Complete cloudbaserc.json
Open miniprogram/skills/payment-skill/cloudbaserc.json and replace all placeholders with your actual values:
{
"version": "2.0",
"envId": "your-cloudbase-env-id",
"functions": [
{
"name": "pay-common",
"type": "http",
"timeout": 30,
"runtime": "Nodejs18.15",
"handler": "index.main",
"memorySize": 256,
"installDependency": true,
"dir": "cloudfunctions/pay-common",
"envVariables": {
"signMode": "sdk",
"appId": "your-mini-program-appid",
"merchantId": "your-merchant-id",
"merchantSerialNumber": "your-certificate-serial-number",
"apiV3Key": "your-apiv3-key",
"privateKey": "-----BEGIN PRIVATE KEY-----\\nMIIEvgIBA...\\n-----END PRIVATE KEY-----",
"wxPayPublicKey": "-----BEGIN PUBLIC KEY-----\\nMIIBIjAN...\\n-----END PUBLIC KEY-----",
"wxPayPublicKeyId": "your-wechat-pay-public-key-id",
"notifyURLPayURL": "https://<envId>.service.tcloudbase.com/pay-common/wx-pay/unifiedOrderTrigger",
"notifyURLRefundsURL": "https://<envId>.service.tcloudbase.com/pay-common/wx-pay/refundTrigger",
"transferNotifyUrl": "https://<envId>.service.tcloudbase.com/pay-common/wx-pay/transferTrigger"
}
}
],
"database": {
"collections": [
{ "name": "payment_records", "description": "Payment records", "aclTag": "PRIVATE" },
{ "name": "refund_records", "description": "Refund records", "aclTag": "PRIVATE" },
{ "name": "transfer_records", "description": "Transfer records", "aclTag": "PRIVATE" }
]
}
}
Key configuration notes:
| Field | Description |
|---|---|
envId | Your CloudBase environment ID |
signMode | sdk (self-signing, recommended) or gateway (Integration Center proxy signing) |
privateKey | Replace PEM file line breaks with \n (literal two characters), write as single line |
notifyURLPayURL | Payment callback URL, must be the actual full address after deployment |
notifyURLRefundsURL | Refund callback URL |
transferNotifyUrl | Transfer callback URL |
Callback URL format:
https://<envId>.service.tcloudbase.com/<functionName>/wx-pay/<route>Example:
https://test-wxpay-5gy4ugzreef15cfe.service.tcloudbase.com/pay-common/wx-pay/unifiedOrderTrigger
2.3 Complete config.js
Open miniprogram/skills/payment-skill/config.js and fill in values consistent with cloudbaserc.json:
module.exports = {
// Cloud function name (must match functions[].name in cloudbaserc.json)
functionName: 'pay-common',
// CloudBase environment ID (must match envId in cloudbaserc.json)
// Leave empty for CloudBase SDK to auto-detect current environment
envId: ''
}
⚠️ Mini Programs cannot read JSON files at runtime, so
config.jsmust be manually kept in sync withcloudbaserc.json. Update this file whenever you change the function name or env ID incloudbaserc.json.
Step 3: One-Click Backend Deployment
npx mp-skills setup
mp-skills setup automatically completes:
| Step | Description |
|---|---|
| Merge config | Skill-level cloudbaserc.json → project-level |
| Install deps | npm packages in cloudfunctions/pay-common/ |
| Deploy function | Deploy as HTTP cloud function |
| Create database | Auto-create payment_records, refund_records, transfer_records collections with indexes |
After deployment, set the following callback paths to no-auth in CloudBase Console → Cloud Functions → pay-common → HTTP Trigger:
/wx-pay/unifiedOrderTrigger(payment callback)/wx-pay/refundTrigger(refund callback)/wx-pay/transferTrigger(transfer callback)
WeChat Pay servers call callback paths directly and cannot carry auth tokens, so these must be no-auth. Security is guaranteed by internal signature verification.
Step 4: Validate
npx mp-skills validate
Expected output:
[OK] Project configuration check passed
[OK] API definitions match implementations
[OK] Atomic components are complete
If validation fails, check these common issues:
- API names in
mcp.jsondon't match registered names inindex.js componentPathpoints to non-existent component filescloudbaserc.jsoncallback URLs still contain template variables
Step 5: Verify in DevTools
# macOS
/Applications/wechatwebdevtools.app/Contents/MacOS/cli open --project /your/path/to/my-ai-app
# Windows
"C:\Program Files (x86)\Tencent\微信web开发者工具\cli.bat" open --project "D:\...\my-ai-app"
In DevTools:
- Switch base library version to 3.16.1 or above
- Switch compile mode to "Mini Program AI Compile"
payment-skillshould appear in the SKILL list on the left- Select it, 7 atomic APIs should display on the right
- Test
createOrder: enter{"description": "Coffee", "totalFee": 100}and execute - Check the payment result card rendering
Verification Checklist
-
npx mp-skills validateall passed -
npx mp-skills setupdeployment successful, cloud function status normal - Callback routes set to no-auth
-
createOrdercan invoke WeChat Pay in DevTools (or returns mock in preview mode) -
payment-cardcomponent renders correctly after successful payment -
queryOrder/closeOrder/refundOrder/queryRefund/transferMoney/queryTransferAPIs work correctly - Result cards (order-status-card, refund-card, transfer-card) display correctly
-
mcp.jsondeclarations matchindex.jsregistered names -
config.jsandcloudbaserc.jsonenvId/functionName are consistent
Payment Architecture
Key design decisions:
| Decision | Choice | Rationale |
|---|---|---|
| Process payments via cloud function? | Yes, via HTTP cloud function | Payment involves key signing, must be handled on backend. Frontend calls via wx.cloud.callHTTPFunction, platform auto-authenticates |
| How to get openid | Backend auto-gets from header | wx.cloud.callHTTPFunction auto-injects x-wx-openid, no frontend passing needed, prevents spoofing |
| Amount source | Demo passes from frontend | Production must get from backend database, never trust frontend amounts |
| Callback verification | signMode: sdk self-verify | No external service dependency, cloud function independently verifies + decrypts |
| Result display | 4 custom card components | Payment scenarios need rich status display (amount, status icons, action buttons) |
Business Constraints (Cross-API Rules)
1. Execution Order
refundOrdermust only be called afterqueryOrderconfirms order status is SUCCESScloseOrdermust only be called afterqueryOrderconfirms order status is NOTPAY- Never call payment APIs concurrently; wait for previous transaction to complete
2. Data Sources
outTradeNomust come fromcreateOrder's original return value, never fabricateoutRefundNomust come fromrefundOrder's original return value, never fabricateoutBillNomust come fromtransferMoney's original return value, never fabricate
3. Amount Handling
- All amounts are in cents/fen (e.g., 1 yuan = 100 cents)
- Refund amount cannot exceed order total
- Transfer amount range: 0.3 yuan (30 cents) ~ 2000 yuan (200000 cents)
4. Security Constraints
- Backend is called via
wx.cloud.callHTTPFunction, platform auto-authenticates payer.openidis auto-obtained by backend, no need to pass from frontend- Never hardcode any keys or certificates on the frontend
FAQ
Error "Current environment does not support wx.cloud.callHTTPFunction"?
- Confirm base library version >= 3.15.1
wx.cloud.init()has been called inapp.js- Use real device debugging or trial version (not simulator)
Payment always returns mock data?
Check if mp_skills_preview_mode is true, and whether the backend cloud function has been deployed. Toggle method:
// Enable preview mode
wx.setStorageSync('mp_skills_preview_mode', true)
// Disable preview mode (use real payment)
wx.setStorageSync('mp_skills_preview_mode', false)
Refund error "Order status does not allow refund"?
Only SUCCESS (paid) orders can be refunded:
NOTPAY→ UsecloseOrderto closeSUCCESS→ UserefundOrderto refundCLOSED→ Already closed, no operation possible
What are the merchant transfer limits?
- Per transaction: 0.3 yuan ~ 2000 yuan
- Must enable "Merchant Transfer to Wallet" feature on Merchant Platform
- User needs to confirm receipt in WeChat
How to use in production?
- Disable preview mode
- Get amounts from backend (never trust frontend amounts)
- Configure callback URLs (must be actual full addresses after deployment)
- Ensure no keys are exposed on frontend
- Callback handling must implement idempotent logic
What's the difference between config.js and cloudbaserc.json?
| File | Purpose | Runtime |
|---|---|---|
cloudbaserc.json | For CloudBase CLI deployment, contains full credentials | Deployment only |
config.js | Mini Program runtime configuration | Mini Program runtime (require) |
The functionName and envId in both must be consistent.