开发者

三次调用,一个 webhook。

Gateway 是托管式 checkout,因此集成刻意保持精简:创建订单,将客户引导至支付页,验证签名结果。以下就是全部接入面——支付界面、支付方式逻辑、3-D Secure、钱包和收据,均由我们构建并持续维护。

概览

你要对接的是什么。

  • 基于 HTTPS 的 REST
  • JSON 进,JSON 出
  • Bearer API 密钥
  • 幂等键
  • 签名 webhook
  • 重放保护
  • 测试与生产模式
  • iOS 与 Android SDK
  • 商店插件
  • 嵌入式字段

快速开始

从零到订单支付成功。

完整的顺利路径。金额以最小货币单位计,reference 由你自定,checkout URL 就是客户要跳转的地址。API 基础地址随沙箱密钥一同发放——将其导出为 PROTOCORE_API_BASE,下面的调用即可原样运行。

01

创建订单

一次调用,传入金额、币种和你自己的 reference。幂等键由你生成——重试的请求会返回原订单,而不会创建第二个。

POST /v1/orders
curl -X POST "$PROTOCORE_API_BASE/v1/orders" \
  -H "Authorization: Bearer $PROTOCORE_API_KEY" \
  -H "Idempotency-Key: 9F21-0716" \
  -H "Content-Type: application/json" \
  -d '{
        "amount": 4900,
        "currency": "EUR",
        "reference": "9F21-0716",
        "line_items": [
          { "name": "Brand identity sprint", "amount": 3850 },
          { "name": "Typeface licensing",   "amount": 600 },
          { "name": "Rush delivery",        "amount": 400 }
        ],
        "return_url": "https://arcstudio.ro/thanks"
      }'
02

将客户引导至 checkout

响应中带有一个位于你专属 checkout 域名上的 checkout URL——沙箱随附的域名,或在你将自有域名指向我们之后使用的域名。直接重定向,或在 SDK 中打开;支付方式、钱包和 3-D Secure 都在该页面内,你这边无需开发任何内容。

201 Created
{
  "id": "ord_2h4Kq9wRz",
  "reference": "9F21-0716",
  "amount": 4900,
  "currency": "EUR",
  "status": "pending",
  "checkout_url": "https://<your-checkout-host>/c/2h4Kq9wRz"
}
03

验证签名结果

支付完成后,一个已签名的事件会发送到你的端点。在信任任何内容之前,先用 webhook 密钥校验签名,然后根据你已掌握的 reference 履约。

POST /your/webhook — order.paid
{
  "type": "order.paid",
  "id": "evt_7Ka2Lm",
  "created": "2026-07-23T09:41:02Z",
  "data": {
    "id": "ord_2h4Kq9wRz",
    "reference": "9F21-0716",
    "amount": 4900,
    "currency": "EUR",
    "method": "usdc",
    "settlement": { "currency": "EUR", "amount": 4900, "rate": "0.9184" }
  }
}

参考

你真正会用到的端点。

文档里还有更多,但大多数集成用不到这个范围之外。

POST /v1/orders
创建订单并获取其 checkout URL。需传入幂等键。
GET /v1/orders/:id
订单的当前状态——状态、支付方式、结算和退款。
POST /v1/orders/:id/refunds
针对订单退款,可全额或部分,必须填写原因。
POST /v1/orders/:id/void
在结算前释放授权,因此不会有任何资金流动。
POST /v1/links
创建支付链接——一次性或可重复收款,可设置有效期。
GET /v1/payouts/:id
一个结算批次及为其提供资金的订单,费用逐项列明。
POST /v1/customers/:id/cards
将银行卡存入保险库,用于一键支付和周期性扣款;返回令牌引用。
POST /v1/subscriptions
按计划对已存卡扣款;每个周期生成各自的订单。

Webhook

你的后端会收到哪些通知。

每个事件都带有你创建的订单 reference,因此你的处理程序只需按类型做 switch,再在自己一侧查询即可。

order.paid
授权与扣款成功——据 reference 履约。
order.failed
支付未完成,并附带运营人员可据以处理的原因。
order.refunded
已发起退款,全额或部分,附原因与备注。
order.disputed
已发起拒付,相关证据已附在订单上。
payout.settled
一个结算批次已发往你的账户,并列出其中包含的订单。
subscription.charged
一个周期性扣款周期生成了自己的订单和收据。
验证

先验签,再信任请求体。

每次推送都带有时间戳和针对原始请求体的 HMAC 签名。请以恒定时间比较,拒绝超出容差窗口的旧请求,并将重复的事件 id 视为已处理——收到非 2xx 响应时我们会重试,因此你的处理程序也应保持幂等。

Node — 签名验证
import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody, header, secret) {
  const [ts, sig] = header.split(",").map((p) => p.split("=")[1]);
  const expected = createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`)
    .digest("hex");

  const a = Buffer.from(sig, "hex");
  const b = Buffer.from(expected, "hex");
  if (a.length !== b.length || !timingSafeEqual(a, b)) return false;

  // Reject replays outside a five-minute window.
  return Math.abs(Date.now() / 1000 - Number(ts)) < 300;
}

保障

可以放心依赖的特性。

01

幂等创建

每次创建订单都需传入幂等键。无论因超时、部署还是队列重新投递而重试,请求都会返回原订单,而不会重复扣款。

02

签名、防重放的事件

Webhook 带有含时间戳的 HMAC 签名和稳定的事件 id。推送会按退避策略重试,直到你的端点返回 2xx,因此部署窗口期不会丢失任何一笔支付。

03

一个 reference,贯穿始终

你在创建时提供的 reference 会出现在 checkout、收据、webhook、出款以及之后的任何退款中。系统之间无需再映射第二个标识符。

04

测试模式走的是同一条代码路径

测试密钥在测试会话上运行完全相同的流程。测试中通过的,就是上线的——区别只在于你发送哪套密钥,而不是调用哪些端点。

测试数据

如何覆盖关键路径。

以下每条路径都对应一张测试卡,卡号会在沙箱开通时随密钥一并提供。卡号按沙箱单独生成,不在此公开,以便在卡组织调整测试号段时始终保持有效。无论哪种情况,行为都是确定的:断言拒付与断言成功一样简单。

直接通过
无需 3-D Secure 验证即可授权并请款——理想路径。
3-D Secure 验证
强制触发可操作的验证流程,方便你测试回跳环节。
软拒付
因余额不足被拒绝,随后通过备用路由重试。
硬拒付
因卡片过期被永久拒绝,不会重试。
USDC 测试网络
Ethereum、Base 和 Solana 上的测试网 USDC,按固定汇率计价。
转账模拟
将测试 vIBAN 转账标记为已到账,订单即变为已支付。

获取密钥,立即开始。

一个沙箱商户,附带 API 密钥、webhook 密钥,并开启所有支付方式——另有完整的参考文档,让你的团队在签约之前就能开始集成。