NeoLinks
ProductsPricingDocsBlogAbout
Sign in
NeoLinks API Docs
  • 平台概览
  • 环境与 Base URL
  • 认证
  • 通用响应格式
  • 幂等与金额单位
  • 收单 Acquiring
  • — 创建收单发票
  • — 查询 / 关单
  • 虚拟账户 VA
  • 收款 Collection
  • 付款 Payout
  • 兑换 Exchange
  • 充值 Deposits
  • 余额 Balances
  • 稳定币收单
  • 法币收单
  • 开通 Capability
  • Webhook 事件
  • — 签名验证
  • 错误码表
  • 本地联调
  • 更新日志

快速上手

NeoLinks 商户 BFF 覆盖收单、收款、付款、法币换汇与账户。当前对外契约是 /api/merchant/v1,鉴权为登录会话 Bearer。Partner HMAC 尚未开放。

🔗

Merchant BFF

Bearer 会话鉴权,RESTful JSON,路径以 api/merchant.openapi.yaml 为准。

🏦

虚拟账户 VA

法币收单 / 收款走 stub VA,响应只回掩码账号与附言,不回完整账号。

⛓️

稳定币链上

Vault 收单、Scanner 入账 crypto_inbounds,清算不得记成充值。

能力总览

📄
收单 Acquiring发票 /acquiring/invoices,CRYPTO Vault + FIAT VA
💰
收款 Collection/collection/orders,CRYPTO 地址或 FIAT 掩码 VA
📤
付款 Payout必须引用已核验 payee;rail=CRYPTO 或 BANK
🔄
兑换 Exchange已开通类型 stub 询价再下单,扣 TREASURY
🏛️
虚拟账户 VA开通后分配;建单返回掩码与 fiat_payment_ref
🔔
Webhook本环境只推送三条收单事件
架构原则:热路径门禁认细 Behavior(type + status=active)。客户链上支付写入 crypto_inbounds,匹配后完结订单;Vault→清算不得记为商户充值。金额:稳定币 amount_minor 为 1e6,法币为分。

环境与 Base URL

对外商户 API 挂在官网同源路径下。下文接口路径均相对此 Base URL;本地联调见「本地联调」。

环境Base URL说明
Production https://neolinks.io/api/merchant/v1 官网 neolinks.io 同源;门户与集成均用此地址

认证

先 POST /auth/login 拿会话 token,之后请求带 Authorization: Bearer <token>。写接口另需对应 mch:* 权限。

请求头

Header类型说明
Authorization必填 string Bearer 后接登录返回的 token
Idempotency-Key可选 string 收单建票可选;同一 key + 不同 body 返回 CONFLICT
X-2FA-Challenge-Token可选 string 付款 / 兑换下单在开启 2FA 时必填
cURL 示例
curl -X POST "https://neolinks.io/api/merchant/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"password1"}'

curl -X POST "https://neolinks.io/api/merchant/v1/acquiring/invoices" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: inv-001" \
  -d '{"amount_due_minor":100000000,"currency":"USDC","payment_rail":"CRYPTO","chain_id":31337}'
注意:商户门户 BFF 只认登录会话。用 API Key 当 Bearer 会 401。开通 Partner API 后,公开前缀 /api/partner/v1 使用 Partner HMAC(X-Api-Key + HMAC)。

通用响应格式

成功时 HTTP 2xx 且 code = 0(整数)。错误时 HTTP 4xx/5xx,code 为字符串错误码。

Success Response
{
  "code": 0,
  "message": "ok",
  "data": { /* 业务对象 */ },
  "trace_id": "tr_abc123",
  "request_id": "req_xyz789"
}
Error Response
{
  "code": "GATE_DENIED",
  "message": "no active ACQUIRING_CRYPTO behavior",
  "trace_id": "tr_abc123",
  "request_id": "req_xyz789"
}

幂等与金额单位

幂等

字段范围说明
Idempotency-Key收单建票可选;冲突且 body 不同 → 409 CONFLICT

金额单位

资产amount_*_minor说明
USDC / USDT1e6必须带已登记 chain_id;100 USDC = 100000000
USD / EUR / HKD分(×100)不得带 chain_id;50.00 USD = 5000

收单 Acquiring

资源名为发票 /acquiring/invoices(/acquiring/orders 为同处理器别名)。建单前须有对应 active Behavior(CRYPTO 或 FIAT)。

订单状态

状态说明
AWAITING_PAYMENT已分配 Vault / 掩码 VA,等待付款
PAYMENT_DETECTED已匹配入账、尚未完结
COMPLETED足额匹配且结算完结
CANCELLED / EXPIRED关单或过期
POST /api/merchant/v1/acquiring/invoices

创建收单发票。成功 201。CRYPTO 返回 pay_address / pay_contract / order_ref;FIAT 返回掩码 VA 与 fiat_payment_ref。

Request Body

