错误与幂等性

统一的错误封装、稳定的错误码,以及真正能守住资金的幂等性。

尚未上线 —— api.baynoy.com 无法解析,下面的示例目前无法运行。这些结构已经定稿:现在就按它们开发,切换到正式密钥时无需任何改动。

One error envelope

Every non-2xx response carries {"error": {"code", "message", "details?"}}. Branch on code — it is a stable identifier. Never branch on message: messages are for humans and they change.

Node
try {
  await baynoy.payouts.create({ amount: 250000, currency: "EUR", beneficiary: "ben_123" },
    { idempotencyKey: key });
} catch (err) {
  switch (err.code) {
    case "insufficient_funds":       return showTopUp();
    case "beneficiary_cooldown":     return showCooldown(err.details.availableAt);
    case "idempotency_key_reused":   return; // already done — do nothing
    case "rate_limited":             return retryAfter(err.details.retryAfterMs);
    default: throw err;              // unknown codes are bugs, not flows
  }
}

Idempotency is not optional on money

Financial POSTs require an Idempotency-Key scoped to your account and endpoint. The same key with the same body returns the first result; the same key with a different body is a conflict. Generate the key before the first attempt and reuse it for every retry of that same intent.

cURL
curl https://api.baynoy.com/v1/payouts \\
  -H "Authorization: Bearer bk_test_..." \\
  -H "Idempotency-Key: 7c1f0b6e-..." \\
  -d amount=250000 -d currency=EUR -d beneficiary=ben_123

# same key + same body  -> the original result, no second payout
# same key + other body -> 409 idempotency_key_reused

Retries and rate limits

Retry 5xx and rate_limited with exponential backoff and jitter; never retry a 4xx other than rate_limited without changing something. Rate-limit responses carry the wait time in details — respect it rather than guessing.