本文へ移動
注文ライフサイクル注文

注文

Orders APIを使用した注文情報の取得と配送記録管理について解説します。

Order APIは注文管理のために3つの独立したエンドポイントを提供しています。注文の取得APIでは、ステータス、商品、顧客詳細を含む包括的な注文情報へのアクセスが可能です。注文キャンセルAPIでは不要になった注文を取り消すことができ、配送記録の登録APIでは柔軟なペイロード構造により、注文履行追跡のための配送記録を登録できます。

注文は、マーチャントがチェックアウトセッションを作成した時点で自動的に生成され、商品、金額、顧客情報などの取引詳細がすべて含まれます。

金額フォーマット: すべての金額値(amount フィールドなど)は各通貨の最小単位で表現されます。通貨ごとの正確なエンコーディングについては、サポートされている通貨を参照してください。

概要

Orderシステムは3つの主要なAPIエンドポイントを提供しています:

  • 注文の取得: ステータス、商品、顧客詳細を含む詳細な注文情報へのアクセス
  • 注文キャンセル: 不要になった注文を取り消し、canceledAt タイムスタンプを含む最新の注文状態を取得
  • 配送記録の登録: 柔軟な配送記録の登録。任意のJSON構造を受け入れつつ、重要なフィールドに関する警告と提案を提供

これらのAPIは独立して動作します。 注文情報はいつでも取得可能で、注文が発送・配送された際に配送記録を登録できます。 配送記録の登録APIは柔軟な設計となっており、任意の有効なJSONペイロードを受け入れながら、警告システムを通じて重要な情報の含有をガイドします。

注文ライフサイクル

支払い処理後、注文は以下の状態を自動的に遷移します:

  1. 注文作成: マーチャントのチェックアウトセッション作成時に自動生成
  2. 注文処理: 以下の状態遷移:requiresPayment → processing → succeeded
  3. 注文取得: Orders APIを使用して履行・追跡用の注文詳細へアクセス
  4. 配送登録: 注文履行時に配送情報を独立して登録

注文ステータス値

注文は以下のステータスを遷移します:

  • requiresPayment: 支払い待ちの状態
  • processing: 支払い受領済み、処理中の状態
  • succeeded: 注文が正常に完了した状態
  • failed: 処理後に注文が失敗した状態
  • blocked: 注文が一時的にブロックされ、操作が制限されている状態
  • canceled: 注文がキャンセルされ、これ以上処理されない状態
  • expired: 注文の有効期限が切れ、無効になった状態
図
図
100%
スクロールで移動・拡大して詳細を確認

APIコール例

注文の取得

注文IDを使用して特定の注文の詳細情報を取得します。注文IDは、チェックアウトセッション作成時のレスポンス、またはWebhookから取得できます。

bash
curl --request GET \
  --url https://api.tokenz.one/v2/order/{YOUR_ORDER_ID} \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE' \
  --header 'Content-Type: application/json'

レスポンス:

json
{
  "id": "order_1D5xA9BnKfv_t",
  "object": "order",
  "status": "requiresPayment",
  "amount": {
    "amount": 3700,
    "currency": "JPY"
  },
  "items": [
    {
      "id": "item_1D6F8mR5TnK_t",
      "detail": {
        "product": {
          "price": {
            "amount": 1200,
            "currency": "JPY"
          },
          "quantity": 3,
          "label": "ひとにぎりのエメラルド",
          "description": "80+8",
          "images": [
            "https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp"
          ]
        }
      }
    },
    {
      "id": "item_1xejV7puGeK_t",
      "detail": {
        "product": {
          "price": {
            "amount": 100,
            "currency": "JPY"
          },
          "quantity": 1,
          "label": "Diamond",
          "description": "",
          "images": [],
          "sku": "sku_103843dfjhdfgiu",
          "taxCategory": "VIRTUAL_CURRENCY"
        }
      }
    }
  ],
  "description": "Game items purchase",
  "reference": "ORDER_2024_001",
  "test": true,
  "expiresAt": "2024-12-31T23:59:59Z",
  "createdAt": "2024-01-15T10:00:00Z",
  "updatedAt": "2024-01-15T10:05:30Z"
}

