產品說明
微信掃碼支付允許顧客使用 微信 App 的「掃一掃」功能,掃描商戶系統產生的 付款 QR Code 完成付款。
常見使用場景:
- 桌面網站付款(顯示 QR Code 讓顧客掃碼)
- POS / 收銀台螢幕顯示 QR Code
- Kiosk / 自助機付款
何時使用
當您的收款流程是「商戶顯示 QR Code → 顧客用微信掃碼 → 完成支付」時,使用本支付方式。
API 端點與方法
PayType: 800201
請求標頭
| Header | 必填 | 說明 |
|---|
X-QF-APPCODE | 是 | QFPay 分配之 AppCode |
X-QF-SIGN | 是 | 根據簽名規則產生之 API 簽名 |
請求參數
| 參數名稱 | 參數編碼 | 必填 | 類型 | 說明 |
|---|
| 交易金額 | txamt | 是 | Int(11) | 最小幣值單位,例如 100 = 1 元。建議大於 200 以降低風控拒付機率。 |
| 交易幣別 | txcurrcd | 是 | String(3) | 三位貨幣代碼,請參閱支援貨幣。 |
| 支付類型 | pay_type | 是 | String(6) | 固定為 800201。 |
| 商戶訂單號 | out_trade_no | 是 | String(128) | Merchant Order Number(商戶自定義,必須唯一)。 |
| 交易時間 | txdtm | 是 | String(20) | Transaction Time:YYYY-MM-DD hh:mm:ss |
| 訂單超時 | expired_time | 否 | String(3) | 單位分鐘,預設 30,範圍 5–120。 |
| 商品名稱 | goods_name | 否 | String(64) | 顯示用途;若包含中文請使用 UTF-8。 |
| 子商戶號 | mchid | 視情況 | String(16) | 僅代理商或特定模式需要,請按實際開通狀態使用。 |
| 裝置識別碼 | udid | 否 | String(40) | 可用於後台追蹤裝置來源(如 POS 機號)。 |
| 人民幣標記 | rmb_tag | 否 | String(1) | 若為香港微信錢包且交易幣別為 CNY,需設 Y(按實際開通狀態為準)。 |
| 客戶擴展資訊 | extend_info | 否 | Object | 實名認證資料(選用;僅限中國大陸公民)。 |
實名認證(選用)
商戶可選擇啟用 微信實名認證(Real-name Verification)。
規則說明:
- 若商戶已提供身份資訊,付款人微信錢包(如綁定銀行卡)需與提供資料一致
- 若付款人尚未綁定銀行卡,仍可完成付款
- 是否強制實名,依商戶開通設定為準
extend_info 範例
Real-name Verification Example
{
"user_creid": "430067798868676871",
"user_truename": "\\u5c0f\\u6797"
}
請求範例
WeChat QR Payment Request
{
"pay_type": "800201",
"txamt": "300",
"txcurrcd": "HKD",
"out_trade_no": "3Z6HPCS6RN54J2Y8LUQM8RBDVBA9URYE",
"txdtm": "2020-04-10 11:45:44",
"expired_time": "30",
"udid": "qiantai2"
}
回應參數
| 參數 | 說明 |
|---|
qrcode | QR Code 內容(需由商戶轉成 QR 圖像展示) |
syssn | QFPay Transaction ID |
out_trade_no | Merchant Order Number |
respcd | Return Code(0000 = 成功建立交易) |
resperr | 錯誤描述(若有) |
respmsg | 附加訊息(除錯用途) |
sysdtm | System Time |
txdtm | Transaction Time |
txamt | 交易金額 |
txcurrcd | 交易貨幣 |
chnlsn | 通道流水號(若有) |
respcd = 0000 僅代表交易建立成功。
商戶需展示 qrcode 給顧客掃碼,付款完成後的最終狀態請以 Webhook 或查詢 API 確認。
回應範例
WeChat QR Payment Response
{
"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": ""
}
範例程式碼(多語言)
以下範例邏輯一致,僅語言不同。
請依您的實際開發語言選擇對應範例。
# coding=utf8
import hashlib
import datetime
import requests
environment = "https://test-openapi-hk.qfapi.com"
app_code = "******"
client_key = "******"
def make_req_sign(data, key):
keys = sorted(data.keys())
p = []
for k in keys:
p.append(f"{k}={data[k]}")
unsign_str = ("&".join(p) + key).encode("utf-8")
return hashlib.md5(unsign_str).hexdigest().upper()
current_time = datetime.datetime.now().replace(microsecond=0).strftime("%Y-%m-%d %H:%M:%S")
data = {
"txamt": "300",
"txcurrcd": "HKD",
"pay_type": "800201",
"out_trade_no": "ORDER123456789",
"txdtm": current_time
}
r = requests.post(
environment + "/trade/v1/payment",
data=data,
headers={"X-QF-APPCODE": app_code, "X-QF-SIGN": make_req_sign(data, client_key)}
)
print(r.json())
const crypto = require("crypto");
const request = require("request");
const environment = "https://test-openapi-hk.qfapi.com";
const app_code = "******";
const client_key = "******";
const payload = {
txamt: "300",
txcurrcd: "HKD",
pay_type: "800201",
out_trade_no: "ORDER123456789",
txdtm: "2026-03-03 18:00:00"
};
const ordered = {};
Object.keys(payload).sort().forEach((k) => (ordered[k] = payload[k]));
const str = Object.keys(ordered).map((k) => `${k}=${ordered[k]}`).join("&") + client_key;
const sign = crypto.createHash("md5").update(str).digest("hex").toUpperCase();
request({
uri: environment + "/trade/v1/payment",
headers: {
"X-QF-APPCODE": app_code,
"X-QF-SIGN": sign
},
method: "POST",
form: payload
}, function (error, response, body) {
console.log(body);
});
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class TestMain {
public static void main(String[] args) {
String appcode = "******";
String key = "******";
String pay_type = "800201";
String out_trade_no = "ORDER123456789";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String txdtm = df.format(new Date());
Map<String, String> params = new HashMap<>();
params.put("pay_type", pay_type);
params.put("out_trade_no", out_trade_no);
params.put("txcurrcd", "HKD");
params.put("txamt", "300");
params.put("txdtm", txdtm);
// Generate sign and send request per your project utilities
}
}
<?php
function signParams($fields, $key) {
ksort($fields);
$pairs = [];
foreach ($fields as $k => $v) {
$pairs[] = $k . "=" . $v;
}
return strtoupper(md5(join("&", $pairs) . $key));
}
$url = "https://test-openapi-hk.qfapi.com/trade/v1/payment";
$app_code = "******";
$app_key = "******";
$fields = [
"pay_type" => "800201",
"out_trade_no" => "ORDER123456789",
"txcurrcd" => "HKD",
"txamt" => "300",
"txdtm" => date("Y-m-d H:i:s")
];
$sign = signParams($fields, $app_key);
$header = [
"X-QF-APPCODE: " . $app_code,
"X-QF-SIGN: " . $sign
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
$output = curl_exec($ch);
curl_close($ch);
echo $output;
?>
整合注意事項與最佳實務
商戶需將回傳的 qrcode 內容轉換成 QR Code 圖像(例如 Canvas / QR Library),並展示給顧客掃描。
當回傳碼為 1143 或 1145 時,代表交易狀態未確定。
商戶必須主動透過交易查詢 API 確認最終狀態,並在必要時進行補單處理。
建議保存以下欄位以利對帳與補單:
syssn(QFPay Transaction ID)
out_trade_no(Merchant Order Number)
- 適合「顯示 QR Code → 顧客掃碼付款」的收款場景
- 商戶需自行生成並展示 QR Code 圖像
- 可選擇啟用實名認證(僅限中國大陸)
- 建議實作 Webhook / 查詢 API 以確保交易狀態一致