# OMG(歐買尬/FunPoint)全方位金流 官方接口参考 > **来源**: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 官方文档为准。 --- ## §0 基础环境 | 环境 | 根地址 | |------|--------| | 正式 | `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 签名。 --- ## §1 產生訂單 AioCheckOut /V5(幕前下单) **介接路径**:`{base}/Cashier/AioCheckOut/V5` **Content Type**:`application/x-www-form-urlencoded`,POST **场景**:消费者下单后,特店 POST 订单到 OMG,跳转收银台选付款方式。 ### 1.1 特店传入参数 | 参数 | 型态 | 必填 | 说明 | |------|------|------|------| | 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|OK`) | | 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) | ### 1.2 ChoosePayment 子参数 **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 + 厂商会员编号)。 - 记忆卡号须有会员系统;仅 Visa/Master/JCB,不支援银联。 **Credit 专属**: - `UnionPay` Int 预设 0:银联卡 `0`=消费者可选 / `1`=只用银联(导到银联网站)/ `2`=隐藏银联。须申请;测试环境无银联;不支援分期/红利/记忆卡号。 ### 1.3 信用卡分期(CreditInstallment) - `CreditInstallment` String(20) *:期数 `3`/`6`/`12`/`18`/`24`/`30`(须先申请开通)。刷卡一次授权,后续银行分期;不与定期定额同传;银联不支援。 ### 1.4 信用卡定期定额 - `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。 - 不与分期同传;第一次授权失败不进排程(需重建订单);银联不支援。 --- ## §2 額外回傳的參數(NeedExtraPaidInfo=Y)★重点 > **官方注意事项(原文)**:「額外回傳的參數全部都需要加入檢查碼計算」 > > 即这些额外字段**全部参与 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`;非信用卡/银联空值 | --- ## §3 查詢訂單 QueryTradeInfo /V5 ★重点(当前验签 bug 相关) **介接路径**: - 正式:`https://payment.funpoint.com.tw/Cashier/QueryTradeInfo/V5` - 测试:`https://payment-stage.funpoint.com.tw/Cashier/QueryTradeInfo/V5` **Content Type**:`application/x-www-form-urlencoded`,POST ### 3.1 特店传入参数 | 参数 | 型态 | 必填 | 说明 | |------|------|------|------| | MerchantID | String(10) | * | 特店编号 | | MerchantTradeNo | String(20) | * | 特店交易编号 | | TimeStamp | Int | * | 当下 UnixTimeStamp;**OMG 验证时间区间暂定 3 分钟内有效**,超过则本次介接无效 | | PlatformID | String(10) | | 平台商代号(同 §1.1) | | CheckMacValue | String | * | 检查码(见 §5) | ### 3.2 OMG 回传参数(基础 17 个) **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) | ### 3.3 TradeStatus 交易状态值 ★ | 值 | 含义 | |----|------| | `0` | 交易订单成立**未付款** | | `1` | 交易订单成立**已付款** | | `10200095` | 消费者**未选择付款方式**,故交易失败 | > 注:文档基础回传只列 17 个参数,但 `NeedExtraPaidInfo=Y` 时实际会回传 §2 的全部额外字段(本项目实测共 47 个字段)。这些额外字段同样参与 CheckMacValue(§2 注意事项)。 > > **信用卡「已授权未关帐」= TradeStatus `1`**(关帐是后端日批,不动 TradeStatus)。 --- ## §4 查詢信用卡單筆明細記錄 CreditDetail/QueryTrade /V2 **介接路径**: - 正式:`https://payment.funpoint.com.tw/CreditDetail/QueryTrade/V2` - 测试:**因无法提供实际授权,无法使用此 API** **传入**:`*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 退刷),非此查询接口。此接口仅供明细查询,**测试环境不可用**。 --- ## §5 CheckMacValue 檢查碼機制 ★重点 > 来源:OMG 正文多次指向「附錄檢查碼機制」;附录页未独立抓到,规则同 ECPay 标准引擎(WebSearch 旁证 + 官方「額外回傳參數全部加入檢查碼」明文)。 **核心规则**: 1. **除 CheckMacValue 本身外,其余所有传递参数皆需加入检查码计算**(含空值字段、含 §2 额外回传参数)。 2. 参数名称按字母 **A-Z 排序**,**大小写不敏感**(实测坐实,见 §6.1;OMG/ECPay 同源引擎服务端按 `String.CASE_INSENSITIVE_ORDER` 排序算检查码)。 3. 组合 `key=value`,参数间以 `&` 串接。 4. 前后包夹:`HashKey={HashKey}&{串接串}&HashIV={HashIV}`。 5. **.NET 风格 URLEncode**(各语言须确认 UrlEncode 转换结果符合附录规范——官方强调这是常见出错点)。 6. 整串转**小写**。 7. **SHA256** 摘要(EncryptType=1),hex **大写** = CheckMacValue。 **验签**:对回传参数(含回传的 CheckMacValue)同算法重算,与回传 CheckMacValue 比对。 **本项目实现**:`OmgCheckMacValue`(SHA256,独立工具,零蓝新依赖)。pre-digest pipeline(排序/包夹/.NET URLEncode/还原 `-.!*()`/小写)已用 ECPay 物流官方向量(MD5)验证正确;该向量字段全大写,**排序大小写分歧由生产 QueryTradeInfo 响应实测另行锁定(大小写不敏感,见 §6.1)**。 --- ## §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 仅在响应验签暴露。 - **坐实手段**:commit `abcd7d4` 的 4 候选 CMV 诊断日志(大小写敏感/不敏感 × 空值保留/排除),生产订单 `991786433092835` 实测 `receivedCMV == ci_inc`(大小写不敏感 + 保留空值),其余 3 候选均不等。 - **修复**:`OmgCheckMacValue.generate` 默认排序改 `String.CASE_INSENSITIVE_ORDER`(保留空值不变)。请求侧零回归(参数全首字母大写,两种排序等价)。回归测试 `OmgCheckMacValueTest#verifiesQueryTradeInfoResponseWithCaseInsensitiveKeyOrder` 锁定(修复前该用例在 `verify` 处失败)。 2. **回传格式**:QueryTradeInfo 回传 `text/html`,k=v 用 `&` 分隔(本项目 `parseKvResponse` 解析;2026-08-12 已放宽对尾随 `&`/空值的容忍,commit `7a8e248`)。 3. **TradeStatus 三值**:`0`/`1`/`10200095`,判断支付成功主要看它,但**必须验签通过后才可信**(防伪造免单攻击)。 4. **TimeStamp 3 分钟有效期**:QueryTradeInfo 介接后须 3 分钟内有效(本项目用 `System.currentTimeMillis()/1000`)。 5. **NeedExtraPaidInfo=Y 的影响**:QueryTradeInfo 与付款通知会回传 §2 全部额外字段(本项目实测 47 字段),验签须全纳入。`card4no`/`card6no` 为卡号片段,日志脱敏注意。 6. **QueryTrade/V2 测试不可用**:信用卡明细查询测试环境无授权,无法用;退款走 `DoAction(Action=R)`。 7. **MTN(MerchantTradeNo)永久绑定**:一旦 AioCheckOut 提交,MTN 永久占用不可复用(详见 `payment-attempt-lifecycle.md` 硬约束)。 --- ## 附录:本项目当前 create 组参对照 `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 / 分期 / 定期定额 / 银联 / 记忆卡号。