SCGA Pay

商戶 API 文件

SCGA Pay · 收款核對 API · 資金直接入你嘅收款戶口,平台唔經手資金

基本資料

Base URLhttps://api.pay.scga.hk
認證X-API-Key: hkpay_…
冪等同一個 reference 重複提交會回原有單,唔會開重複單

API key 喺後台「API」分頁建立(只顯示一次);換屆時可以撤銷再建新嘅。

流程

  1. 你嘅系統 POST /payments 建立收款單 → 取 payment_id 同 pay_payload(method 唔傳 = both:同一張單同時有轉數快 QR 同 PayMe 連結)
  2. 把 pay_payload.qr_data_url 顯示成 QR(或者直接用我哋嘅付款頁 /pay/{payment_id})
  3. 客人付款(記住備註要填 6 位付款碼)→ 上載截圖
  4. 你輪詢 GET /payments/{id} 睇 status(paid / pending_review)

建立收款單

Request
curl -X POST https://api.pay.scga.hk/api/v1/payments \
  -H "Content-Type: application/json" \
  -H "X-API-Key: hkpay_xxxxxxxx" \
  -d '{
    "amount_hkd": 200,
    "method": "fps",
    "reference": "BNI-KLN-2026-11-G37",
    "description": "嘉賓登記費",
    "expires_in_minutes": 1440
  }'
Response(節錄)
{
  "payment_id": "7bf929192a673bc0",
  "reference": "BNI-KLN-2026-11-G37",
  "method": "fps",
  "amount_hkd": 200,
  "status": "pending",
  "payment_code": "792826",
  "pay_payload": {
    "qr_data_url": "data:image/png;base64,iVBOR...",
    "qr_text": "00020101021226320012hk.com.hkicl...",
    "instructions": "請用銀行 App 掃描 QR 付款。金額 HK$200.00,付款備註請輸入 792826"
  },
  "payout": { "merchant_name": "SZE C** C*** G***", "fps_mobile": "****1111" }
}

欄位:amount_hkd(必要,> 0)、method(both = FPS + PayMe 同時出,客人邊個通就用邊個;亦可指定 fps / payme)、reference(必要,你嘅單號,同一商戶內唯一)、description、expires_in_minutes、payout_account_id、payout(inline)。

收款身份(換屆用)

⚠️ 每個收款身份都要填收款人全名(同銀行戶口一樣,例如 SZE CHI CHUNG GARY); 填遮罩(SZE C** C*** G***)或簡稱會被拒 —— 因為核對截圖時要靠個名對得上。

優先次序:inline payout(API 即時傳)→ payout_account_id(後台已存)→ 帳號預設。 每張單都會記錄當時用邊個收款身份(payout),換屆後查舊單仍然準確。

# 收款身份由 API 即時傳入(需後台開啟 allow_inline_payout)
curl -X POST https://api.pay.scga.hk/api/v1/payments \
  -H "Content-Type: application/json" \
  -H "X-API-Key: hkpay_xxxxxxxx" \
  -d '{
    "amount_hkd": 200,
    "method": "fps",
    "reference": "BNI-KLN-2027-G01",
    "payout": { "fps_mobile": "+85291111111", "merchant_name": "CHAN T** M***" }
  }'

上載付款截圖(AI 核對)

# 客戶付款後上載截圖(唔使 API key)
curl -X POST https://api.pay.scga.hk/api/v1/payments/7bf929192a673bc0/proof \
  -F "[email protected]"

核對規則:
・金額必須相等・付款方式係 fps/payme/both 時必須對上 6 位付款碼
・收款人姓名:單上顯示嘅收款人(可以係銀行遮罩版,例如 SZE C** C*** G***、SZEC** C***、陳*文,或夾咗 (Wechat Gary) 別名)會同你設定嘅收款人全名比對;對唔上轉人手,線索太少(例如 ***)亦轉人手
・自己轉自己:如果單上「付款人」都係你(例如自己由一個戶口轉去另一個戶口),一律轉人手 —— 唔會當客人付款
・交易狀態「失敗/取消」→ 拒絕;「處理中/指示已提交」→ 唔會當已收款
・收款人姓名(mask 感知)唔對、截圖早過建單 24 小時、同金額撞單 → 轉人手覆核
・每張單最多上載 5 次

Webhook(付款/退款即時通知)

喺後台「Webhook」分頁填 https 網址,我哋會 POST JSON 去你嘅系統;唔使自己輪詢。

