跳转到主要内容
在将任何 VelaFi 集成从沙盒环境切换到生产环境之前,请逐项完成本页内容。通用部分适用于所有集成。最后一部分链接到各使用场景页面上的检查清单。 我们看到的大多数生产事故都源于三个缺口:Webhook 端点未按要求的格式确认推送、重试时未使用 clientId,以及没有对账任务来发现 Webhook 遗漏的内容。

凭证与认证

  • 将沙盒环境凭证与生产环境凭证分开管理。沙盒环境密钥由 VelaFi 提供,配合 https://api-test.velafi.com 使用。生产环境密钥在 API Management 页面创建,配合 https://api.velafi.com 使用。两套密钥不可互换。参见沙盒环境与生产环境密钥。
  • 将每台调用 API 的生产服务器的公网 IP 地址添加到密钥的 IP 白名单中(每个密钥最多 5 个地址,不支持 CIDR 网段)。没有白名单的密钥无法获取令牌(-1023),来自其他地址的调用会以 -2015(令牌请求)或 -2019(API 调用)失败。在迁移服务器或更改出口 IP 之前,请先更新白名单。
  • 将 API 密钥、API 私钥和令牌保存在您的服务器上。切勿将它们放入浏览器或移动端代码、日志或源代码管理中。
  • 缓存令牌,并在其 expireTime(Unix 毫秒)之前请求新令牌。如果调用返回 -1022,说明令牌已过期或无法识别:请获取新令牌并重新发送该调用。
  • 规划密钥轮换:创建新密钥,为其配置 IP 白名单,完成切换,然后删除旧密钥。参见安全最佳实践。

Webhook

Webhook 不会在沙盒环境中触发,因此生产环境是您的处理程序首次接收真实推送的地方。请仔细检查。
  • 为您使用的每种事件类型注册生产环境 Webhook:使用生产环境凭证调用创建 Webhook(POST /v2/webhook)。每种事件类型(ORDER_WEBHOOK、GLOBAL_PAYMENT_WEBHOOK、FUNDING_WEBHOOK、ON_RAMP_WITHDRAW_WEBHOOK、CRYPTO_WITHDRAW_WEBHOOK、STABLE_COIN_PAYMENT_WEBHOOK)都需要单独注册。在某事件类型没有有效 Webhook 期间发生的事件不会排队保留,因此请在首笔真实交易之前完成注册。
  • 保存每个 Webhook 的 publicKey,并在解析或重新序列化 JSON 之前,基于原始请求体字节验证 RSA-SHA256 signature 请求头。参见 Webhook 设置。
  • 对您接受的每次推送,以 HTTP 2xx 和完全相同的以下 JSON 响应体进行确认。 如果签名验证失败,请返回 {"callbackStatus":"FAIL"},以便该推送被重试。
