跳轉到主要內容
客戶可在商戶網站上使用支付寶完成交易。使用者掃描顯示的二維碼確認金額並付款。付款完成後,系統可透過 return_url 參數將使用者導回商戶指定頁面。支付寶以人民幣即時從用戶錢包扣除金額,QFPay 則以港幣或本地貨幣結算給商戶。

HTTP 請求

  • 方法POST
  • 端點../trade/v1/payment

PayType 對應類型

編碼描述
801101支付寶線上掃碼支付(支付寶直接結算)
801501支付寶線上掃碼支付(QFPay 結算)

請求參數

參數名稱參數代碼必填資料型別描述
訂單金額txamtInt(11)以最小單位(如 100 = $1)計算。建議大於 200 以避免風控。
幣種txcurrcdString(3)請參閱 幣種列表
支付方式pay_typeString(6)海外商戶:801101;香港商戶:801501
外部訂單編號out_trade_noString(128)商戶自訂交易編號,於同一商戶帳戶中必須唯一。
交易時間txdtmString(20)時間格式:YYYY-MM-DD hh:mm:ss
過期時間expired_timeString(3)單位分鐘,預設 30 分鐘,允許範圍為 5–120 分鐘。
商品名稱goods_nameString(64)最多 20 個字元(含中英文及數字)。若為中文需使用 UTF-8 編碼。
子商戶編號mchidString(16)僅代理商或特定模式需要,請按實際開通狀態使用。
設備唯一 IDudidString(40)裝置代碼,將顯示於商戶後台。
成功跳轉網址return_urlString(512)支付完成後導向的 URL。

選填參數

支付標記pay_tag預設 ALIPAYHK;大陸版使用 ALIPAYCN

回應參數

參數名稱參數代碼資料型別描述
支付方式pay_typeString(6)回傳支付方式,例如:801101 / 801501
系統時間sysdtmString(20)格式:YYYY-MM-DD hh:mm:ss,作為結算截止依據。
交易時間txdtmString(20)發送請求時的時間。
錯誤訊息resperrString(128)如有錯誤則此欄回傳描述。
交易金額txamtInt(11)付款金額(單位為最小單位)。
附加訊息respmsgString(128)其他訊息(可用於除錯)。
外部訂單編號out_trade_noString(128)商戶自訂交易編號。
QFPay 訂單號syssnString(40)QFPay 系統交易編號。
回應碼respcdString(4)0000 表成功;1143 / 1145 表示仍處理中;其他為失敗。詳見 交易狀態碼
支付連結pay_urlString(512)用戶端用於生成 QR Code 的支付連結。

程式碼範例

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

# API 憑證
environment = 'https://test-openapi-hk.qfapi.com'
app_code = 'D5589D2A1F2E42A9A60C37*********'
client_key = '0E32A59A8B454940A2FF39**********'

# 當前時間
current_time = datetime.datetime.now().replace(microsecond=0)
print(current_time)

# 建立簽名函數
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()

# 請求參數
data = {
  'txamt': '10',
  'txcurrcd': 'HKD',
  'pay_type': '801101',
  'out_trade_no': '01234567890123',
  'txdtm': current_time,
  'mchid': 'ZaMVg*****'
}

# 發送 POST 請求
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())
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="D5589D2A1F2E42A9A60C37*********";
        String key="0E32A59A8B454940A2FF39*********";
        String mchid="ZaMVg*****";

        String pay_type="801101";
        String out_trade_no= "01234567890123";
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String txdtm=df.format(new Date());
        String txamt="10";
        String txcurrcd="EUR";

        Map<String, String> unsortMap = new HashMap<>();
        unsortMap.put("mchid", mchid);
        unsortMap.put("pay_type", pay_type);
        unsortMap.put("out_trade_no", out_trade_no);
        unsortMap.put("txdtm", txdtm);
        unsortMap.put("txamt", txamt);
        unsortMap.put("txcurrcd", txcurrcd);

        String data=QFPayUtils.getDataString(unsortMap);
        String md5Sum=QFPayUtils.getMd5Value(data+key);

        String url="https://test-openapi-hk.qfapi.com";
        String resp= Requests.sendPostRequest(url+"/trade/v1/payment", data, appcode, key);
        System.out.println(resp);
    }
}
// API 憑證
const environment = 'https://test-openapi-hk.qfapi.com'
const app_code = 'D5589D2A1F2E42A9A60C37*********'
const client_key = '0E32A59A8B454940A2FF39*********'