事件
payment.paid            客人付款已確認(AI 自動或人手)
payment.pending_review  已收到截圖但要人手覆核
payment.refunded        已記錄退款(可部分)
payment.cancelled       商戶取消咗張單
payment.expired         過期未付款
ping                    後台「送測試 ping」用
Headers
POST https://your-system.example.com/hkpay/webhook
Content-Type: application/json
X-HKPay-Event: payment.paid
X-HKPay-Delivery: 8f3c...
X-HKPay-Timestamp: 1793016296
X-HKPay-Signature: t=1793016296,v1=4f2c9a...
驗簽(Node.js)
import crypto from "node:crypto";

// rawBody 一定要用「未 parse 嘅原始字串」
const [tPart, vPart] = req.headers["x-hkpay-signature"].split(",");
const ts = tPart.split("=")[1];
const sig = vPart.split("=")[1];

if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) throw new Error("stale");

const expect = crypto
  .createHmac("sha256", process.env.HKPAY_WEBHOOK_SECRET)
  .update(ts + "." + rawBody)
  .digest("hex");

if (!crypto.timingSafeEqual(Buffer.from(expect), Buffer.from(sig))) {
  throw new Error("bad signature");
}

失敗會自動重試(30 秒 → 2 分 → 10 分 → 1 小時 → 6 小時 → 24 小時 ×3);後台可以睇最近 20 次派送結果。

退款

平台唔經手資金:退款只係記錄,實際退錢你要自己用銀行/PayMe 做。 已退款金額會由收款淨額扣除,所以唔會再收服務費;全額退嘅單狀態轉 refunded,部分退保持 paid 並累加 refunded_amount。

curl -X POST https://api.pay.scga.hk/api/v1/dashboard/payments/7bf929192a673bc0/refund \
  -H "Authorization: Bearer <session-token>" -H "Content-Type: application/json" \
  -d '{"amount_hkd": 50, "reason": "客人取消"}'

限制與門檻

項目值
截圖客人唔需要理大小:上載後系統自動縮到長邊 1600px、JPEG q82 才送核對(硬上限 10MB 只係防濫用,正常唔會撞到)
每單上載次數5 次,超過轉人手
人手覆核門檻HK$5,000(可設定);以下金額只要金額、付款碼、收款人姓名全對就自動確認
付款碼6 位數字,同一商戶內不重複
截圖時效早過建單 24 小時或遲過 7 日 → 人手
資料保留截圖不長期保存;AI 抽取結果 180 日後清空

全部 endpoints

MethodPath用途認證
POST/api/v1/payments建立收款單(fps / payme)API key
GET/api/v1/payments/{id}查收款單狀態(客戶端用)開放
POST/api/v1/payments/{id}/proof上載付款截圖 → AI 核對開放
GET/api/v1/payments/by-reference/{ref}用自己單號查API key
POST/api/v1/payments/{id}/cancel取消未付款嘅單API key
GET/api/v1/payout-accounts列出收款身份API key / 登入
POST/api/v1/payout-accounts新增收款身份API key / 登入
PATCH/api/v1/payout-accounts/{id}改收款身份(設預設/停用)API key / 登入
GET/api/v1/reconciliation對賬(JSON,已扣退款)API key
GET/api/v1/reconciliation.csv對賬(CSV,開 Excel)API key
POST/api/v1/dashboard/payments/{id}/refund退款(可部分退,只記錄)登入 owner/admin
GET/api/v1/dashboard/payments/{id}/refunds退款紀錄登入
POST/api/v1/dashboard/payments/{id}/review人手確認/拒絕登入
GET/PATCH/api/v1/dashboard/webhook讀/設 webhook URL登入 admin
POST/api/v1/dashboard/webhook/test送測試 ping(附簽名)登入 admin
POST/api/v1/dashboard/webhook/rotate換 webhook 簽名密鑰登入 admin
GET/api/v1/dashboard/invoices/{id}/pay月結服務費繳費 QR登入
GET/api/v1/version平台版本/啟用方法/門檻開放
GET/openapi.jsonOpenAPI 3.1 規格開放
POST/api/v1/webhooks/{provider}支付機構回調(預留)API key
GET/health健康檢查開放

錯誤碼

HTTP意思
400參數錯(金額 ≤ 0、方法唔支援、已取消嘅單再取消)
401冇 X-API-Key,或者 key 無效
403帳號停用,或者唔夠權限(例如 staff 想改收款身份)
404搵唔到收款單
409用戶名重複(開戶/加成員)
413超過硬上限 10MB(自動縮圖後正常唔會撞到)
415圖片格式唔支援(只收 png/jpeg/webp/gif)
422業務驗證唔過(例如未設定收款身份、退款超過餘額)
429同一張單上載截圖次數過多(預設 5 次)

錯誤回應格式:{ "detail": "說明" }

下載 OpenAPI 規格(JSON)文字版完整說明申請開戶