跳至內容
產品與訂閱變更與查詢

變更與查詢

訂閱相關端點分為兩類。

直接查詢與變更。 這類呼叫不經過 Checkout Session。可用來顯示訂閱、其訂單紀錄與發票連結,以及尚未完成的方案變更;當由您主動發起時,也可用來取消訂閱或待生效的方案變更。直接取消會立即生效。

需由消費者確認的請求。 這類呼叫會回傳 Checkout Session,請將消費者重新導向至其 url。在消費者確認之前,訂閱不會有任何變動。當變更需要消費者操作或同意時使用:消費者要求取消、需要消費者核准方案變更,或需要消費者提供新的付款方式。

金額格式: 金額(例如 amount 欄位)以各貨幣的最小輔助單位表示。請參閱支援的貨幣。

查詢結果僅限於 API 金鑰所屬的商家,以及該金鑰的測試模式設定。

列出訂閱

GET /v2/subscription 會回傳已驗證商家的訂閱,依 id 由新到舊排序。

reference 和 customerId 為完全比對,同時指定時以 AND 組合。limit 範圍為 1–100,預設為 20。取得第一頁時請省略 cursor;要取得下一頁時,將 pagination.nextCursor 原封不動地作為 cursor 傳回。

bash
curl --request GET \
  --url 'https://api.tokenz.one/v2/subscription?customerId=customer_123&limit=20' \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE'

回應

json
{
  "data": [
    {
      "id": "subscription_1p4LS47fB1h_t",
      "object": "subscription",
      "status": "active",
      "test": true,
      "reference": "Pro Plan (Monthly)",
      "customerId": "customer_123",
      "items": [
        {
          "id": "item_1p4LS47fB1i_t",
          "detail": {
            "product": {
              "price": { "amount": 1000, "currency": "USD" },
              "quantity": 1,
              "label": "Pro Plan (Monthly)",
              "images": ["https://example.com/pro-plan.png"]
            }
          }
        }
      ],
      "interval": { "unit": "MONTH", "count": 1 },
      "provideAccess": true,
      "currentBillingPeriodEnd": "2026-08-01T00:00:00Z",
      "createdAt": "2026-07-01T00:00:00Z",
      "updatedAt": "2026-07-01T00:00:00Z"
    }
  ],
  "pagination": {
    "nextCursor": "subscription_1p4LC47fB2a_t"
  }
}

最後一頁不會包含 pagination.nextCursor。

取得單一訂閱

GET /v2/subscription/{id} 會回傳單一訂閱。若 id 不存在、屬於其他商家,或與 API 金鑰的測試模式不符,呼叫會以 404 失敗。

bash
curl --request GET \
  --url https://api.tokenz.one/v2/subscription/subscription_1p4LS47fB1h_t \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE'

回應

json
{
  "id": "subscription_1p4LS47fB1h_t",
  "object": "subscription",
  "status": "active",
  "test": true,
  "reference": "Pro Plan (Monthly)",
  "customerId": "customer_123",
  "items": [
    {
      "id": "item_1p4LS47fB1i_t",
      "detail": {
        "product": {
          "price": { "amount": 1000, "currency": "USD" },
          "quantity": 1,
          "label": "Pro Plan (Monthly)",
          "images": ["https://example.com/pro-plan.png"]
        }
      }
    }
  ],
  "interval": { "unit": "MONTH", "count": 1 },
  "provideAccess": true,
  "currentBillingPeriodEnd": "2026-08-01T00:00:00Z",
  "createdAt": "2026-07-01T00:00:00Z",
  "updatedAt": "2026-07-01T00:00:00Z"
}

取消訂閱

POST /v2/subscription/{id}/cancel 會立即取消訂閱,不需要請求內容。 訂閱必須處於 trialing、active 或 unpaid 狀態才能取消。已經是 canceled 的訂閱不受影響,其他狀態則會回傳 422,錯誤代碼為 subscription.status-invalid。

取消會設定 canceledAt、停止產生後續的續訂訂單,並發送 subscription.canceled。取消後無法復原。關於存取權限與處理中訂單的後續處理,請參閱生命週期與計費。

bash
curl --request POST \
  --url https://api.tokenz.one/v2/subscription/subscription_1p4LS47fB1h_t/cancel \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE'

回應

