開発者/はじめに
共通ルール
7つのエンドポイントすべてに共通するルールです。
#リクエスト
- ベースURL:
https://b2b.cardv.net/api/v1(Live)、https://sandbox.cardv.net/api/v1(Sandbox) - パスの末尾にスラッシュは付けません。
/api/v1/orders/ではなく/api/v1/ordersを使ってください。 - JSONの本文はUTF-8で、
Content-Type: application/jsonを付けて送ります。 - 金額は
"9.2500"のように文字列で送ります。丸め誤差を防ぐためです。 AcmeShop-CardV/1.4のように、送信元がわかるUser-Agentを設定してください。
#金額と日時
- 金額は小数点以下4桁の文字列です。例:
"merchant_price": "9.2500" - 金額は必ず10進数型(Decimalなど)で扱い、浮動小数点数は使わないでください。
- 支払いはウォレットの通貨で行います(
GET/accountのdefault_currency。現在はUSD)。 face_currencyはカードに記載されている通貨です。ウォレットの通貨と異なる場合があります。- 仕入れ価格の計算には必ず
merchant_priceを使ってください。price_labelなどのラベルは表示専用です。 - 日時はすべてUTCで、ISO 8601形式です。例:
2026-09-29T08:15:30.123456Z - 日時の解析には、正式なISO 8601パーサーを使ってください。秒の小数点以下の桁数は一定ではありません。
- 署名に使う
X-TimestampはUnix時間(秒)です。
#ID
| 種類 | 例 | 補足 |
|---|---|---|
| Merchant ID | M00000001 | 変わることはありません。 |
| SKU ID | S000456 | 価格の確認と注文に使います。 |
| 商品ID | P000123 | SKUが属する商品のIDです。 |
| CardVの注文ID | O-00001234 | 注文の照会に使います。 |
| 自社の注文番号 | SHOP-10001 | external_order_id。1~120文字で、重複は不可です。 |
- IDは文字列として保存し、中身を解析しないでください。将来、桁数が増える可能性があります。
- 注文には数値の
idもありますが、使わないでください。order_idを使ってください。 - 自社の注文番号には
A–Z a–z 0–9 - _ .だけを使ってください。
#ページング
ページングがあるのは GET/skus だけです。limit と offset を指定します。
GET /api/v1/skus?limit=100&offset=200{"count": 1234, "limit": 100, "results": ["..."], "filter_options": {}}limitの初期値は100、上限は500です。500を超える値は500として扱われます。countは条件に合う件数の合計です。offsetがcountに達するまで取得を続けてください。limitやoffsetに負の数や数値以外を指定すると、HTTP 400が返ります。- 存在しない絞り込み条件を指定した場合は、エラーではなく空の一覧が返ります。
#レート制限
初期値は、アカウント全体で1分あたり60リクエストです。すべてのAPIキーとPortalユーザーでこの上限を共有します。契約プランによっては上限が異なります。
1分の区切りは、時計の
:00秒から始まります。拒否されたリクエストも回数に含まれます。上限を超えると、HTTP 429と
Retry-Afterヘッダー(待つべき秒数)が返ります。{"detail": "Merchant API rate limit exceeded. Expected available in 23 seconds."}上限を超えないためには、SKU一覧をキャッシュする、短い間隔でのポーリングではなくWebhookを使う、 429が返るたびに待ち時間を少しずつ長くする、といった工夫をしてください。
#エラー
まずHTTPステータスを確認し、次にJSONの本文を読みます。何が問題だったかは、本文のキーでわかります。メッセージの文言には依存しないでください。
認証、権限、未検出、レート制限のエラーは detail で返ります。
{"detail": "Order not found."}注文と見積もりのエラーは、問題のあったフィールド名で返ります。
{"balance": "Insufficient available balance."}注文明細の形式が正しくない場合は、明細ごとにエラーが返ります。並び順は送信した items と同じです。
{"items": [{}, {"quantity": ["Ensure this value is greater than or equal to 1."]}]}| キー | 発生する場所 | 対処 |
|---|---|---|
detail | すべて | 下のステータスコード一覧を参照してください。 |
items | POST/orders | 明細を修正してください。価格が変わった場合は、もう一度見積もりを取ってください。 |
balance | POST/orders | Portalで入金してください。 |
risk | POST/orders | 注文の上限に達しました。CardVにお問い合わせください。 |
external_order_id | POST/orders | 自社の注文番号がない、長すぎる、または別の注文で使用済みです。 |
wallet | POST/orders | 有効なウォレットがありません。CardVにお問い合わせください。 |
quantity, amount | 見積もり | 範囲外か、数値ではありません。 |
limit, offset | GET/skus | 正しい数値ではありません。 |
一部のエラーはJSON以外の形式で返ります。
error code: 1010のようなプレーンテキストのHTTP 403は、CardVのネットワークの入口で返されたものです。リクエストはCardVのサーバーに届いていません。貴社サーバーのIPアドレスとUser-AgentをCardVにお知らせください。- 存在しないパス(404)やプロキシのエラー(5xx)では、HTMLが返ることがあります。
エラーをログに記録するときも、APIキー、署名、コードは絶対に記録しないでください。
#HTTPステータスコード
| ステータス | 意味 | 再試行 |
|---|---|---|
| 200 | 成功。POST/orders の場合は、その注文がすでに存在していたことを示します。 | 不要 |
| 201 | 新しい注文が作成されました。 | 不要 |
| 400 | リクエストが拒否されました。代金は引き落とされていません。 | 修正してから |
| 403 | 認証情報、署名、IPアドレス、またはPortal専用のエンドポイントの問題です。 | 修正してから |
| 404 | 見つからないか、貴社のアカウントでは利用できません。 | しない |
| 405 | このパスでは使えないメソッドです。 | しない |
| 429 | リクエストが多すぎます。 | Retry-After の後に |
| 5xxまたはタイムアウト | サーバーまたはネットワークの問題です。注文が作成されている可能性があります。 | する(下記参照) |
POST/orders を再試行するときは、本文と自社の注文番号を必ず同じにしてください。詳しくは安全な再送の手順をご覧ください。
#レスポンス
brand_logo_urlとimage_urlは、CardVが提供する画像の完全なURL、または""です。公開されている画像なので、キャッシュして構いません。- 注文の
invoice_urlとdelivery_file_urlは/orders/O-00001234/invoiceのようなパス、またはまだ何もない場合は""です。これらはPortal専用で、APIキーで呼び出すとHTTP 403が返ります。請求書やコードのCSVファイルはPortalで開いてください。
#互換性
- 知らないフィールドは無視してください。CardVはAPIのバージョンを変えずにフィールドを追加します。
- 新しいステータスの値が追加されることがあります。知らないステータスは「まだ完了していない」ものとして扱ってください。
- JSONのキーの順番やメッセージの文言には依存しないでください。
連携についてご不明な点は、Merchant ID と注文 ID またはリクエスト ID を添えて [email protected] までお問い合わせください。