跳轉到主要內容

產品說明

微信掃碼支付允許顧客使用 微信 App 的「掃一掃」功能,掃描商戶系統產生的 付款 QR Code 完成付款。 常見使用場景:
  • 桌面網站付款(顯示 QR Code 讓顧客掃碼)
  • POS / 收銀台螢幕顯示 QR Code
  • Kiosk / 自助機付款

何時使用

當您的收款流程是「商戶顯示 QR Code → 顧客用微信掃碼 → 完成支付」時,使用本支付方式。

API 端點與方法

建立微信掃碼支付交易
POST /trade/v1/payment
PayType: 800201

請求標頭

Header必填說明
X-QF-APPCODEQFPay 分配之 AppCode
X-QF-SIGN根據簽名規則產生之 API 簽名

請求參數

參數名稱參數編碼必填類型說明
交易金額txamtInt(11)最小幣值單位,例如 100 = 1 元。建議大於 200 以降低風控拒付機率。
交易幣別txcurrcdString(3)三位貨幣代碼,請參閱支援貨幣。
支付類型pay_typeString(6)固定為 800201
商戶訂單號out_trade_noString(128)Merchant Order Number(商戶自定義,必須唯一)。
交易時間txdtmString(20)Transaction Time:YYYY-MM-DD hh:mm:ss
訂單超時expired_timeString(3)單位分鐘,預設 30,範圍 5–120。
商品名稱goods_nameString(64)顯示用途;若包含中文請使用 UTF-8。
子商戶號mchid視情況String(16)僅代理商或特定模式需要,請按實際開通狀態使用。
裝置識別碼udidString(40)可用於後台追蹤裝置來源(如 POS 機號)。
人民幣標記rmb_tagString(1)若為香港微信錢包且交易幣別為 CNY,需設 Y(按實際開通狀態為準)。
客戶擴展資訊extend_infoObject實名認證資料(選用;僅限中國大陸公民)。

實名認證(選用)

商戶可選擇啟用 微信實名認證(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"
}

回應參數

參數說明
qrcodeQR Code 內容(需由商戶轉成 QR 圖像展示)
syssnQFPay Transaction ID
out_trade_noMerchant Order Number
respcdReturn Code(0000 = 成功建立交易)
resperr錯誤描述(若有)
respmsg附加訊息(除錯用途)
sysdtmSystem Time
txdtmTransaction 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),並展示給顧客掃描。
當回傳碼為 11431145 時,代表交易狀態未確定。
商戶必須主動透過交易查詢 API 確認最終狀態,並在必要時進行補單處理。
建議保存以下欄位以利對帳與補單:
  • syssn(QFPay Transaction ID)
  • out_trade_no(Merchant Order Number)

小結

  • 適合「顯示 QR Code → 顧客掃碼付款」的收款場景
  • 商戶需自行生成並展示 QR Code 圖像
  • 可選擇啟用實名認證(僅限中國大陸)
  • 建議實作 Webhook / 查詢 API 以確保交易狀態一致