json
{
  "id": "subscription_1p4LS47fB1h_t",
  "object": "subscription",
  "status": "canceled",
  "test": true,
  "items": [
    {
      "id": "item_1p4LS47fB1i_t",
      "detail": {
        "product": {
          "price": { "amount": 1000, "currency": "USD" },
          "quantity": 1,
          "label": "Pro Plan (Monthly)",
          "images": ["https://example.com/pro-plan.png"]
        }
      }
    }
  ],
  "interval": { "unit": "MONTH", "count": 1 },
  "provideAccess": true,
  "provideAccessUntil": "2026-08-01T00:00:00Z",
  "canceledAt": "2026-07-15T12:00:00Z",
  "createdAt": "2026-07-01T00:00:00Z",
  "updatedAt": "2026-07-15T12:00:00Z"
}

要求消費者確認取消

POST /v2/subscription/{id}/request/cancel 本身不會取消訂閱,而是建立一個 Checkout Session 供消費者確認。請將消費者重新導向至回傳的 url。消費者確認後,訂閱會以與直接取消相同的方式取消,同樣會發送 subscription.canceled webhook。

必填的請求內容欄位:

  • successUrl:消費者確認後導向的頁面。
  • pendingUrl:確認仍在處理中時,消費者導向的頁面。
  • cancelUrl:消費者中途放棄流程時導向的頁面。

theme 為選填(LIGHT 或 DARK)。

bash
curl --request POST \
  --url https://api.tokenz.one/v2/subscription/subscription_1p4LS47fB1h_t/request/cancel \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE' \
  --data '{
    "successUrl": "https://example.com/success",
    "pendingUrl": "https://example.com/pending",
    "cancelUrl": "https://example.com/cancel"
  }'

回應

201 會回傳 Checkout Session。在消費者確認之前,訂閱會維持目前的狀態。

json
{
  "id": "checkoutsession_1p4LC47fB2a_t",
  "object": "checkoutsession",
  "url": "https://checkout.tokenz.one/1p4LC47fB2a_t",
  "successUrl": "https://example.com/success",
  "pendingUrl": "https://example.com/pending",
  "cancelUrl": "https://example.com/cancel",
  "test": true,
  "subscription": {
    "id": "subscription_1p4LS47fB1h_t",
    "object": "subscription",
    "status": "active"
  },
  "createdAt": "2026-07-15T12:00:00Z",
  "updatedAt": "2026-07-15T12:00:00Z"
}

要求變更付款方式

POST /v2/subscription/{id}/request/payment-method-change 會建立一個 Checkout Session,讓消費者提供新卡片。請將消費者重新導向至 url。新卡片的授權會在該代管頁面上取得;請參閱支付方式與授權。

請求內容與要求消費者確認取消相同,為三個重新導向網址(successUrl、pendingUrl、cancelUrl),以及選填的 theme。

若訂閱為 unpaid,回傳的工作階段是未付款訂單的結帳頁面。支付該訂單後,付款方式會隨之更換,訂閱也會恢復有效。成功時,Tokenz 會發送 subscription.activated webhook。

若訂閱為 active 或 trialing,則會回傳用於更新付款方式的 Checkout Session。成功時,Tokenz 會發送 subscription.payment_method_updated webhook。

bash
curl --request POST \
  --url https://api.tokenz.one/v2/subscription/subscription_1p4LS47fB1h_t/request/payment-method-change \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE' \
  --data '{
    "successUrl": "https://example.com/success",
    "pendingUrl": "https://example.com/pending",
    "cancelUrl": "https://example.com/cancel"
  }'

回應

json
{
  "id": "checkoutsession_1p4LP47fB3b_t",
  "object": "checkoutsession",
  "url": "https://checkout.tokenz.one/1p4LP47fB3b_t",
  "successUrl": "https://example.com/success",
  "pendingUrl": "https://example.com/pending",
  "cancelUrl": "https://example.com/cancel",
  "test": true,
  "subscription": {
    "id": "subscription_1p4LS47fB1h_t",
    "object": "subscription",
    "status": "active"
  },
  "createdAt": "2026-07-15T12:00:00Z",
  "updatedAt": "2026-07-15T12:00:00Z"
}

要求變更方案

POST /v2/subscription/{id}/request/plan-change 會請消費者核准新的商品與計費間隔。 在消費者於回傳的 Checkout Session 上核准之前,變更不會套用。

訂閱必須處於 active 或 trialing 狀態,其他狀態會回傳 422,錯誤代碼為 subscription.status-invalid。 請求內容必須包含 itemDetails、replacementMode、successUrl、pendingUrl 和 cancelUrl。 itemDetails 會取代訂閱目前的商品:必須是唯一一個未打折、quantity 為 1 的商品。 商品的幣別必須與訂閱的幣別相同,否則會回傳 400 錯誤,錯誤代碼為 currency.inconsistent。 interval 用於設定新的計費間隔:{ "unit": "WEEK" | "MONTH" | "YEAR", "count": <integer ≥ 1> }。 立即變更套用後會使用 successUrl,遞延變更獲得核准後則會使用 pendingUrl。

