開発者/はじめに

共通ルール

7つのエンドポイントすべてに共通するルールです。

関連ドキュメント:認証 · 商品と注文 · README

#リクエスト

  • ベース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 IDM00000001変わることはありません。
SKU IDS000456価格の確認と注文に使います。
商品IDP000123SKUが属する商品のIDです。
CardVの注文IDO-00001234注文の照会に使います。
自社の注文番号SHOP-10001external_order_id。1~120文字で、重複は不可です。
  • IDは文字列として保存し、中身を解析しないでください。将来、桁数が増える可能性があります。
  • 注文には数値の id もありますが、使わないでください。order_id を使ってください。
  • 自社の注文番号には A–Z a–z 0–9 - _ . だけを使ってください。

#ページング

ページングがあるのは GET/skus だけです。limit と offset を指定します。

HTTP
GET /api/v1/skus?limit=100&offset=200
JSON
{"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 ヘッダー(待つべき秒数)が返ります。

    JSON
    {"detail": "Merchant API rate limit exceeded. Expected available in 23 seconds."}
  • 上限を超えないためには、SKU一覧をキャッシュする、短い間隔でのポーリングではなくWebhookを使う、 429が返るたびに待ち時間を少しずつ長くする、といった工夫をしてください。

#エラー

まずHTTPステータスを確認し、次にJSONの本文を読みます。何が問題だったかは、本文のキーでわかります。メッセージの文言には依存しないでください。

認証、権限、未検出、レート制限のエラーは detail で返ります。

JSON
{"detail": "Order not found."}

注文と見積もりのエラーは、問題のあったフィールド名で返ります。

JSON
{"balance": "Insufficient available balance."}

注文明細の形式が正しくない場合は、明細ごとにエラーが返ります。並び順は送信した items と同じです。

JSON
{"items": [{}, {"quantity": ["Ensure this value is greater than or equal to 1."]}]}
キー発生する場所対処
detailすべて下のステータスコード一覧を参照してください。
itemsPOST/orders明細を修正してください。価格が変わった場合は、もう一度見積もりを取ってください。
balancePOST/ordersPortalで入金してください。
riskPOST/orders注文の上限に達しました。CardVにお問い合わせください。
external_order_idPOST/orders自社の注文番号がない、長すぎる、または別の注文で使用済みです。
walletPOST/orders有効なウォレットがありません。CardVにお問い合わせください。
quantity, amount見積もり範囲外か、数値ではありません。
limit, offsetGET/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] までお問い合わせください。