Skip to main content

WeChat QR Code Payment

WeChat QR Code Payment Flow

Overview

WeChat QR Code payment allows customers to use WeChat's "Scan" feature to scan a QR code generated by the merchant's website or system and complete the payment process.

In this payment mode:

  • The merchant system embeds order details into a unique QR Code
  • The customer scans the code using WeChat and goes through a security check
  • Once verified, the payment is completed

Common scenarios include:

  • Desktop web checkout
  • POS screen QR display
  • Kiosk/self-service payment terminals

Real-name Verification (Optional)

Merchants may choose to enable WeChat Real-name Verification.

note

Currently, real-name verification is only available for mainland Chinese citizens, and requires:

  • Payer's full legal name
  • Chinese National ID number

Verification rules:

  • If merchant has provided identity data, the payer’s linked wallet/bank info must match
  • Payments are still allowed even if the customer hasn't linked a bank card
  • Whether identity verification is enforced depends on merchant settings

Sample Code (Multi-language)

The following examples demonstrate how to call the WeChat QR Code payment API using different languages:

  • Python
  • Java
  • JavaScript (Node.js)
  • PHP
info

All examples follow the same logic; choose based on your development environment.

#coding=utf8
import urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse, hashlib
import requests
import datetime
import string

# Enter Client Credentials
environment = 'https://test-openapi-hk.qfapi.com'
app_code = 'D5589D2A1F2E42A9A60C37*********'
client_key = '0E32A59A8B454940A2FF39**********'


# Create parameter values for data payload
current_time = datetime.datetime.now().replace(microsecond=0)

print(current_time)

# Create signature
def make_req_sign(data, key):
keys = list(data.keys())
keys.sort()
p = []
for k in keys:
v = data[k]
p.append('%s=%s'%(k,v))
unsign_str = ('&'.join(p) + key).encode("utf-8")
s = hashlib.md5(unsign_str).hexdigest()
return s.upper()


# Body payload
txamt = '10' #In USD,EUR,etc. Cent. Suggest value > 200 to avoid risk control.
txcurrcd = 'HKD'
pay_type = '800201'
auth_code='283854702356157409' #CPM only
out_trade_no = '01234567890123'
txdtm = current_time
goods_name = 'test1'
mchid = 'ZaMVg*****'
key = client_key


#data ={'txamt': txamt, 'txcurrcd': txcurrcd, 'pay_type': pay_type, 'out_trade_no': out_trade_no, 'txdtm': txdtm, 'goods_name': goods_name, 'udid': udid, 'mchid': mchid}
data ={'txamt': txamt, 'txcurrcd': txcurrcd, 'pay_type': pay_type, 'out_trade_no': out_trade_no, 'txdtm': txdtm, 'mchid': mchid}

r = requests.post(environment+"/trade/v1/payment",data=data,headers={'X-QF-APPCODE':app_code,'X-QF-SIGN':make_req_sign(data, key)})

print(r.json())

API Response

After a successful request, the API will return a QRCode URL for the merchant to convert into a QR image.

info

The returned qrcode field should be rendered into an actual QR Code for customers to scan.

{
"sysdtm": "2020-04-10 11:45:44",
"paydtm": "2020-04-10 11:45:44",
"txcurrcd": "HKD",
"respmsg": "OK",
"qrcode": "weixin://wxpay/bizpayurl?pr=4PsXP5N",
"pay_type": "800201",
"cardcd": "",
"udid": "qiantai2",
"txdtm": "2020-04-10 11:45:44",
"txamt": "300",
"resperr": "success",
"out_trade_no": "3Z6HPCS6RN54J2Y8LUQM8RBDVBA9URYE",
"syssn": "20200410000300020086358791",
"respcd": "0000",
"chnlsn": ""
}

HTTP Request

  • Method: POST
  • Endpoint: /trade/v1/payment
  • PayType: 800201 (WeChat QR Payment)

Request Parameters

Field NameParameterSub-ParamRequiredTypeDescription
Transaction AmounttxamtYesInt(11)Amount in minor unit (e.g. 100 = $1). Must be integer. Suggest value > 200 to avoid risk flags.
CurrencytxcurrcdYesString(3)See Supported Currencies.
Payment Typepay_typeYesString(6)Always use 800201 for WeChat QR Code Payment. See Payment Types.
Merchant Order IDout_trade_noYesString(128)Merchant-defined order ID. Must be unique per transaction.
Transaction TimetxdtmYesString(20)Format: YYYY-MM-DD hh:mm:ss
Expiry Timeexpired_timeNoString(3)Time (in minutes) until QR expires. Default is 30. Range: 5–120 mins.
Product Namegoods_nameNoString(64)Name of product. Avoid special characters. UTF-8 encoding recommended for Chinese.
Sub-merchant IDmchidNoString(16)Required only for agent mode or multi-MID use. Check with support.
Device IDudidNoString(40)Optional device identifier shown in backend.
RMB Indicatorrmb_tagNoString(1)Set to Y if using RMB wallet with currency CNY.
Extended Infoextend_infouser_creid, user_truenameNoObjectReal-name details for mainland Chinese citizens. Example: {"user_creid":"430067798868676871","user_truename":"\u5c0f\u6797"}

Response Fields

Field NameParameterTypeDescription
Payment Typepay_typeString(6)Should be 800201 for WeChat QR Code Payment.
System TimestampsysdtmString(20)Time the transaction was processed by QFPay.
Transaction TimetxdtmString(20)Original timestamp from merchant request.
Status MessageresperrString(128)Success/failure message.
Paid AmounttxamtInt(11)Final amount paid.
Additional MessagerespmsgString(128)Any extra return messages.
Merchant Order IDout_trade_noString(128)Echoed back from request.
QFPay Order IDsyssnString(40)Unique transaction ID from QFPay.
Response CoderespcdString(4)0000 means success. See Status Codes.
Channel Order IDchnlsnStringThird-party payment platform order ID (e.g. WeChat transaction number).
warning

If respcd = 1143 or 1145, the transaction is pending. Merchants must call transaction inquiry to confirm final status.


Summary

  • Best used for displaying QR codes for customers to scan
  • QR must be generated from returned qrcode field
  • Real-name verification is optional but available
  • Always handle response codes carefully and implement order query fallback