replacementMode:

  • IMMEDIATE_PRORATION:適用於以時間計的訂閱(例如進階方案),在消費者授權訂單後立即套用變更。 若訂閱為 active,消費者會獲得目前計費週期剩餘價值按比例計算的折抵,計費錨點則改為授權當天。 若訂閱為 trialing,試用期會立即結束且不另給折抵,訂閱直接以新方案開始。 若計算出的折抵金額超過新商品的價格,會回傳 422 錯誤,錯誤代碼為 subscription.plan-replacement-invalid。 請勿將此模式用於以商品計的訂閱(例如每月購買遊戲幣)。若需要為以商品計的訂閱提供升級選項,請聯絡 Tokenz。
  • DEFERRED:在目前計費週期結束後套用變更。核准時會發送 subscription.plan_change_scheduled;方案本身會在下一個計費週期的訂單付款完成時變更。

方案套用時(無論是立即或在下一個週期),Tokenz 會發送 subscription.plan_changed webhook。

bash
curl --request POST \
  --url https://api.tokenz.one/v2/subscription/subscription_1p4LS47fB1h_t/request/plan-change \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE' \
  --data '{
    "itemDetails": [{
      "product": {
        "price": { "amount": 2000, "currency": "USD" },
        "quantity": 1,
        "label": "Pro Plan (Yearly)",
        "images": ["https://example.com/pro-plan.png"],
        "taxCategory": "SAAS"
      }
    }],
    "interval": { "unit": "YEAR", "count": 1 },
    "replacementMode": "DEFERRED",
    "successUrl": "https://example.com/success",
    "pendingUrl": "https://example.com/pending",
    "cancelUrl": "https://example.com/cancel"
  }'

若要在消費者核准後立即套用相同方案,請使用 "replacementMode": "IMMEDIATE_PRORATION"。此模式適用於以時間計的訂閱,不適用於以商品計的訂閱。

回應

201 會回傳 Checkout Session 以及待處理的變更。

json
{
  "id": "checkoutsession_1p4LR47fB4c_t",
  "object": "checkoutsession",
  "url": "https://checkout.tokenz.one/1p4LR47fB4c_t",
  "successUrl": "https://example.com/success",
  "pendingUrl": "https://example.com/pending",
  "cancelUrl": "https://example.com/cancel",
  "test": true,
  "subscriptionChange": {
    "id": "subscriptionchange_1p4LC9aB2cD_t",
    "object": "subscriptionchange",
    "status": "pending",
    "replacementMode": "DEFERRED",
    "interval": { "unit": "YEAR", "count": 1 },
    "items": [
      {
        "id": "item_1p4LS47fB1j_t",
        "detail": {
          "product": {
            "price": { "amount": 2000, "currency": "USD" },
            "quantity": 1,
            "label": "Pro Plan (Yearly)",
            "images": ["https://example.com/pro-plan.png"]
          }
        }
      }
    ]
  },
  "createdAt": "2026-07-15T12:00:00Z",
  "updatedAt": "2026-07-15T12:00:00Z"
}

請將消費者重新導向至 url。若之後需要列出或取消此變更,請保存 subscriptionChange.id。

列出方案變更

GET /v2/subscription/{id}/plan-change 會回傳訂閱尚未完成的變更,即狀態為 pending 或 approved 的變更。canceled 和 applied 的變更不包含在內。

變更會經歷以下狀態:pending(等待消費者處理)、approved(已接受;若為遞延變更,表示尚未套用)、applied 或 canceled。

bash
curl --request GET \
  --url https://api.tokenz.one/v2/subscription/subscription_1p4LS47fB1h_t/plan-change \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE'

回應

json
{
  "data": [
    {
      "id": "subscriptionchange_1p4LC9aB2cD_t",
      "object": "subscriptionchange",
      "status": "approved",
      "replacementMode": "DEFERRED",
      "interval": { "unit": "YEAR", "count": 1 },
      "items": [
        {
          "id": "item_1p4LS47fB1j_t",
          "detail": {
            "product": {
              "price": { "amount": 2000, "currency": "USD" },
              "quantity": 1,
              "label": "Pro Plan (Yearly)",
              "images": ["https://example.com/pro-plan.png"]
            }
          }
        }
      ]
    }
  ]
}