注文キャンセル

不要になった注文を停止するために既存の注文をキャンセルします。リクエストボディは不要で、パスに注文IDを指定するだけです。

bash
curl --request POST \
  --url https://api.tokenz.one/v2/order/{YOUR_ORDER_ID}/cancel \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE' \
  --header 'Content-Type: application/json'

レスポンス:

json
{
  "id": "order_1D5xA9BnKfv_t",
  "object": "order",
  "status": "canceled",
  "amount": {
    "amount": 3700,
    "currency": "JPY"
  },
  "items": [
    {
      "id": "item_1D6F8mR5TnK_t",
      "detail": {
        "product": {
          "price": {
            "amount": 1200,
            "currency": "JPY"
          },
          "quantity": 3,
          "label": "ひとにぎりのエメラルド",
          "description": "80+8",
          "images": [
            "https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp"
          ]
        }
      }
    },
    {
      "id": "item_1xejV7puGeK_t",
      "detail": {
        "product": {
          "price": {
            "amount": 100,
            "currency": "JPY"
          },
          "quantity": 1,
          "label": "Diamond",
          "description": "",
          "images": [],
          "sku": "sku_103843dfjhdfgiu",
          "taxCategory": "VIRTUAL_CURRENCY"
        }
      }
    }
  ],
  "description": "Game items purchase",
  "reference": "ORDER_2024_001",
  "test": true,
  "expiresAt": "2024-12-31T23:59:59Z",
  "createdAt": "2024-01-15T10:00:00Z",
  "updatedAt": "2024-01-15T10:05:30Z",
  "canceledAt": "2024-01-15T10:05:32Z"
}

注文をキャンセルできない場合(例:すでにsucceededになっている場合)、APIはorder.status-invalidエラーコードを含む422 Unprocessable Entityを返します。

配送記録の登録

柔軟なペイロードで注文の配送情報を登録します。APIは任意の有効なJSON構造を受け入れ、配送追跡の最適化に役立つ警告と提案を返します。

注意: このAPIは同一注文に対して複数回呼び出し可能で、部分配送の追跡が可能です。例えば、注文に複数の商品が含まれ、別々のバッチで発送される場合、各発送ごとにこのAPIを呼び出すことができます。各呼び出しは独立した配送記録を作成し、履行進捗を正確に追跡できます。

bash
curl --request POST \
  --url https://api.tokenz.one/v2/order/{YOUR_ORDER_ID}/delivery \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE' \
  --header 'Content-Type: application/json' \
  --data '{
            "at": "2025-01-15T10:30:00Z",
            "user": {
              "userId": "user_67890",
              "phoneNumber": "+1234567890",
              "emailAddress": "test-user@example.com"
            },
            "items": [
              {
                "sku": "TEST-SKU-001",
                "name": "Test Product for Delivery",
                "itemId": "item_12345",
                "itemChange": {
                  "inAppBalanceAfter": 102,
                  "inAppBalanceBefore": 100
                },
                "deliveredQuantity": 2
              }
            ],
            "status": "succeeded",
            "metadata": {
              "customField": "test_value",
              "merchantNotes": "Successfully delivered via API",
              "deliveryChannel": "api"
            },
            "progress": "completed",
            "cartContext": {
              "deviceId": "device_abc123",
              "timestamp": "2025-01-15T10:00:00Z",
              "ipAddress": "192.168.1.100",
              "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
              "geoLocation": {
                "lat": 37.7749,
                "lon": -122.4194,
                "region": "US"
              }
            },
            "deliveryInfo": {
              "deliveryMethod": "digital_download",
              "confirmationType": "email",
              "confirmationProof": "delivery_confirmation_12345"
            },
            "deliveryContext": {
              "deviceId": "device_abc123",
              "timestamp": "2025-01-15T10:30:00Z",
              "ipAddress": "192.168.1.100",
              "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
            }
          }'