任何其他响应都视为推送失败并会触发重试,即使您的系统已处理该事件。以下每一种都属于失败:
  • 纯文本 SUCCESS、success 或 OK
  • {"callbackStatus":"success"}(该值区分大小写)
  • {"received":true}、{"status":"ok"} 或任何不包含 "callbackStatus":"SUCCESS" 的其他 JSON
  • 空响应体,或在开头的 { 之前带有空白字符或字节顺序标记(BOM)的响应体
  • 您自己的错误 JSON,或任何非 2xx 状态码
  • 在推送超时前未响应
  • 快速响应。 验证签名、保存事件、返回确认,并异步执行耗时的工作(数据库更新、调用其他系统)。
  • 处理重复事件。 同一事件可能到达不止一次。请基于事件类型、记录 ID(orderId、txId 或 withdrawId)和状态实现幂等处理。
  • 不要依赖顺序,也不要指望看到每个状态。 推送可能乱序到达,当记录已进入后续状态时,中间状态可能被跳过。请将 Webhook 视为一个信号:通过相应的查询端点读取记录的当前状态,并据此采取行动。
  • 对 Webhook 遗漏的内容进行对账。 一次失败的推送总共会尝试 3 次(第二次约在第一次之后 5–10 分钟,第三次约在第二次之后 60–65 分钟)。之后该事件将被丢弃,且 API 没有重新推送的端点。请运行下文所述的对账任务。
  • 上线前测试处理程序的响应。 向您自己的端点发送示例负载,检查原始响应是否恰好为 {"callbackStatus":"SUCCESS"} 且状态码为 2xx。

使用 clientId 实现幂等性

在每个创建类调用中传入一个新的唯一 clientId,在发送请求前保存它,并在重试该请求时复用相同的值。VelaFi 会拒绝重复使用的 clientId,而不是创建第二条记录。重复请求的响应不会返回原记录,因此请自行查询。 clientId 会永久绑定到其记录,包括记录被取消之后。新的操作请使用新的值。 创建商户没有 clientId。重试之前,请通过获取商户列表(status=-1)按 email 查找该商户。

错误处理

  • 根据 code 字段而不是 HTTP 状态码进行分支处理。错误使用 HTTP 400(-1001 为 500),并带有负数 code(30012 除外)。不存在 401 或 429。参见错误码。
  • 在创建或变更类调用中,将 -1001、-1006、-1007 和 30012 视为结果未知。该操作可能已经完成。请通过 clientId 查询(见上表),仅在查不到时才使用相同的 clientId 重试。如果重试时返回 -1174,说明第一次请求已成功。
  • 不要匹配 msg。它可能包含运行时值和占位符。
  • 对于有速率限制的端点返回的 -1006 以及 30012(并发请求过多),请进行退避。
  • 对于失败的订单,请从获取订单中读取 failCode 和 failReason。failReason 可能为空,也可能包含服务商的原始文本,因此请记录日志,并根据订单状态进行处理。

对账

Webhook 是通知渠道,而不是您的账本。请运行定时任务,读取 VelaFi 最近几小时或几天的记录,并与您自己的记录进行比对。
  • 重新检查您系统中所有处于非最终状态的记录,以免因错过一条 Webhook 而让订单或出金在您这边永远处于待处理状态。
  • 对停留在非最终状态时间超过该支付通道预期的记录发出告警。
  • 每日对账余额:期初余额加上资金记录应等于期末余额。

限额

  • 通过获取商户列表检查每个商户的每日和每月限额及使用情况(dayFiatLimit、monthFiatLimit、monthCryptoLimit 以及对应的 ...Used 字段),并通过获取商户账户列表检查各渠道限额(monthBuyLimit、monthSellLimit)。
  • 处理限额错误:-5050 和 -5060(订单低于最低限额或高于最高限额),-5029、-5030 和 -5081(超出每月或每日限额)。
  • 如果预期交易量需要,请在上线前申请提升限额。参见交易限额。
  • 遵守报价和订单端点的速率限制。

监控

  • 记录每个请求和响应,并附上您的 clientId 和 VelaFi 的 ID(orderId、txId、withdrawId),以便追踪任意交易。
  • 对令牌失败(-1022、-1023、-2015、-2019)发出告警。它们通常意味着令牌已过期、密钥已被禁用或 IP 未加入白名单。
  • 当 Webhook 推送停止到达,或您的处理程序返回确认以外的任何内容时,发出告警。
  • 对错误率上升、结果未知错误码,以及停留在非最终状态的订单或出金发出告警。
  • 监控您用于付款的余额(法币余额用于出金和预先注资订单,加密货币余额用于加密货币兑法币出金订单),以免出金因资金不足而失败。

按使用场景

每个使用场景页面末尾都有针对该流程的检查清单。请为您上线的每个流程完成对应的清单:

使用虚拟账户收款

每个付款人一个虚拟账户、FUNDING_WEBHOOK 处理、按 depositAlias 匹配充值。

从余额出金

收款人、余额与手续费检查、出金状态跟踪。

兑换为稳定币

预先注资或按单付款的入金订单、报价、过期处理。

以稳定币注资出金

出金订单、加密货币余额、出金失败与退款。

客户入驻

商户创建、验证状态、渠道激活。

跨境支付

使用 GLOBAL_PAYMENT_WEBHOOK 的法币兑法币订单。