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/mepsMEPS+ 转账
转账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/mtmxMT/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说明是否必需
AuthorizationBearer {accessToken}是
Content-Typeapplication/json是,POST 请求必填
Idempotency-Key唯一请求标识,用于防止重复操作(建议使用 UUID)。规则见幂等性是,三个转账 POST 接口必填
X-Channel-Provider渠道提供商标识,如 GLDB是。虚拟账户接口不传时默认 GLDB

业务数据基类字段

所有业务响应的 data 对象中都包含以下通用字段:

字段说明类型示例
providerStatusCode渠道响应码String000000
providerMessage渠道响应消息Stringok
providerRequestSerialNo渠道请求流水号String795883203712778240
providerResponseSerialNo渠道响应流水号String785957885476737024
providerTimestamp渠道请求时间戳String2023-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签名验证失败
100067Payload 解密失败
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=10000000003

MEPS+ 转账

通过 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&currency=SGD&startDate=20240213&endDate=20240426&currentPage=1&pageSize=20

amount 为正数表示收入,负数表示支出。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=OUTGOING

SWIFT 报文示例

以下是不同场景下返回的 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 字段说明

字段名称类型必填说明
transactionReferenceStringY交易参考号
tradeDateStringY交易日期,银行原始格式 yyyyMMdd,例如 20260528
tradeTimeStringY交易时间,银行原始格式 HHmmssSSS,例如 101135517 表示 10:11:35.517
valueDateStringY起息日,银行原始格式 yyyyMMdd,例如 20260528
currencyStringY币种
amountStringY金额
senderAccountStringY付款方账号
senderNameStringY付款方名称
senderBankCodeStringN付款方银行代码
receiverAccountStringY收款方账号
receiverNameStringY收款方名称
receiverBankCodeStringN收款方银行代码
remarksStringN备注
directionStringY方向(INCOMING/OUTGOING)
paymentReferenceStringN支付参考号
sourceStringY来源(SWIFT/SWIFTMX/FAST/MEPS/INTERNAL)
eventReferenceStringY事件参考号
accountNumberStringY账号
senderBankNameStringN付款方银行名称
masterAccountNoStringN主账户号,仅多币种账户适用;单币种报文不携带该字段

示例 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 调用结果查询接口确认状态,见幂等性。

通用问题和技术支持方式见常见问题。错误响应的口径见错误码。联系技术支持时请提供 traceId。

本页目录