開発者/連携

モバイルチャージ

モバイルチャージは、プリペイド式の携帯電話番号に直接チャージする機能です。エンドユーザーの回線に通話料やデータ通信量が追加されます。渡すコードはありません。ほかの注文と同じく、代金はCardVのウォレットから支払われます。

関連ドキュメント:認証 · 共通ルール · Webhook

#全体の流れ

Text
GET  /recharge/countries            チャージできる国
GET  /recharge/operators?country=US  通信事業者、チャージの種類と金額
POST /recharge/quote                貴社の価格と、300秒間有効な quote_token
POST /recharge/orders               注文(ウォレットから支払い)
GET  /recharge/orders/{order_id}    ステータスを照会、またはWebhookを待つ
  • パスはすべて /api/v1 から始まります。ヘッダーはほかの呼び出しと同じものを送ります。
  • 2つの POST の呼び出しには署名が必要です。署名の方法は POST/orders と同じですが、パスはそれぞれのものを使います。例:/api/v1/recharge/quote
  • チャージの注文はギフトカードの注文とは別に管理されます。照会には /recharge のエンドポイントを使ってください。
  • 提供しているのは直接チャージだけです。PIN型の商品(エンドユーザーがコードを入力するもの)は対象外です。

#国

GET/api/v1/recharge/countries で、現在チャージできる国の一覧を取得します。

JSON
{
  "count": 2,
  "results": [
    {"code": "MX", "name": "Mexico", "currency_codes": ["MXN"], "operator_count": 4, "offer_count": 37},
    {"code": "US", "name": "United States", "currency_codes": ["USD"], "operator_count": 6, "offer_count": 52}
  ]
}
  • code はISO 3166-1 alpha-2の国コードです。以降の呼び出しでは country として送ります。
  • currency_codes は、その国の通信事業者が販売に使う現地通貨です。
  • 通信事業者の追加や停止に合わせて一覧は変わります。数時間ごとに取得し直してください。

#通信事業者

GET/api/v1/recharge/operators?country=US で、1つの国の通信事業者の一覧を取得します。 search=att を付けると、事業者名で絞り込めます。

JSON
{
  "count": 1,
  "results": [
    {
      "operator_key": "us-att",
      "name": "AT&T",
      "country": "US",
      "country_name": "United States",
      "logo_url": "https://b2b.cardv.net/api/v1/catalog-assets/3f5c...a1.png",
      "subtypes": ["airtime", "data"],
      "amount_model": "range",
      "currency_codes": ["USD"],
      "amounts": [
        {"min": "5.0000", "max": "100.0000", "currency": "USD", "subtype": "airtime", "label": "5.0000-100.0000 USD"},
        {"min": "15.0000", "max": "15.0000", "currency": "USD", "subtype": "data", "label": "15.0000 USD"}
      ],
      "offer_count": 3
    }
  ]
}
フィールド意味
operator_key見積もりと注文で送るIDです。例:us-att。文字列として保存してください。
subtypes購入できる種類:airtime(通話料)、data(データ通信)、bundle(通話とデータのセット)。
amount_modelすべての金額が固定値なら fixed、1つでも範囲指定があれば range です。
amounts[]選べる金額です。min と max が同じなら固定額、違う場合はその範囲内の任意の金額です。
amounts[].currencyその選択肢の現地通貨です。local_currency として送ります。
logo_urlCardVが配信する画像です。ない場合は "" です。
  • 金額は現地金額です。つまり、携帯電話の回線に実際にチャージされる、現地通貨での金額です。
  • country が存在しない、または形式が正しくない場合は、HTTP 400が返ります。

#見積もり

POST/api/v1/recharge/quote で、1回のチャージの価格がわかります。この呼び出しには署名が必要です。

JSON
{
  "country": "US",
  "operator_key": "us-att",
  "amount": "10.00",
  "local_currency": "USD",
  "subtype": "airtime"
}
フィールド必須意味
country必須国の一覧にある国コードです。
operator_key必須通信事業者の一覧から取得します。
amount必須現地金額を文字列で指定します。固定額:一覧にある値のいずれか。範囲指定:min から max の間。
local_currency推奨amount のISO 4217通貨コードで、amounts[].currency の値です。通信事業者が複数の通貨を扱う場合は必ず送ってください。
subtype任意airtime(初期値)、data、bundle のいずれかです。

レスポンス:

