How to integrate WeChat payment?

David Yu
David Yu
Oct 27, 2018 · 4 min read
Image for post
Image for post
“woman wearing beanie with smartphone on ear” by Fezbot2000 on Unsplash

Purpose: To help you avoid those rabbit holes and set up WeChat payment on your WeChat mini-program.


Basic Knowledge of Node.js

Basic Knowledge of WeChat Mini-program

WeChat Mini-Program Account(Apply here:

WeChat Merchant Account

Miniprogram’s App ID

Miniprogram’s App Secret

Merchat ID

Vendor Key(or Merchant Key or Partner Key)

Important Note: Never expose these credential in public repositories. Use environment variables.

In a nutshell:

Image for post
Image for post

Overwhelmed? No worries. Let’s break it down.

Get user’s OpenID

On Miniprogram side:

success (res) {
if (res.code) {
url: '',
data: {
code: res.code
} else {
// Handle failed request to Tencent API

On Your Backend Server

router.get('/getOpenID/:code', async (req, res) => {  const { code } = req.params;  const url = `    appid=${your_miniprogram_app_id}&secret=${your_miniprogram_app_secret}&js_code=${code}&grant_type=authorization_code`;  // Use axios, request, or whatever to make a GET request to this endpoint then it should return the OpenID and Session of the user});

Bonus tip: You could use wx.setStorage() to storage the OpenID and Session of the user.

Place an order on Tencent Server

Download npm module here:

In your backend writes:

var order = {body: 'Product Title',attach: '{"Stringified":"Object"}',out_trade_no: 'kfc' + (+new Date),total_fee: 10 * 100,spbill_create_ip: req.ip,openid: req.user.openid,trade_type: 'JSAPI'};payment.getBrandWCPayRequestParams(order, function(err, payargs){res.json(payargs);});

At your miniprogram:

Use the payargs from the backend, use the wx.requestPayment as such

timeStamp: '',
nonceStr: '',
package: '',
signType: 'MD5',
paySign: '',
success (res) { },
fail (res) { }

In your backend:

  1. Generate signature

Concatenate all params into string by alphabetically order of the params keys

Add WeChat Payment Key at the end like “&key=your_key_here”

Hash the whole string with MD5 or HMAC-SHA256

Params(Bold params are required):

appid, mch_id, device_info, nonce_str, sign, sign_type, body, detail, attach, out_trade_no, fee_type, total_fee, spbill_create_ip, time_start, time_expire, goods_tag, notify_url, trade_type, product_id, limit_pay, openid


mch_id: Merchat ID / Vendor Key(or Merchant Key or Partner Key)

nonce_str: Random String

sign: Signature

sign_type: MD5 or HMAC-SHA256

body: Product title(Usually the name of the product)

detail: Product Description(Usually the quantity and specs)

attach: Extra data stringified

fee_type: Currency type

total_fee: Payment amount. Note: Fee is one hundredth of the value. Example: total_fee: 1 = 0.01 RMB

spbill_create_ip: IP of your server

goods_tag: Used for WeChat coupons

notify_url: The callback url for Tencent server to notify your server

trade_type: Should be JSAPI. You will deal will other types if you are building native apps

out_trade_no: An unique order identification. Alphanumeric. Limited to 32 characters.

Can include _-|*

2. Send it in XML strings as Form Data

3. Make a POST request to this endpoint:

4. Use the prepay_id from tencent server and generate the signature on our own server the second time

5. params to put into signature:

appId: appid,

nonceStr: nonceStr,

package: package,

signType: signType,

timeStamp: timeStamp

6. Return the params above with the signature to miniprogram

Setup Callback Url for Payment Result

  1. We get the result of the payment in notify_url in rawBody in XML format
  2. Validate if signature matches to prevent fake notification

Using the wechat-pay npm module, you can

var middleware = require('wechat-pay').middleware;app.use('<notifyUrl>', middleware(initConfig).getNotify().done(function(message, req, res, next) {var openid = message.openid;var order_id = message.out_trade_no;var attach = {};try{attach = JSON.parse(message.attach);// Do something on your own server about the successful payment}catch(e){
// If there's error, reply with, if you don't Tencent server will ping you server three more times
res.reply(new Error(e));}res.reply('success');}));

Common Pitfall

The first time that I was doing this, I kept receiving invalid signature from Tencent server. It made me question my life’s choices for two days.

Then I realized my client has given me the wrong vendor key. Because the signature is comprised of several params, you must make sure every params are correct.

Vendor key is not the App key. Reset the vendor key if you have to.

Beware of the 32 character limits of out_trade_no

Hardcode the total_fee so you don’t accidentally pay too much for testing


To test signature:

Official WeChat Miniprogram Doc

Official WeChat Payment Doc

Still confused?

If WeChat development is fresh to you, here’s a free glossary to get you up to speed. 1 Billion of WeChat’s user awaits.

Shanghai Coders

Sharing software development required in China

David Yu

Written by

David Yu

Software Freelancer based in Shanghai. More articles at Work with me:

Shanghai Coders

Sharing software development required in China

David Yu

Written by

David Yu

Software Freelancer based in Shanghai. More articles at Work with me:

Shanghai Coders

Sharing software development required in China

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store