取消方案變更

POST /v2/subscription/{id}/plan-change/{changeId}/cancel 會在變更套用前取消狀態為 pending 或 approved 的變更,不需要請求內容。 取消狀態為 applied、expired 或 canceled 的變更會回傳 422,錯誤代碼為 subscription.change-status-invalid。 一旦下一個計費週期的訂單已建立,遞延變更即使狀態仍為 approved 也無法再取消;嘗試取消這類變更會回傳 422,錯誤代碼為 subscription.change-status-invalid。

取消已核准的遞延變更時,會發送 subscription.plan_change_canceled。

bash
curl --request POST \
  --url https://api.tokenz.one/v2/subscription/subscription_1p4LS47fB1h_t/plan-change/subscriptionchange_1p4LC9aB2cD_t/cancel \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE'

回應

json
{
  "id": "subscriptionchange_1p4LC9aB2cD_t",
  "object": "subscriptionchange",
  "status": "canceled",
  "replacementMode": "DEFERRED",
  "interval": { "unit": "YEAR", "count": 1 },
  "items": [
    {
      "id": "item_1p4LS47fB1j_t",
      "detail": {
        "product": {
          "price": { "amount": 2000, "currency": "USD" },
          "quantity": 1,
          "label": "Pro Plan (Yearly)",
          "images": ["https://example.com/pro-plan.png"]
        }
      }
    }
  ]
}

列出訂閱的訂單

Order 服務上的 GET /v2/order 可列出為某個訂閱建立的訂單,subscriptionId 為必填。limit(1–100,預設 20)和 cursor 的分頁方式與列出訂閱相同:將 pagination.nextCursor 原封不動地作為 cursor 傳回。訂單依 id 由新到舊排序,且只會回傳與 API 金鑰測試模式相符的訂單。

每筆訂單都包含 subscriptionId。商品可能包含 billedPeriodStart(含)和 billedPeriodEnd(不含),表示該訂單涵蓋的期間。

bash
curl --request GET \
  --url 'https://api.tokenz.one/v2/order?subscriptionId=subscription_1p4LS47fB1h_t&limit=20' \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE'

回應

json
{
  "data": [
    {
      "id": "order_1D5xA9BnKfv_t",
      "object": "order",
      "status": "succeeded",
      "test": true,
      "subscriptionId": "subscription_1p4LS47fB1h_t",
      "amount": { "amount": 1000, "currency": "USD" },
      "items": [
        {
          "id": "item_1p4LO47fB1k_t",
          "billedPeriodStart": "2026-07-01T00:00:00Z",
          "billedPeriodEnd": "2026-08-01T00:00:00Z",
          "detail": {
            "product": {
              "price": { "amount": 1000, "currency": "USD" },
              "quantity": 1,
              "label": "Pro Plan (Monthly)",
              "images": ["https://example.com/pro-plan.png"]
            }
          }
        }
      ],
      "createdAt": "2026-07-01T00:00:00Z",
      "updatedAt": "2026-07-01T00:00:05Z"
    }
  ],
  "pagination": {
    "nextCursor": "order_1p4LC47fB2a_t"
  }
}

發票連結

GET /v2/order/{id}/invoice 會回傳訂單(包括訂閱續訂訂單)給買家的代管發票連結。displayUrl 是代管發票頁面。downloadUrl 是 PDF 檔案,只有在 PDF 產生後才會出現。請將顧客重新導向至完整網址,包括帶有 Tokenz 產生之簽章的片段(fragment)部分。

bash
curl --request GET \
  --url https://api.tokenz.one/v2/order/order_1D5xA9BnKfv_t/invoice \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE'

回應

json
{
  "displayUrl": "https://invoice.tokenz.one/i/1D5xA9BnKfv_t#generated-invoice-signature",
  "downloadUrl": "https://invoice.tokenz.one/i/1D5xA9BnKfv_t/download#generated-invoice-signature"
}

在 PDF 產生之前,回應只會包含 displayUrl。

Webhook

請透過 webhook 同步您自己的記錄,而不要輪詢這些端點。本頁各項操作對應的事件如下:

  • subscription.canceled:直接取消或經消費者確認的取消已完成。
  • subscription.payment_method_updated:消費者已確認新卡片。
  • subscription.plan_change_scheduled:消費者已核准遞延方案變更。
  • subscription.plan_change_canceled:已排程的遞延方案變更在套用前被取消。
  • subscription.plan_changed:立即或遞延的方案變更已套用。負載中的 items 和 interval 即為新方案。

負載結構請參閱 Webhook。