レスポンス:

json
{
  "success": true,
  "message": "Delivery record has been registered successfully"
}

warnings と suggestions 配列は空の場合はレスポンスから省略されます。含まれる場合は、ペイロード内の不足フィールドや改善点を説明する文字列が格納されます。

APIの柔軟性とガイダンス

配送記録の登録APIは柔軟性を重視した設計となっています。任意の有効なJSON構造を送信可能で、APIはそれを受け入れます。配送追跡から最大限の価値を得られるよう、APIはレスポンスに警告と提案を含めて返します。

警告と提案システム

配送記録登録時、APIはペイロードを分析し、以下のガイダンスを提供します:

  • 警告: 効果的な配送追跡に必要な重要フィールドの欠落・無効時にアラート表示
  • 提案: 分析、不正検出、配送最適化の強化に役立つオプションフィールドの推奨

このシステムにより、シンプルな実装から開始し、フィードバックに基づいて段階的に統合を改善することが可能です。

フィールド定義と重要度レベル

ステータスと進捗の列挙値

status:個別配送のステータス

  • succeeded - この特定の配送が正常に完了
  • failed - この特定の配送に失敗

progress:注文全体の配送進捗

  • completed - 注文内のすべての商品が完全に配送済み
  • in_progress - 部分配送 - 一部の商品は配送済み、その他は保留中
  • pending - 注文からまだ商品が配送されていない

重要な違い:複数の商品を別々に発送する注文の場合:

  • status は各個別配送を追跡
  • progress は注文全体の完了状況を追跡
  • 例:3つの商品を2回に分けて発送する注文では、2つの配送記録(それぞれ独自のstatusを持つ)が作成され、progressは3つすべての商品が配送されたかどうかを反映

フィールド重要度カテゴリ

統合の優先順位付けのため、フィールドを重要度別に分類しています:

重要フィールド(欠落/無効時に警告生成):

  • status: 配送ステータス(上記の列挙値を参照)
  • progress: 配送進捗(上記の列挙値を参照)
  • at: 配送日時(ISO 8601形式のタイムスタンプ)
  • cartContext.timestamp: cartContext を指定した場合のタイムスタンプ
  • deliveryContext.timestamp: deliveryContext を指定した場合のタイムスタンプ

推奨フィールド(欠落時に提案生成):

  • items: 配送商品の詳細配列
  • items.deliveredQuantity: 各商品の配送数量
  • items.itemChange.inAppBalanceBefore: 残高追跡に必須
  • items.itemChange.inAppBalanceAfter: 残高追跡に必須
  • user: パーソナライズされた分析用のユーザー情報
  • user.userId: 配送追跡用のユーザー識別子
  • user.emailAddress: ユーザー識別用のメールアドレス
  • deliveryContext: 不正検出用のコンテキスト情報
  • deliveryInfo: 配送方法および確認詳細

オプションフィールド(警告なし、追加価値あり):

  • metadata: 特定用途向けのカスタムフィールド(タイプ: Map<String, String>)
  • cartContext: 購入時のコンテキスト情報
  • geoLocation: 地理位置データ

配送記録データ構造

配送記録エンドポイントは任意の有効なJSON構造を受け入れますが、紛争に備えて包括的な配送情報を提供することを強く推奨します。配送記録が詳細であればあるほど、問題が発生した際の証拠として強力になります。

上記のcurlコマンド例に示されているように、すべての利用可能なフィールドを含む完全なペイロードを送信することを推奨します。

紛争対応における包括的な記録の重要性

完全な配送情報の提供は、紛争対策として不可欠です:

  • 証拠の文書化:顧客が紛争を提起した際、詳細な記録が配送の証拠となります
  • タイムラインの検証:タイムスタンプとコンテキストデータにより、配送がいつどのように行われたかを証明できます
  • 商品追跡:詳細な商品記録により、何がどのような数量で配送されたかを正確に証明できます