参数类型说明
amount_due_minor必填 integer 应付最小单位。也可用展示字段 amount
currency必填 string USDC / USDT 或 USD / EUR / HKD
payment_rail可选 enum 省略或 CRYPTO;法币必须显式 FIAT
chain_idCRYPTO 必填 integer 已登记链。本地 31337。FIAT 禁止携带
Request — Crypto
{
  "amount_due_minor": 100000000,
  "currency": "USDC",
  "payment_rail": "CRYPTO",
  "chain_id": 31337
}
Response 201
{
  "code": 0,
  "message": "ok",
  "data": {
    "id": "ao_...",
    "status": "AWAITING_PAYMENT",
    "amount": "100.000000",
    "amount_due_minor": 100000000,
    "currency": "USDC",
    "payment_rail": "CRYPTO",
    "pay_address": "0x...",
    "pay_contract": "0x...",
    "order_ref": "0x...",
    "chain_id": 31337,
    "company_id": "co_...",
    "behavior_id": "beh_..."
  }
}
GET /api/merchant/v1/acquiring/invoices/{id}

查询本公司发票。跨公司 id 返回 404。列表:GET /acquiring/invoices。

POST /api/merchant/v1/acquiring/invoices/{id}/close

关闭未完结发票。已 COMPLETED 不可关。

虚拟账户 Virtual Account

法币收单 / 收款使用 VA。创建时必须 payment_rail: "FIAT",且该币种 Capability 已开通。响应永不返回完整账号。

FIAT 发票字段

字段类型说明
fiat_account_maskedstring掩码账号(与 fiat_va_masked 同值)
fiat_payment_refstring付款附言,银行转账须原样填写
payment_railstringFIAT
Request — Fiat
{
  "amount_due_minor": 500000,
  "currency": "USD",
  "payment_rail": "FIAT"
}
请求体若带 own_account_id 或完整 account_number → 400。开发阶段银行入账为 stub,不是真实通道。

收款 Collection

独立收款单,不是收单发票。CRYPTO 分配地址;FIAT 返回掩码 VA。客户支付匹配入 crypto_inbounds / fiat_inbounds,不是充值。

POST /api/merchant/v1/collection/orders

创建收款单。成功 201。

Request Body

参数类型说明
amount_due_minor必填integer期望金额(最小单位)
currency必填stringCRYPTO:USDC/USDT;FIAT:USD/EUR/HKD
payment_rail可选enumCRYPTO | FIAT(法币必须显式 FIAT)
chain_idCRYPTO 必填integer已登记链。本地 31337。FIAT 禁止携带
reference_no可选string商户参考号
GET /api/merchant/v1/collection/orders/{id}

详情含 pay_address(CRYPTO)或 fiat_va_masked(FIAT)。关单:POST …/cancel。

POST /api/merchant/v1/collection/orders/{id}/payment-tx

CRYPTO:绑定付款方链上交易哈希(payment_tx_hash 或 tx_hash),触发匹配。成功 200;状态不允许或哈希冲突 → 409。

GET /api/merchant/v1/collection/orders/{id}/documents

列出贸易材料。需先 POST /uploads 拿到 file_id。

POST /api/merchant/v1/collection/orders/{id}/documents

挂载材料。成功 201。待审状态可在详情页补传(含 COMPLETED)。

Request Body

参数类型说明
file_name必填string文件名
file_id必填string上传接口返回的 file_id
document_type可选string默认 COLLECTION_SUPPORTING
DELETE /api/merchant/v1/collection/orders/{id}/documents/{document_id}

仅 PENDING_OPS 可删;已审材料 → 409。

付款 Payout

对手必须是本公司已核验 payees(purpose=PAYOUT)。禁止手填地址/账号。CRYPTO 扣 TREASURY 并进入材料审核;BANK 无 chain_id。

POST /api/merchant/v1/payout/orders

Request Body

参数类型说明
payee_account_id必填string已 VERIFIED 的付款对手 id
amount_minor必填integer付款金额(最小单位)
currency必填stringCRYPTO:USDC/USDT;FIAT:USD/EUR/HKD
rail可选enum省略/CRYPTO 或显式 BANK
chain_idCRYPTO 必填integerCRYPTO 必填;BANK 禁止
Request
{
  "payee_account_id": "pae_...",
  "amount_minor": 100000000,
  "currency": "USDC",
  "rail": "CRYPTO",
  "chain_id": 31337
}

不存在可写的 …/execute、…/finalize、…/batch。

兑换 Exchange

已开通的 FIAT_FX / CRYPTO_SWAP / ONRAMP / OFFRAMP 走 stub 询价再下单。扣款户只能是 TREASURY。未开通或已停用的类型返回 403 GATE_DENIED。source_amount_minor / target_amount_minor 按各币种最小单位;跨法币↔稳定币时目标金额会按汇率并换算 scale(法币×100,稳定币×1e6)。

POST /api/merchant/v1/exchange/quotes

锁定汇率,成功 201。需要 mch:exchange:quote。

Request Body

参数类型说明
exchange_type必填stringFIAT_FX / CRYPTO_SWAP / ONRAMP / OFFRAMP
source_currency必填string卖出币种
target_currency必填string买入币种
source_amount_minor必填integer卖出金额(源币种最小单位:法币×100,稳定币×1e6)
POST /api/merchant/v1/exchange/orders

