Skip to main content

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 --version outputs 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:

CredentialLocationFormat
Merchant ID (merchantId)Merchant Platform homepage10-digit number
Certificate Serial Number (merchantSerialNumber)Account Center → API Security → API Certificate40-char hex
APIv3 Key (apiV3Key)Account Center → API Security → Set APIv3 Key32-byte string
Merchant Private Key (privateKey)apiclient_key.pem downloaded during certificate applicationPEM format
WeChat Pay Public Key (wxPayPublicKey)Account Center → API Security → WeChat Pay Public KeyPEM format
Public Key ID (wxPayPublicKeyId)Same as abovePaired 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:

FieldDescription
envIdYour CloudBase environment ID
signModesdk (self-signing, recommended) or gateway (Integration Center proxy signing)
privateKeyReplace PEM file line breaks with \n (literal two characters), write as single line
notifyURLPayURLPayment callback URL, must be the actual full address after deployment
notifyURLRefundsURLRefund callback URL
transferNotifyUrlTransfer 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.js must be manually kept in sync with cloudbaserc.json. Update this file whenever you change the function name or env ID in cloudbaserc.json.

Step 3: One-Click Backend Deployment

npx mp-skills setup

mp-skills setup automatically completes:

StepDescription
Merge configSkill-level cloudbaserc.json → project-level
Install depsnpm packages in cloudfunctions/pay-common/
Deploy functionDeploy as HTTP cloud function
Create databaseAuto-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.json don't match registered names in index.js
  • componentPath points to non-existent component files
  • cloudbaserc.json callback 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:

  1. Switch base library version to 3.16.1 or above
  2. Switch compile mode to "Mini Program AI Compile"
  3. payment-skill should appear in the SKILL list on the left
  4. Select it, 7 atomic APIs should display on the right
  5. Test createOrder: enter {"description": "Coffee", "totalFee": 100} and execute
  6. Check the payment result card rendering

Verification Checklist

  • npx mp-skills validate all passed
  • npx mp-skills setup deployment successful, cloud function status normal
  • Callback routes set to no-auth
  • createOrder can invoke WeChat Pay in DevTools (or returns mock in preview mode)
  • payment-card component renders correctly after successful payment
  • queryOrder / closeOrder / refundOrder / queryRefund / transferMoney / queryTransfer APIs work correctly
  • Result cards (order-status-card, refund-card, transfer-card) display correctly
  • mcp.json declarations match index.js registered names
  • config.js and cloudbaserc.json envId/functionName are consistent

Payment Architecture

Key design decisions:

DecisionChoiceRationale
Process payments via cloud function?Yes, via HTTP cloud functionPayment involves key signing, must be handled on backend. Frontend calls via wx.cloud.callHTTPFunction, platform auto-authenticates
How to get openidBackend auto-gets from headerwx.cloud.callHTTPFunction auto-injects x-wx-openid, no frontend passing needed, prevents spoofing
Amount sourceDemo passes from frontendProduction must get from backend database, never trust frontend amounts
Callback verificationsignMode: sdk self-verifyNo external service dependency, cloud function independently verifies + decrypts
Result display4 custom card componentsPayment scenarios need rich status display (amount, status icons, action buttons)

Business Constraints (Cross-API Rules)

1. Execution Order

  • refundOrder must only be called after queryOrder confirms order status is SUCCESS
  • closeOrder must only be called after queryOrder confirms order status is NOTPAY
  • Never call payment APIs concurrently; wait for previous transaction to complete

2. Data Sources

  • outTradeNo must come from createOrder's original return value, never fabricate
  • outRefundNo must come from refundOrder's original return value, never fabricate
  • outBillNo must come from transferMoney'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.openid is 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"?

  1. Confirm base library version >= 3.15.1
  2. wx.cloud.init() has been called in app.js
  3. 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 → Use closeOrder to close
  • SUCCESS → Use refundOrder to refund
  • CLOSED → 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?

  1. Disable preview mode
  2. Get amounts from backend (never trust frontend amounts)
  3. Configure callback URLs (must be actual full addresses after deployment)
  4. Ensure no keys are exposed on frontend
  5. Callback handling must implement idempotent logic

What's the difference between config.js and cloudbaserc.json?

FilePurposeRuntime
cloudbaserc.jsonFor CloudBase CLI deployment, contains full credentialsDeployment only
config.jsMini Program runtime configurationMini Program runtime (require)

The functionName and envId in both must be consistent.

References