APIは最小限のデータも受け入れますが、不完全な記録では紛争時に十分な証拠を提供できない可能性があります。包括的な監査証跡を維持するため、常に利用可能なすべての情報を含めてください。

レスポンスステータスコード

Orders APIは標準的なHTTPステータスコードと詳細なエラーメッセージを返します:

  • 200 OK: 注文の取得またはキャンセルが正常に完了
  • 201 Created: 配送記録の登録が正常に完了
  • 400 Bad Request: 無効なリクエスト形式または必須フィールドの欠落
  • 401 Unauthorized: 無効または欠落したAPIトークン
  • 403 Forbidden: リクエストされたリソースへのアクセス拒否
  • 404 Not Found: 注文が見つからない、またはアクセス不可
  • 422 Unprocessable Entity: 現在の注文ステータスで許可されない操作(例:完了済みの注文をキャンセルしようとするとorder.status-invalidが返ります)
  • 500 Server Error: 内部サーバーエラー

すべてのエラーレスポンスには、プログラム処理用のコードとメッセージを含む構造化されたエラーオブジェクトが含まれています。

エラーレスポンス例

json
{
  "status": 404,
  "code": "entity.not-found",
  "message": "The requested order could not be found."
}

注文Webhook

注文イベントに関する通知を受信するためにWebhookを設定します:

order.created

注文が作成されたときにトリガーされます:

json
{
  "id": "d4e5f6a7-b8c9-0123-defa-234567890abc",
  "object": "order.created",
  "createdAt": "2024-01-15T10:00:00Z",
  "test": true,
  "eventData": {
    "type": "order",
    "version": "v2",
    "data": {
      "order": {
        "id": "order_1D5xA9BnKfv_t",
        "object": "order",
        "status": "requiresPayment",
        "amount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "consumerAmount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "items": [
          {
            "id": "item_1D6F8mR5TnK_t",
            "detail": {
              "product": {
                "price": {
                  "amount": 3700,
                  "currency": "JPY"
                },
                "quantity": 1,
                "label": "Game Item Bundle",
                "description": "In-game items",
                "images": []
              }
            }
          }
        ],
        "description": "Game items purchase",
        "reference": "ORDER_2024_001",
        "test": true,
        "expiresAt": "2024-01-16T10:00:00Z",
        "createdAt": "2024-01-15T10:00:00Z",
        "updatedAt": "2024-01-15T10:00:00Z",
        "regionCode": "JP"
      }
    }
  }
}

order.succeeded

支払い後、注文が正常に完了したときにトリガーされます:

json
{
  "id": "e5f6a7b8-c9d0-1234-efab-345678901def",
  "object": "order.succeeded",
  "createdAt": "2024-01-15T10:45:00Z",
  "test": true,
  "eventData": {
    "type": "order",
    "version": "v2",
    "data": {
      "order": {
        "id": "order_1D5xA9BnKfv_t",
        "object": "order",
        "status": "succeeded",
        "amount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "consumerAmount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "items": [
          {
            "id": "item_1D6F8mR5TnK_t",
            "detail": {
              "product": {
                "price": {
                  "amount": 3700,
                  "currency": "JPY"
                },
                "quantity": 1,
                "label": "Game Item Bundle",
                "description": "In-game items",
                "images": []
              }
            }
          }
        ],
        "description": "Game items purchase",
        "reference": "ORDER_2024_001",
        "test": true,
        "expiresAt": "2024-01-16T10:00:00Z",
        "createdAt": "2024-01-15T10:00:00Z",
        "updatedAt": "2024-01-15T10:45:00Z",
        "regionCode": "JP"
      }
    }
  }
}

order.expired

注文が完了せずに期限切れになったときにトリガーされます:

json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "object": "order.expired",
  "createdAt": "2024-12-31T23:59:59Z",
  "test": true,
  "eventData": {
    "type": "order",
    "version": "v2",
    "data": {
      "order": {
        "id": "order_1D5xA9BnKfv_t",
        "object": "order",
        "status": "expired",
        "amount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "consumerAmount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "items": [
          {
            "id": "item_1D6F8mR5TnK_t",
            "detail": {
              "product": {
                "price": {
                  "amount": 3700,
                  "currency": "JPY"
                },
                "quantity": 1,
                "label": "Game Item Bundle",
                "description": "In-game items",
                "images": []
              }
            }
          }
        ],
        "description": "Game items purchase",
        "reference": "ORDER_2024_001",
        "test": true,
        "expiresAt": "2024-12-31T23:59:59Z",
        "createdAt": "2024-01-15T10:00:00Z",
        "updatedAt": "2024-12-31T23:59:59Z",
        "regionCode": "JP"
      }
    }
  }
}

order.canceled

注文がキャンセルされたときにトリガーされます:

json
{
  "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "object": "order.canceled",
  "createdAt": "2024-01-15T10:05:32Z",
  "test": true,
  "eventData": {
    "type": "order",
    "version": "v2",
    "data": {
      "order": {
        "id": "order_1D5xA9BnKfv_t",
        "object": "order",
        "status": "canceled",
        "amount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "consumerAmount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "items": [
          {
            "id": "item_1D6F8mR5TnK_t",
            "detail": {
              "product": {
                "price": {
                  "amount": 3700,
                  "currency": "JPY"
                },
                "quantity": 1,
                "label": "Game Item Bundle",
                "description": "In-game items",
                "images": []
              }
            }
          }
        ],
        "description": "Game items purchase",
        "reference": "ORDER_2024_001",
        "test": true,
        "createdAt": "2024-01-15T10:00:00Z",
        "updatedAt": "2024-01-15T10:05:32Z",
        "canceledAt": "2024-01-15T10:05:32Z",
        "regionCode": "JP"
      }
    }
  }
}

order.failed

注文が失敗したときにトリガーされます:

json
{
  "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
  "object": "order.failed",
  "createdAt": "2024-01-15T11:00:00Z",
  "test": true,
  "eventData": {
    "type": "order",
    "version": "v2",
    "data": {
      "order": {
        "id": "order_1D5xA9BnKfv_t",
        "object": "order",
        "status": "failed",
        "amount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "consumerAmount": {
          "amount": 3700,
          "currency": "JPY"
        },
        "items": [
          {
            "id": "item_1D6F8mR5TnK_t",
            "detail": {
              "product": {
                "price": {
                  "amount": 3700,
                  "currency": "JPY"
                },
                "quantity": 1,
                "label": "Game Item Bundle",
                "description": "In-game items",
                "images": []
              }
            }
          }
        ],
        "description": "Game items purchase",
        "reference": "ORDER_2024_001",
        "test": true,
        "createdAt": "2024-01-15T10:00:00Z",
        "updatedAt": "2024-01-15T11:00:00Z",
        "regionCode": "JP"
      }
    }
  }
}

ベストプラクティス

注文と配送記録管理

  • 後続参照用に注文IDをシステムに保存
  • Webhookを使用してリアルタイムの注文ステータス更新を受信
  • 配送または発送後すぐに独立した配送記録を維持・登録。APIは紛争解決用のバックアップストレージを提供しますが、お客様のシステムが配送データの主要なソースであるべきです
  • 部分配送の場合、配送記録の登録APIを複数回呼び出し - 各商品バッチの発送ごとに1回。各呼び出しは個別の配送記録を作成し、複数配送注文の正確な追跡が可能

配送記録の登録API統合戦略

  • 警告を最小化し、追跡機能を最大化するために包括的なペイロード構造を使用
  • 最適なパフォーマンスのためにすべての推奨フィールド(at、user、items、deliveryContext、deliveryInfo)を含める
  • すべてのタイムスタンプにISO 8601形式を使用(at、cartContext.timestamp、deliveryContext.timestamp)し、2024-03-01T00:00:00.000Z以降の日時を指定