Payment 产品指南
余额查询、转账、交易查询、SWIFT 报文、虚拟账户和入账通知。接口细节见 API 参考。
概述
Stabo Payment OpenAPI 面向企业客户。通过本 API,可以实现以下功能:
- 账户管理:实时查询账户余额和状态
- 资金转账:支持行内转账、MEPS+ 本地转账、SWIFT 跨境汇款
- 交易查询:查询历史交易记录和转账状态
- 虚拟账户管理:申请开通和管理虚拟子账户(Virtual Account)
- 报文获取:获取 MT/MX SWIFT 报文原文
- 实时通知:通过 Webhook 接收入账等事件通知
版本:v1.7
接入准备、环境信息和鉴权见快速开始与鉴权。协议、统一响应格式见通用约定。
API 一览
| 模块 | 接口 | 说明 |
|---|---|---|
| 账户 | GET /openapi/v1/payments/balance | 余额查询 |
| 转账 | POST /openapi/v1/payments/transfer/intra-bank | 行内转账 |
| 转账 | GET /openapi/v1/payments/transfer/intra-bank/{referenceNo} | 行内转账结果查询 |
| 转账 | POST /openapi/v1/payments/transfer/meps | MEPS+ 转账 |
| 转账 | GET /openapi/v1/payments/transfer/meps/{referenceNo} | MEPS+ 转账结果查询 |
| 转账 | POST /openapi/v1/payments/transfer/swift | 跨境汇款 |
| 转账 | GET /openapi/v1/payments/transfer/swift/{referenceNo} | 跨境汇款结果查询 |
| 交易 | GET /openapi/v1/payments/transaction/history | 交易历史查询 |
| 交易 | GET /openapi/v1/payments/message/mtmx | MT/MX 报文查询 |
| 费用 | POST /openapi/v1/payments/fees/estimate | 查询转账预估手续费 |
| 虚拟账户 | POST /openapi/v1/wallet/virtual-accounts | 申请开通虚拟账户 |
| 虚拟账户 | PUT /openapi/v1/wallet/virtual-account-requests/{requestNo} | 修改虚拟账户申请 |
| 虚拟账户 | GET /openapi/v1/wallet/virtual-account-requests/{requestNo} | 查询虚拟账户申请详情 |
| 虚拟账户 | GET /openapi/v1/wallet/virtual-account-requests | 查询虚拟账户申请列表 |
| 虚拟账户 | GET /openapi/v1/wallet/virtual-accounts | 查询虚拟账户列表 |
| 虚拟账户 | GET /openapi/v1/wallet/virtual-accounts/{virtualAccountNo} | 查询虚拟账户详情 |
| Webhook | 商户配置的 HTTPS URL | 接收入账通知 va.credit.create |
每个接口的参数、响应和在线调试见 API 参考。
请求头
Payment 接口在通用约定的请求头之外,还需要 X-Channel-Provider。
| Header | 说明 | 是否必需 |
|---|---|---|
Authorization | Bearer {accessToken} | 是 |
Content-Type | application/json | 是,POST 请求必填 |
Idempotency-Key | 唯一请求标识,用于防止重复操作(建议使用 UUID)。规则见幂等性 | 是,三个转账 POST 接口必填 |
X-Channel-Provider | 渠道提供商标识,如 GLDB | 是。虚拟账户接口不传时默认 GLDB |
业务数据基类字段
所有业务响应的 data 对象中都包含以下通用字段:
| 字段 | 说明 | 类型 | 示例 |
|---|---|---|---|
providerStatusCode | 渠道响应码 | String | 000000 |
providerMessage | 渠道响应消息 | String | ok |
providerRequestSerialNo | 渠道请求流水号 | String | 795883203712778240 |
providerResponseSerialNo | 渠道响应流水号 | String | 785957885476737024 |
providerTimestamp | 渠道请求时间戳 | String | 2023-05-17 21:03:48 |
错误响应
请以 HTTP 状态码判断请求是否成功,规则见错误码。渠道返回错误时,HTTP 状态码为 400,响应体中的 code 为 500,data 中带渠道返回的 provider* 字段:
{
"code": 500,
"message": "Operation failed",
"traceId": "trace-uuid-string",
"data": {
"providerStatusCode": "100019",
"providerMessage": "Version number is empty",
"providerRequestSerialNo": "795883203712778240",
"providerResponseSerialNo": "785957885476737024",
"providerTimestamp": "2023-05-17 21:03:48"
}
}渠道响应码
providerStatusCode 的取值由渠道决定。
GLDB 渠道响应码
| 响应码 | 说明 |
|---|---|
000000 | 成功 |
100019 | 版本号为空 |
100020 | 渠道序列号为空 |
100021 | 时间戳为空 |
101119 | 时间戳不匹配(超过 2 分钟) |
100111 | 字段长度超限 |
100017 | 接口不存在或状态异常 |
100004 | 签名验证失败 |
100067 | Payload 解密失败 |
100098 | 开发者应用状态异常 |
100060 | 开发者证书未找到 |
100099 | 发送下游系统异常 |
999999 | 未知异常 |
199999 | 下游系统返回错误 |
交易状态
| 状态 | 说明 |
|---|---|
SUCCESS | 成功 |
PROCESSING | 处理中 |
SENT_TO_BANK | 已发送至银行 |
FAILED | 失败 |
幂等性 (Idempotency)
Stabo API 支持幂等性,避免因网络中断等原因导致的操作重复(如重复扣款)。
机制说明:
- 客户端在发送转账
POST请求时,必须在 HTTP Header 中提供Idempotency-Key - 使用相同的
Idempotency-Key发送请求时,Stabo 只会处理一次 Idempotency-Key由客户端生成(建议使用 UUID),有效期为 24 小时GET请求天然幂等,不需要此 Header
每笔转账交易必须使用唯一的 Idempotency-Key,切勿为不同交易复用同一个 Key。
在有效期内再次使用同一个 Idempotency-Key,请求会被拒绝(HTTP 400,message 为 Duplicate request detected),不会返回首次处理的结果。第一次请求仍在处理时,重复请求同样被拒绝。Key 在请求被受理时即被占用,首次请求失败也不会释放。超时或没收到响应时,用 referenceNo 调用结果查询接口确认状态,不要重新提交。
余额查询
查询账户可用余额。accountNumber 和 currency 必填。
curl -G "https://api.test.stabofx.com/openapi/v1/payments/balance" \
-H "Authorization: Bearer {accessToken}" \
-H "X-Channel-Provider: GLDB" \
--data-urlencode "accountNumber=10000000001" \
--data-urlencode "currency=USD"响应示例:
{
"code": 200,
"message": "OK",
"traceId": "a1b2c3d4-e5f6-7890",
"data": {
"providerStatusCode": "000000",
"providerMessage": "ok",
"providerRequestSerialNo": "795883203712778240",
"providerResponseSerialNo": "785957885476737024",
"providerTimestamp": "2023-05-17 21:03:48",
"balance": "1000000.00",
"currency": "USD",
"status": "ACTIVE"
}
}status 取值:ACTIVE / CLOSED / INACTIVE / DORMANT。
行内转账
账户之间的行内转账,支持所有币种。适用于同一银行内不同账户间的资金调拨。
curl -X POST "https://api.test.stabofx.com/openapi/v1/payments/transfer/intra-bank" \
-H "Authorization: Bearer {accessToken}" \
-H "Content-Type: application/json" \
-H "X-Channel-Provider: GLDB" \
-H "Idempotency-Key: STABO20231121001" \
-d '{
"referenceNo": "STABO20231121001",
"fromAccount": "10000000001",
"beneficiaryAccount": "10000000002",
"currency": "SGD",
"amount": "200.00",
"remarks": "Payment for services"
}'响应示例:
{
"code": 200,
"message": "OK",
"traceId": "a1b2c3d4-e5f6-7890",
"data": {
"providerStatusCode": "000000",
"providerMessage": "ok",
"providerRequestSerialNo": "795883203712778240",
"providerResponseSerialNo": "785957885476737024",
"providerTimestamp": "2023-05-17 21:03:48",
"channelSerialNo": "742465990302056448",
"status": "SUCCESS",
"coreSerialNo": "FT23131QQQ2P",
"poboAccountNo": "10000000003",
"poboAccountName": "EXAMPLE PTE. LTD."
}
}注意事项
remarks仅支持字母数字、空格及特殊字符/ - ? : ( ) . , ' +- 当返回
PROCESSING状态时,请在 5 分钟后调用结果查询接口确认最终状态 - 走 POBO 出账的订单,响应会返回
poboAccountNo/poboAccountName;调用结果查询接口时建议传入accountNumber=poboAccountNo,以明确指定 POBO 出账账号。未传accountNumber时,系统将根据referenceNo自动匹配对应的 POBO 出账账号。
转账结果查询
三种转账都有对应的结果查询接口,参数和响应相同。转账返回 PROCESSING 时,调用结果查询接口获取最终结果。
# 普通订单 / POBO 出账订单
GET /openapi/v1/payments/transfer/intra-bank/STABO20231121001
# POBO 出账订单也可显式指定出账账号
GET /openapi/v1/payments/transfer/intra-bank/STABO20231121001?accountNumber=10000000003MEPS+ 转账
通过 MEPS+(MAS Electronic Payment System)进行新加坡本地实时转账。
特点:
- 仅支持 SGD 币种
- 实时到账
- 适用于大额本地转账
请求示例:
{
"referenceNo": "STABO20231121002",
"fromAccount": "10000000001",
"beneficiaryAccount": "10000000004",
"beneficiaryName": "Example Company",
"beneficiaryAddress": "1 Example Road, Singapore 000000",
"beneficiaryCountryCode": "SG",
"currency": "SGD",
"amount": "100.00",
"beneficiaryBankCode": "EXMPSGS0XXX",
"beneficiaryBankName": "EXAMPLE BANK LTD",
"purposeCode": "BEXP",
"chargeBearer": "SHA"
}purposeCode 和 chargeBearer 的取值见附录。
注意事项
beneficiaryName、beneficiaryAddress、remarks仅支持字母数字、空格及特殊字符/ - ? : ( ) . , ' +- 如收款银行非 MEPS+ 参与行,需提供中间行信息
- 走 POBO 出账的订单,响应会返回
poboAccountNo/poboAccountName;调用结果查询接口时建议传入accountNumber=poboAccountNo,以明确指定 POBO 出账账号。未传accountNumber时,系统将根据referenceNo自动匹配对应的 POBO 出账账号。
跨境汇款
通过 SWIFT 网络进行跨境汇款。注意:GLDB 渠道不支持 SGD 币种的跨境汇款。
请求示例:
{
"referenceNo": "STABO20231121003",
"fromAccount": "10000000001",
"beneficiaryAccount": "10000000005",
"beneficiaryName": "Example Company",
"beneficiaryAddress": "1 Example Road",
"beneficiaryCountryCode": "SG",
"beneficiaryCountryName": "Singapore",
"currency": "USD",
"amount": "1001.64",
"beneficiaryBankCode": "EXMPSGS0XXX",
"beneficiaryBankName": "EXAMPLE BANK LTD",
"chargeBearer": "SHA",
"purposeCode": "BEXP",
"remarks": "open transfer test"
}注意事项(GLDB 渠道)
- 不支持 SGD 币种
- BIC 代码不足 11 位需补充
X beneficiaryName、beneficiaryAddress、remarks仅支持字母数字、空格及特殊字符/ - ? : ( ) . , ' +- 走 POBO 出账的订单,响应会返回
poboAccountNo/poboAccountName;调用结果查询接口时建议传入accountNumber=poboAccountNo,以明确指定 POBO 出账账号。未传accountNumber时,系统将根据referenceNo自动匹配对应的 POBO 出账账号。
交易历史查询
查询账户的交易历史记录,支持分页查询。适用于对账和财务报表生成。
GET /openapi/v1/payments/transaction/history?accountNumber=10000000001¤cy=SGD&startDate=20240213&endDate=20240426¤tPage=1&pageSize=20amount 为正数表示收入,负数表示支出。pageSize 最大 100。transactionType 的取值见交易类型代码。
查询转账预估手续费
根据转账类型和金额,计算产生的预估手续费。请求体为 JSON。
请求示例:
{
"transferType": "SWIFT",
"amount": "100.00",
"currency": "USD",
"usdEquivalentAmount": "100.00",
"chargeOption": "SHA"
}fee 保留两位小数,向上进位。例如 1.221 会被算成 1.23。INTRA_BANK、MEPS、SWIFT SGD 的手续费币种为 SGD,非 SGD 的 SWIFT 为 USD。当前费用预估逻辑不依赖 chargeOption。
MT/MX 报文查询
查询转账交易关联的 MT/MX SWIFT 报文原文。适用于合规审计和问题排查。paymentReference 来自转账结果查询接口。
GET /openapi/v1/payments/message/mtmx?paymentReference=SGL24241GG0LJHCB&direction=OUTGOINGSWIFT 报文示例
以下是不同场景下返回的 messageContent 字段内容示例。示例中的机构、账号和参考号均为占位值。
虚拟账户
为 MSO(Money Service Operator)客户申请开通虚拟子账户。适用于支付机构为其下游商户开立独立的虚拟账户。
流程:申请开通 → 银行审核 → 查询申请状态 → 申请成功后在申请详情中取得虚拟账户号 → 查询虚拟账户。
- 申请开通和修改申请使用
multipart/form-data,不是 JSON。 - 申请提交后需要银行审核,请通过查询接口跟踪申请状态。
- 申请成功后,虚拟账户号会在申请详情中返回。
- 只能修改状态为
PENDING的申请。 - 文件相关的以最后一次提交为准,每次提交都应该全部文件重新提交。新上传的文件会覆盖原有文件。
contactPhone使用 E.164 格式,如+6591234567,不含空格。- 这些接口不校验
Idempotency-Key。 - 申请状态和虚拟账户状态见附录。
请求示例(申请开通):
POST /openapi/v1/wallet/virtual-accounts
Content-Type: multipart/form-data
accountName=Example Trading Pte Ltd
currency=SGD,USD
contactName=Example Contact
contactEmail=contact@example.com
contactPhone=+6500000000
companyRegistrationDoc=<binary file data>
otherDocuments=<binary file data>响应示例:
{
"code": 200,
"message": "OK",
"traceId": "6a3ae549-32dd-469a-a6b8-4e213c070930",
"data": {
"requestNo": "SA0000000001",
"status": "PENDING"
}
}列表接口用 pageNum(默认 1)和 pageSize(默认 10,最大 1000)分页。例如:
GET /openapi/v1/wallet/virtual-accounts?status=ACTIVE&pageNum=1&pageSize=20入账通知 (va.credit.create)
账户收到入账资金时,Stabo 通过 Webhook 推送 va.credit.create 事件。
通知机制、重试策略、请求头、事件对象结构和签名验证与其他产品相同,见 Webhook。这里只说明本事件的载荷。Webhook-Event-Type 为 va.credit.create。
最佳实践:收到 Webhook 通知后,建议先返回 2xx 响应,再异步处理业务逻辑,避免处理超时导致重复推送。
data.object 字段说明
| 字段名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
transactionReference | String | Y | 交易参考号 |
tradeDate | String | Y | 交易日期,银行原始格式 yyyyMMdd,例如 20260528 |
tradeTime | String | Y | 交易时间,银行原始格式 HHmmssSSS,例如 101135517 表示 10:11:35.517 |
valueDate | String | Y | 起息日,银行原始格式 yyyyMMdd,例如 20260528 |
currency | String | Y | 币种 |
amount | String | Y | 金额 |
senderAccount | String | Y | 付款方账号 |
senderName | String | Y | 付款方名称 |
senderBankCode | String | N | 付款方银行代码 |
receiverAccount | String | Y | 收款方账号 |
receiverName | String | Y | 收款方名称 |
receiverBankCode | String | N | 收款方银行代码 |
remarks | String | N | 备注 |
direction | String | Y | 方向(INCOMING/OUTGOING) |
paymentReference | String | N | 支付参考号 |
source | String | Y | 来源(SWIFT/SWIFTMX/FAST/MEPS/INTERNAL) |
eventReference | String | Y | 事件参考号 |
accountNumber | String | Y | 账号 |
senderBankName | String | N | 付款方银行名称 |
masterAccountNo | String | N | 主账户号,仅多币种账户适用;单币种报文不携带该字段 |
示例 Payload
{
"id": "evt_1234567890",
"object": "event",
"type": "va.credit.create",
"created": 1712345678,
"data": {
"object": {
"transactionReference": "TXN0000000001",
"tradeDate": "20260528",
"tradeTime": "101135517",
"valueDate": "20260528",
"currency": "USD",
"amount": "20600.00",
"senderAccount": "123456789",
"senderName": "EXAMPLE SENDER PTE LTD",
"senderBankCode": "EXMPHKHHXXX",
"receiverAccount": "10000000001",
"receiverName": "EXAMPLE RECEIVER PTE LTD",
"receiverBankCode": "EXMBSGSGXXX",
"remarks": "INVOICE-0001",
"direction": "INCOMING",
"paymentReference": "SGL0000000000000",
"source": "SWIFTMX",
"eventReference": "00000000-0000-4000-8000-000000000001",
"accountNumber": "10000000001",
"senderBankName": "EXAMPLE BANK LIMITED",
"masterAccountNo": "10000000000"
}
}
}附录
费用承担方式、汇款目的代码、交易类型代码、国家代码、虚拟账户申请状态和虚拟账户状态见 Payment 附录。
常见问题与支持
Q: 如何确保转账不会重复执行?
A: 每次转账请求使用唯一的 Idempotency-Key。同一个 Key 只会被处理一次,有效期内再次提交会被拒绝。网络超时或没收到响应时,不要重新提交,用 referenceNo 调用结果查询接口确认状态,见幂等性。