来源:OMG 官方介接技术文件 https://developers.omg.com.tw/payment/aio/ 文档版本:V 1.5.3(2026-07,首页标注,茂為歐買尬數位科技) 抓取日期:2026-08-12 抓取页:
01_order.html(產生訂單)、04_order_query.html(查詢訂單) 用途:本项目 OMG 支付接入/排查参考。底层引擎与 ECPay(綠界)同源(FunPoint),但以 OMG 官方文档为准。
| 环境 | 根地址 |
|---|---|
| 正式 | https://payment.funpoint.com.tw |
| 测试 | https://payment-stage.funpoint.com.tw |
本项目配置(application.yml → omg.base-url):测试期指向 stage。
凭证:门店级 pos_store_omg(merchant_id / hash_key / hash_iv / store_id),CheckMacValue 用 HashKey/HashIV 签名。
介接路径:{base}/Cashier/AioCheckOut/V5
Content Type:application/x-www-form-urlencoded,POST
场景:消费者下单后,特店 POST 订单到 OMG,跳转收银台选付款方式。
| 参数 | 型态 | 必填 | 说明 |
|---|---|---|---|
| MerchantID | String(10) | * | 特店编号 |
| MerchantTradeNo | String(20) | * | 特店交易编号(唯一不可重复;英数字大小写混合;PlatformID 模式下全平台不可重复) |
| StoreID | String(20) | 分店代号(英数字大小写混合) | |
| MerchantTradeDate | String(20) | * | yyyy/MM/dd HH:mm:ss |
| PaymentType | String(20) | * | 固定 aio |
| TotalAmount | Int | * | 交易金额(整数,仅 NTD) |
| TradeDesc | String(200) | 交易描述 | |
| ItemName | String(200) | 商品名称(多笔以 # 分隔;中文60/英数字120 字内,超出自动截断) |
|
| ReturnURL | String(200) | * | 付款完成 Server POST 通知网址(收到后须回传 `1 |
| ChoosePayment | String(20) | * | Credit/ATM/CVS/AFTEE/BarcodeATM/ApplePay/ALL |
| CheckMacValue | String | * | 检查码(见 §5) |
| ClientBackURL | String(200) | Client 端返回商店按钮 | |
| ItemURL | String(200) | 商品销售网址 | |
| Remark | String(100) | 备注 | |
| ChooseSubPayment | String(20) | 付款子项目(指定后无法选其它) | |
| OrderResultURL | String(200) | Client 端付款结果回传(幕前;银联卡/ATM/CVS/Barcode/BarcodeATM 不支援) | |
| NeedExtraPaidInfo | String(1) | 预设 N;Y=回传额外付款信息(见 §2)。本项目用 Y |
|
| DeviceSource | String(10) | 带空值,系统自动判定 | |
| IgnorePayment | String(100) | ChoosePayment=ALL 时隐藏付款方式(# 分隔):Credit/ATM/CVS/BarcodeATM |
|
| PlatformID | String(10) | 平台商代号;一般特店/平台商自身带空值,平台商的特店带绑定的 MerchantID | |
| InvoiceMark | String(1) | 固定 N(本项目发票走 ezPay) |
|
| CustomField1~4 | String(50) | 自定义字段(特殊符号仅支援 ,.#()$[];%{}:?/&@<>!) |
|
| EncryptType | Int | * | 固定 1(SHA256) |
| Language | String(3) | 预设中文;ENG/KOR/JPN/CHI |
|
| RiskMerchantMemberID | String(100) | 风控监测会员识别码(申请风控时必填,目前仅 ATM) |
ALL / ATM:
ExpireDate Int:缴费有效天数 1~60(预设 1)。例:4/10 成立、有效期 1 天 → 截止 4/11 23:59。ExpireMinute Int:有效分钟数 10~1440(10 的倍数;仅中信/一银/凯基虚拟账号)。与 ExpireDate 不可同传;ExpireMinute>0 以分钟为主。ATMFromBankID String(3):转出银行代码(仅凯基 ATM,需申请)。ATMFromBankAcc String(16):转出银行账号(16 码,不足左补 0;仅凯基)。PaymentInfoURL String(200):Server 端回传付款信息(取号通知)。ClientRedirectURL String(200):Client 端回传付款信息。ALL / CVS(超商代码):
StoreExpireDate Int:缴费截止分钟(预设 10080=7 天;测试上限 3012 分=3 天)。Desc_1~4 String(20):超商缴费平台显示的交易描述。PaymentInfoURL / ClientRedirectURL:同上。ALL / BarcodeATM(超商快付):
BarcodeATMExpireDate int:天数(预设 7,上限 7;测试上限 7)。PaymentInfoURL / ClientRedirectURL:同上。回传三段号码(非条码图,需自转 code39)。ALL / Credit(信用卡):
BindingCard Int:记忆卡号 1/0。MerchantMemberID String(30):记忆卡号识别码(MerchantID + 厂商会员编号)。
Credit 专属:
UnionPay Int 预设 0:银联卡 0=消费者可选 / 1=只用银联(导到银联网站)/ 2=隐藏银联。须申请;测试环境无银联;不支援分期/红利/记忆卡号。CreditInstallment String(20) *:期数 3/6/12/18/24/30(须先申请开通)。刷卡一次授权,后续银行分期;不与定期定额同传;银联不支援。PeriodAmount Int *:每次授权金额(须 = TotalAmount)。PeriodType String(1) *:D天 / M月 / Y年。Frequency Int *:执行频率(D≤365 / M≤12 / Y≤1)。ExecTimes Int *:执行次数(D≤999 / M≤99 / Y≤9)。PeriodReturnURL String(200):每次授权结果回传 URL。官方注意事项(原文):「額外回傳的參數全部都需要加入檢查碼計算」
即这些额外字段全部参与 CheckMacValue 计算——本项目
NeedExtraPaidInfo=Y,故 QueryTradeInfo 响应与付款通知回调会带回这些字段,验签时必须全部纳入(我们OmgCheckMacValue已对响应全部字段签名,字段集一致,不是验签分歧原因)。
应用场景:产生订单时 NeedExtraPaidInfo=Y,OMG 在「付款结果通知」与「查询订单」时额外回传下表参数。
| 参数 | 型态 | 说明 |
|---|---|---|
| AlipayID | String(10) | 支付宝系统编号(目前已无提供此付款方式) |
| AlipayTradeNo | String(20) | 支付宝交易编号(目前已无) |
| TenpayTradeNo | String(20) | 财付通交易编号(目前已无) |
| WebATMAccBank | String(3) | WebATM 付款人银行代码(未提供则空) |
| WebATMAccNo | String(5) | WebATM 银行账号后五码 |
| WebATMBankName | String(10) | 银行名称 |
| ATMAccBank | String(3) | ATM 付款人银行代码(未提供则空) |
| ATMAccNo | String(5) | ATM 银行账号后五码 |
| PaymentNo | String(14) | 缴费代码 |
| PayFrom | String(10) | 缴费超商 family(全家)/ibon(7-ELEVEN) |
| gwsr | Int | 授权交易单号 |
| process_date | String(20) | 处理时间 yyyy/MM/dd HH:mm:ss |
| auth_code | String(6) | 授权码 |
| amount | Int | 金额 |
| stage | Int | 分期期数 |
| stast | Int | 头期金额 |
| staed | Int | 各期金额 |
| eci | Int | 3D(VBV),5/6/2/1 代表 3D 交易 |
| card4no | String(4) | 卡片末 4 码 |
| card6no | String(6) | 卡片前 6 码 |
| red_dan | Int | 红利扣点 |
| red_de_amt | Int | 红利折抵金额 |
| red_ok_amt | Int | 实际扣款金额 |
| red_yet | Int | 红利剩余点数 |
| PeriodType | String(1) | 订单建立时的周期种类 |
| Frequency | Int | 订单建立时的执行频率 |
| ExecTimes | Int | 订单建立时的执行次数 |
| PeriodAmount | Int | 订单建立时的每次授权金额 |
| TotalSuccessTimes | Int | 目前已成功授权次数 |
| TotalSuccessAmount | Int | 目前已成功授权金额合计 |
| CVSStoreID | String(20) | 超商代码缴款的店铺代号 |
| CVSStoreName | String(20) | 超商代码缴款的店铺名称 |
| UnionPay | String(1) | 银联回传:银联卡 Y / 一般信用卡 N |
| ForeignCard | String(1) | 海外卡:海外卡 Y / 国内地 N;非信用卡/银联空值 |
介接路径:
https://payment.funpoint.com.tw/Cashier/QueryTradeInfo/V5https://payment-stage.funpoint.com.tw/Cashier/QueryTradeInfo/V5Content Type:application/x-www-form-urlencoded,POST
| 参数 | 型态 | 必填 | 说明 |
|---|---|---|---|
| MerchantID | String(10) | * | 特店编号 |
| MerchantTradeNo | String(20) | * | 特店交易编号 |
| TimeStamp | Int | * | 当下 UnixTimeStamp;OMG 验证时间区间暂定 3 分钟内有效,超过则本次介接无效 |
| PlatformID | String(10) | 平台商代号(同 §1.1) | |
| CheckMacValue | String | * | 检查码(见 §5) |
Content Type:text/html,POST
格式:订单结果以 form-data 参数直接回传页面,参数=值,参数间以 & 隔开。
例:MerchantID=123456789&MerchantTradeNo=123456abc&TradeNo=20120315174058256423
| 参数 | 型态 | 说明 |
|---|---|---|
| MerchantID | String(9) | 特店编号 |
| MerchantTradeNo | String(20) | 特店交易编号 |
| StoreID | String(20) | 分店代号 |
| TradeNo | String(20) | OMG 交易编号 |
| TradeAmt | Int | 交易金额 |
| PaymentDate | String(20) | 付款时间 yyyy/MM/dd HH:mm:ss |
| PaymentType | String(20) | 付款方式 |
| HandlingCharge | Int | 手续费合计(履约结束后才计算,未计前为 0) |
| PaymentTypeChargeFee | Decimal | 通路费 |
| TradeDate | String(20) | 订单成立时间 yyyy/MM/dd HH:mm:ss |
| TradeStatus | String(8) | 交易状态(见下) |
| ItemName | String(200) | 商品名称 |
| CustomField1~4 | String(50) | 自定义字段 |
| CheckMacValue | String | 检查码(特店必须检查以验证,见 §5) |
| 值 | 含义 |
|---|---|
0 |
交易订单成立未付款 |
1 |
交易订单成立已付款 |
10200095 |
消费者未选择付款方式,故交易失败 |
注:文档基础回传只列 17 个参数,但
NeedExtraPaidInfo=Y时实际会回传 §2 的全部额外字段(本项目实测共 47 个字段)。这些额外字段同样参与 CheckMacValue(§2 注意事项)。信用卡「已授权未关帐」= TradeStatus
1(关帐是后端日批,不动 TradeStatus)。
介接路径:
https://payment.funpoint.com.tw/CreditDetail/QueryTrade/V2传入:*MerchantID / *CreditRefundId Int(信用卡授权单号,= gwsr,须 NeedExtraPaidInfo=Y 取得)/ *CreditAmount Int / *CreditCheckCode Int(厂商后台→信用卡收单→信用卡授权信息查到)/ *CheckMacValue
回传:JSON 格式(非 k=v)。
RtnMsg:成功空值;error_Stop(查无商家或到期)/error_nopay(查无该授权单号)/error(错误)。RtnValue:TradeID / amount / clsamt(已关帐金额)/ authtime / status。status(未有明细):已取消 / 未授权 / 已授权;(有明细)銀行拒絕 / 要關帳 / 關帳中 / 已關帳 / 要取消 / 取消中 / 已取消 / 銀行追回中 / 銀行已追回 / 批次失敗 / 不明 / 操作取消。close_data[]:status / sno(关帐序号) / amount / datetime。本项目退款用
CreditDetail/DoAction(Action=R 退刷),非此查询接口。此接口仅供明细查询,测试环境不可用。
来源:OMG 正文多次指向「附錄檢查碼機制」;附录页未独立抓到,规则同 ECPay 标准引擎(WebSearch 旁证 + 官方「額外回傳參數全部加入檢查碼」明文)。
核心规则:
String.CASE_INSENSITIVE_ORDER 排序算检查码)。key=value,参数间以 & 串接。HashKey={HashKey}&{串接串}&HashIV={HashIV}。验签:对回传参数(含回传的 CheckMacValue)同算法重算,与回传 CheckMacValue 比对。
本项目实现:OmgCheckMacValue(SHA256,独立工具,零蓝新依赖)。pre-digest pipeline(排序/包夹/.NET URLEncode/还原 -.!*()/小写)已用 ECPay 物流官方向量(MD5)验证正确;该向量字段全大写,排序大小写分歧由生产 QueryTradeInfo 响应实测另行锁定(大小写不敏感,见 §6.1)。
QueryTradeInfo 响应验签分歧 — 已解决(2026-08-12 坐实并修复):
OmgCheckMacValue 默认用 Comparator.naturalOrder()(ASCII 大小写敏感)排序算 CheckMacValue,而 OMG 服务端按大小写不敏感排序算。QueryTradeInfo 响应字段大小写混合(首字母大写 AlipayID/MerchantID/TradeStatus vs 首字母小写 amount/auth_code/card4no/eci/gwsr/process_date/red_dan),两种排序结果不同 → 验签必然 mismatch。出站请求参数全为首字母大写,两种排序相同,故请求签名一直被 OMG 接受,bug 仅在响应验签暴露。abcd7d4 的 4 候选 CMV 诊断日志(大小写敏感/不敏感 × 空值保留/排除),生产订单 991786433092835 实测 receivedCMV == ci_inc(大小写不敏感 + 保留空值),其余 3 候选均不等。OmgCheckMacValue.generate 默认排序改 String.CASE_INSENSITIVE_ORDER(保留空值不变)。请求侧零回归(参数全首字母大写,两种排序等价)。回归测试 OmgCheckMacValueTest#verifiesQueryTradeInfoResponseWithCaseInsensitiveKeyOrder 锁定(修复前该用例在 verify 处失败)。回传格式:QueryTradeInfo 回传 text/html,k=v 用 & 分隔(本项目 parseKvResponse 解析;2026-08-12 已放宽对尾随 &/空值的容忍,commit 7a8e248)。
TradeStatus 三值:0/1/10200095,判断支付成功主要看它,但必须验签通过后才可信(防伪造免单攻击)。
TimeStamp 3 分钟有效期:QueryTradeInfo 介接后须 3 分钟内有效(本项目用 System.currentTimeMillis()/1000)。
NeedExtraPaidInfo=Y 的影响:QueryTradeInfo 与付款通知会回传 §2 全部额外字段(本项目实测 47 字段),验签须全纳入。card4no/card6no 为卡号片段,日志脱敏注意。
QueryTrade/V2 测试不可用:信用卡明细查询测试环境无授权,无法用;退款走 DoAction(Action=R)。
MTN(MerchantTradeNo)永久绑定:一旦 AioCheckOut 提交,MTN 永久占用不可复用(详见 payment-attempt-lifecycle.md 硬约束)。
OmgPayController.create 实际组参(对照 §1):
MerchantID / MerchantTradeNo / MerchantTradeDate / PaymentType=aio /
TotalAmount / TradeDesc / ItemName / ReturnURL / ChoosePayment=ALL /
EncryptType=1 / InvoiceMark=N / NeedExtraPaidInfo=Y / PaymentInfoURL
未用:StoreID / ClientBackURL / ItemURL / Remark / ChooseSubPayment / OrderResultURL / DeviceSource / IgnorePayment / PlatformID / CustomField / Language / RiskMerchantMemberID / 分期 / 定期定额 / 银联 / 记忆卡号。