JSON
{
  "country": "US",
  "country_name": "United States",
  "operator": {"operator_key": "us-att", "name": "AT&T", "logo_url": ""},
  "subtype": "airtime",
  "local_amount": "10.0000",
  "local_currency": "USD",
  "merchant_price": "9.6200",
  "merchant_currency": "USD",
  "expires_at": "2026-09-30T08:20:30.123456+00:00",
  "quote_token": "eyJ2ZXJzaW9uIjox...:1uXyZa:8c1f..."
}
  • merchant_price は、ウォレットから支払われる金額です。通貨は merchant_currency です。
  • quote_token は、expires_at までの 300秒間 この価格を確定させます。注文時にそのまま送ってください。
  • このトークンは、貴社のアカウントと、今回の国、通信事業者、種類、金額に結び付いています。
  • 注文する前に、local_currency が想定どおりの通貨か確認してください。
  • 見積もりでは資金は確保されません。見積もりはいつでも取り直せます。

#チャージを注文する

POST/api/v1/recharge/orders で携帯電話にチャージし、ウォレットから支払います。この呼び出しには署名が必要です。

JSON
{
  "external_order_id": "SHOP-RC-20260930-0001",
  "country": "US",
  "operator_key": "us-att",
  "amount": "10.00",
  "local_currency": "USD",
  "subtype": "airtime",
  "account": "12125550100",
  "quote_token": "eyJ2ZXJzaW9uIjox...:1uXyZa:8c1f..."
}
フィールド必須意味
external_order_id必須自社の注文番号です。ギフトカードの注文も含め、すべての注文で重複は不可です。
country, operator_key, amount, local_currency, subtype必須見積もりで送ったものと同じ値です。
account必須チャージする電話番号です。国番号付きの数字のみで、+ や空白は入れません。
quote_token必須見積もりで取得したもので、有効期限内のものです。

電話番号の例:12125550100(米国)、525512345678(メキシコ)。番号が選んだ通信事業者のものか確認してください。間違った番号へのチャージは取り消せません。

CardVは見積もりを確認し、merchant_price をすぐにウォレットから引き落として、バックグラウンドでチャージを始めます。新しい注文ではHTTP 201 が返ります。

JSON
{
  "idempotent_replay": false,
  "order": {
    "order_id": "O-00005678",
    "external_order_id": "SHOP-RC-20260930-0001",
    "status": "accepted",
    "status_title": "Recharge accepted",
    "poll_after_seconds": 12,
    "account": "12***00",
    "local_amount": "10.0000",
    "local_currency": "USD",
    "merchant_price": "9.6200",
    "merchant_currency": "USD",
    "...": "more fields"
  }
}
  • order.order_id を保存してください。
  • 電話番号は一部を伏せた形で返り、全桁が返ることはありません。

#安全な再送

自社の注文番号(external_order_id)には、二重チャージを防ぐ役割があります。

送った内容結果
新しい注文番号HTTP 201。新しい注文が作成され、ウォレットから引き落とされます。
同じ注文番号で同じチャージHTTP 200と "idempotent_replay": true。既存の注文が返り、引き落としはありません。
同じ注文番号で違うチャージexternal_order_id のHTTP 400。何も処理されません。

「同じチャージ」とは、国、通信事業者、種類、金額、電話番号がすべて同じであることを指します。重複した注文かどうかは見積もりの確認より前に判定されるため、quote_token の期限が切れていても最初の注文が返ります。

  • タイムアウト、5xx、接続の切断が起きたときは、同じ注文番号で同じ本文を送ってください。署名は、新しいタイムスタンプとnonceで作り直します。
  • 応答が得られなかったからといって、新しい注文番号を使わないでください。 同じ電話番号に2回チャージされるおそれがあります。

#チャージ注文の照会

GET/api/v1/recharge/orders/{order_id} で、1件の注文を取得します。CardVの注文ID(O-00005678)を使えます。