// 當前時間
const txdtm = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')

// 請求參數
const payload = {
  txamt: '10',
  txcurrcd: 'HKD',
  pay_type: '801101',
  out_trade_no: String(Math.round(Math.random() * 1000000000)),
  txdtm,
  mchid: 'ZaMVg*****'
};

// 建立簽名(按 key 排序後,拼接 & 並加上 client_key,再做 MD5)
const ordered = {};
Object.keys(payload).sort().forEach(k => { ordered[k] = payload[k]; });

const pairs = [];
for (const k in ordered) {
  if (Object.prototype.hasOwnProperty.call(ordered, k)) pairs.push(`${k}=${ordered[k]}`);
}
const sign_str = pairs.join("&") + client_key;

const crypto = require('crypto')
const sign = crypto.createHash('md5').update(sign_str).digest('hex').toUpperCase()

// 發送 POST 請求
const request = require("request");
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);
});
<?php
function GetRandStr($length){
  $str='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  $len=strlen($str)-1;
  $randstr='';
  for($i=0;$i<$length;$i++){
    $num=mt_rand(0,$len);
    $randstr .= $str[$num];
  }
  return $randstr;
}

$url = 'https://test-openapi-hk.qfapi.com';
$api_type = '/trade/v1/payment';
$pay_type = '801101';

$app_code = 'FF2FF74F2F2E42769A4A73*********';
$app_key = '7BE791E0FD2E48E6926043B*********';
$now_time = date("Y-m-d H:i:s");

$fields = array(
  'pay_type' => $pay_type,
  'out_trade_no' => GetRandStr(20),
  'txcurrcd' => 'HKD',
  'txamt' => 2200,
  'txdtm' => $now_time
);

ksort($fields);

$pairs = array();
foreach($fields as $k=>$v) {
  $pairs[] = $k.'='.$v;
}
$fields_string = implode('&', $pairs);

$sign = strtoupper(md5($fields_string . $app_key));

$header = array(
  'X-QF-APPCODE: ' . $app_code,
  'X-QF-SIGN: ' . $sign
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url . $api_type);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);

$output = curl_exec($ch);
curl_close($ch);

echo $output;
?>

JSON 回應範例

{
  "sysdtm": "2020-04-13 10:30:34",
  "paydtm": "2020-04-13 10:30:34",
  "txcurrcd": "HKD",
  "respmsg": "",
  "pay_type": "801101",
  "cardcd": "",
  "udid": "qiantai2",
  "txdtm": "2020-04-13 10:30:34",
  "txamt": "300",
  "resperr": "success",
  "out_trade_no": "4K35N374II7UJJ8RGIAE45O2CVHGHFF0",
  "syssn": "20200413000300020087033882",
  "respcd": "0000",
  "pay_url": "https://globalmapi.alipay.com/gateway.do?total_fee=3.0&secondary_merchant_name=###merchant_name###&out_trade_no=20200413000300020087033882&secondary_merchant_industry=7011&service=create_forex_trade&_input_charset=UTF-8&sign=02beb99974ce6167666280b9727c4444&currency=THB&notify_url=https%3A%2F%2Fo2-hk.qfapi.com%2Fonline-test%2Ftrade%2Falipay%2Fv1%2Fonline_notify&order_valid_time=1800&secondary_merchant_id=2565075&sign_type=MD5&partner=2088631377368888&product_code=NEW_OVERSEAS_SELLER&order_gmt_create=2020-04-13+10%3A30%3A34&return_url=&subject=###merchant_name###",
  "chnlsn": ""
}

備註

請將 QR Code 或 iframe 指向回應中的 pay_url
請勿重複使用 out_trade_no
若回傳 respcd = 1143 / 1145,請使用 /trade/v1/query API 查詢最終交易結果。