用 quote_id 成交,成功 201 COMPLETED。需要 mch:exchange:create。没有 …/execute。

充值 Deposits

GET /deposits 只表示真实充值。客户付到 Vault、Vault→清算都不是充值,不会出现在此列表。

GET /api/merchant/v1/deposits

分页。收单流水请看 /acquiring/transactions 或发票详情。

余额 Balances

按业务账户查询可用余额。query business_account:ACQUIRING / COLLECTION / TREASURY / EXCHANGE。

GET /api/merchant/v1/account/balances

例:?business_account=TREASURY

稳定币收单

开通 ACQUIRING_CRYPTO 后建 CRYPTO 发票。付款方对 Vault 调用 pay(orderRef, amount)。Scanner 写入 crypto_inbounds 并匹配订单。

  • 匹配成功 → inbound MATCHED,订单离开纯待付
  • Vault→清算完结订单,禁止记两条假充值
  • 本地 Anvil chain_id=31337

法币收单

先开通 ACQUIRING_FIAT(按币种 scope)。建单必须显式 payment_rail=FIAT,且 currency 为 USD/EUR/HKD。

  • 响应只有掩码账号与 fiat_payment_ref
  • 入账通道默认 stub,不阻塞功能验收
  • 本环境 Webhook 不含法币超额 / 充值入账事件

开通 Capability

无对应 active 细 Behavior 时建单 403 GATE_DENIED。KYB 须 APPROVED。

POST说明
/capabilities/acquiring-crypto/activateACQUIRING_CRYPTO
/capabilities/partner-api/activatePARTNER_API
/capabilities/acquiring-fiat/activateACQUIRING_FIAT,按币种
/capabilities/collection-crypto/activateCOLLECTION_CRYPTO
/capabilities/collection-fiat/activateCOLLECTION_FIAT
/capabilities/payout-crypto/activatePAYOUT_CRYPTO
/capabilities/payout-bank/activatePAYOUT_BANK
/capabilities/exchange/activatebody: exchange_type=FIAT_FX

Webhook 事件

在门户「设置 → Webhook」或 PATCH /integration/webhook 配置 URL。本环境只投递下列三条收单事件。

本环境已推送

事件触发时机
acquiring.order.awaiting_payment建票成功且已有付款地址
acquiring.order.payment_detected订单进入 PAYMENT_DETECTED
acquiring.order.completed订单 COMPLETED

不投递:收款 / 付款 / 兑换、deposit_credited、法币超额、KYT 失败。

Webhook Payload
{
  "event": "acquiring.order.completed",
  "id": "ao_...",
  "status": "COMPLETED",
  "amount_due_minor": 100000000,
  "currency": "USDC",
  "order_ref": "0x..."
}

签名验证

首次保存配置会返回一次明文 secret。签名:

Header说明
X-Webhook-Signaturesha256= + hex(HMAC-SHA256(secret, timestamp + "\n" + rawBody))
X-Webhook-TimestampRFC3339 UTC

接收方返回 HTTP 2xx 视为成功。轮换密钥:POST /integration/webhook/rotate。

错误码

codeHTTP说明
02xx成功(整数)
INVALID_REQUEST400参数错误
UNAUTHORIZED401未登录或 token 无效
FORBIDDEN403缺少 mch:* 权限
GATE_DENIED403无 active Behavior 或 KYB 未批
TENANT_MISMATCH403body/query 的 company_id 不属于本会话
TWO_FA_REQUIRED403需要 X-2FA-Challenge-Token
EXCHANGE_TYPE_UNSUPPORTED403未知兑换类型
EXCHANGE_DEBIT_FORBIDDEN400兑换扣款户不是 TREASURY
INSUFFICIENT400可用余额不足
NOT_FOUND404资源不存在或不属于本公司
CONFLICT409幂等冲突、重复或状态不允许
INTERNAL_ERROR500内部错误

本地联调

在 neolinks-core 仓库启动 Docker API 与商户门户即可对照本文档调接口。

  1. make up && make up-app-skip-build && make web-restart
  2. POST /auth/login 获取 Bearer token
  3. 确认 KYB APPROVED 且已开通对应 Capability
  4. 创建 CRYPTO 发票,用 Anvil 钱包向 Vault 支付
  5. PATCH /integration/webhook 后观察三条收单事件
Local E2E (Anvil)
# neolinks-core 仓库
make up                 # Postgres + Redis
make up-anvil           # 本地链 RPC :8545
make up-app-skip-build  # Docker API :8080
make web-restart        # 商户 :3000 / 运营 :3001

更新日志

版本日期变更
Merchant BFF 0.22026-09收款材料 documents;兑换跨法币/稳定币 minor scale;账户多 BA 同链余额聚合
Merchant BFF 0.12026-08对齐 /api/merchant/v1:Bearer、amount_minor、payment_rail、三条 Webhook;废止 Partner HMAC 文档

联系方式

NeoLinks Payments

neolinks.io

商务合作

[email protected]

企业接入与定制方案

技术支持

[email protected]

集成问题与本地联调

© 2026 NeoLinks. Merchant BFF · OpenAPI SSOT: api/merchant.openapi.yaml