JSON
{
  "order_id": "O-00005678",
  "external_order_id": "SHOP-RC-20260930-0001",
  "status": "processing",
  "order_status": "processing",
  "status_title": "Recharge processing",
  "status_message": "The recharge request is being processed. Delivery is not confirmed yet.",
  "next_step": "Keep this order open and wait for confirmation before placing another recharge.",
  "poll_after_seconds": 12,
  "country": "US",
  "operator": {"operator_key": "us-att", "name": "AT&T", "logo_url": ""},
  "subtype": "airtime",
  "account": "12***00",
  "local_amount": "10.0000",
  "local_currency": "USD",
  "merchant_price": "9.6200",
  "merchant_currency": "USD",
  "attempts": [{"attempt_no": 1, "status": "processing", "error_message": "", "submitted_at": "2026-09-30T08:16:02.511201Z", "completed_at": null}],
  "created_at": "2026-09-30T08:16:01.004211Z",
  "updated_at": "2026-09-30T08:16:02.611978Z",
  "...": "more fields"
}
  • 存在しない注文ID、またはほかのアカウントの注文を指定すると、HTTP 404が返ります。
  • status_title、status_message、next_step は英語の説明文で、社内のスタッフ向けに表示できます。
  • poll_after_seconds は、次に照会するまで待つ秒数です。0 は注文が完了したことを意味します。

#チャージ注文の一覧

GET/api/v1/recharge/orders で、チャージ注文を新しい順に一覧表示します。

HTTP
GET /api/v1/recharge/orders?status=processing&limit=50&offset=0
JSON
{"count": 3, "limit": 50, "results": ["..."]}
  • 絞り込み条件:status と search(CardVの注文ID、自社の注文番号、事業者名)。
  • limit の初期値は20、上限は100です。100を超える値は100として扱われます。
  • limit や offset に負の数や数値以外を指定すると、HTTP 400が返ります。

#ステータス

Text
accepted ──► processing ──► succeeded
                  │
                  ├──► manual_review ──► succeeded または refunded
                  │
                  └──► failed ──► refunded   (代金はウォレットに返金)
ステータス完了か対応
acceptedいいえ待ちます。代金は引き落とし済みで、チャージはまだ始まっていません。
processingいいえ待ちます。数分かかることがあります。もう一度注文しないでください。
manual_reviewいいえCardVが通信事業者と結果を確認しています。待ちます。
succeededはいチャージが完了しました。エンドユーザーに知らせます。
failedまだチャージは成功しませんでした。refunded になるまで待ちます。
refundedはい代金がウォレットに戻っています。新しく注文できます。
  • poll_after_seconds の後に照会し、その後は間隔を広げます:30秒、60秒、その後は5分ごと。レート制限を超えないようにしてください。
  • 知らないステータスは「まだ完了していない」ものとして扱ってください。
  • 注文が完了していない間は、新しい注文番号で同じ番号に別のチャージを送らないでください。最初の注文も成功した場合、2回チャージされてしまいます。

#Webhookと返金

チャージの注文でも、ほかの注文と同じWebhookが届きます: order.succeeded、order.failed、order.refunded。Webhookには、CardVの注文IDと自社の注文番号が入っており、items は空の一覧です。Webhookを受け取ったら、GET/api/v1/recharge/orders/{order_id} で注文を照会してください。

返金は自動で行われます。通信事業者が失敗を確認すると、CardVは merchant_price の全額をウォレットに戻し、注文は refunded になります。返金はPortalの取引履歴ページで確認できます。成功したチャージは、返金も取り消しもできません。

#エラー

エラーの形式は共通ルールに従います。見積もりや注文が拒否されるとHTTP 400が返り、代金は引き落とされません。

キー発生する呼び出し対処
detail見積もり、注文国、通信事業者、種類、金額のいずれかが利用できません。通信事業者の一覧を確認してください。
amount見積もり、注文数値でない、ゼロ、または範囲外です。
local_currency見積もり、注文3文字のISO 4217コードではありません。
account注文電話番号がありません。
quote_token注文ない、期限切れ、書き換えられている、または一致しません。code を確認し、見積もりを取り直してください。
balance注文Portalで入金してください。
risk注文注文の上限に達しました。CardVに問い合わせてください。
external_order_id注文別の注文で使われています。安全な再送を参照してください。
wallet注文有効なウォレットがありません。CardVに問い合わせてください。

quote_token のエラーには code が付きます。

JSON
{"code": "quote_expired", "quote_token": "This quote expired. Refresh the price and confirm again."}
code意味
quote_requiredquote_token が送られていません。
quote_expired300秒を過ぎています。見積もりを取り直してください。
quote_invalid書き換えられているか、別のチャージのものです。見積もりを取り直してください。
price_changed見積もりの後に貴社の価格が変わりました。見積もりを取り直し、新しい価格を確認してください。

HTTP 403は、認証情報、署名、IP、承認のいずれかに問題があることを意味します。認証を参照してください。

連携についてご不明な点は、Merchant ID と注文 ID またはリクエスト ID を添えて [email protected] までお問い合わせください。