號卡平台渠道 API
下載本語言說明

號卡平台渠道 API

版本:0.24.0 · 2026-10-04

API 基礎網址:https://api.roguemobile.hk/v1

線上 API 文件

帳戶與 API Key

平台提供渠道帳戶(即渠道代碼)和固定 API Key。每次請求在標頭中同時傳入這兩個值,無需登入、取得臨時 token 或更新權杖。

X-Partner-Id: YOUR_CHANNEL_CODE
X-API-Key: YOUR_API_KEY
Content-Type: application/json

先用餘額查詢測試接入:

curl 'https://api.roguemobile.hk/v1/balance' \
  -H 'X-Partner-Id: YOUR_CHANNEL_CODE' \
  -H 'X-API-Key: YOUR_API_KEY'

請將佔位值替換為自己的憑證。Key 不會定時到期;重置後舊值立即失效。渠道代碼變更後須更新 X-Partner-Id。憑證由渠道伺服器透過 HTTPS 發送,不放在公開網頁或 URL 中,也不要同時發送 Authorization 標頭。

本文路徑均相對於 /v1,不要重複加上 /v1。JSON 請求使用 Content-Type: application/json;正常回應使用 data 和 meta,HTTP 錯誤回應使用 error 和 meta。/ledger/export 成功時返回 CSV。文件語言切換不改變 API 欄位、狀態值或錯誤碼;程式應依錯誤碼判斷,不依賴可讀 message 的文字或語言。

選填欄位可省略;只有結構定義明確允許時才可傳 null。例如 txid: null 或 change_type: null 返回 HTTP 400,不會自動產生交易號或選擇即日續費。查詢參數須符合文件列出的格式及可選值;同一個單值參數重複傳入、無效日期或錯誤的布林值返回 400,不會忽略錯誤條件而擴大查詢範圍。

最小接入流程

步驟 呼叫 渠道需要做的事
開卡時選擇套餐和城市 GET /regional-catalog?orderable=true 保存選中的 catalog_entry_id,一個值對應套餐和地址
提交業務 選擇下方四類業務之一的 POST 範例 至少一條明細,不設固定條數上限;建議提供渠道內唯一的 txid
取得結果 GET /jobs/{id} 或回呼 保存返回的 data.job.id;依逐卡最終狀態判斷成功或失敗

續費、重新啟用沿用已有線路,不需要再次查套餐目錄。每次辦理前也無需先查餘額、校驗地址或同步卡片:平台會檢查歸屬、價格和整批餘額。未登記識別資料的舊卡可能需要先同步一次。HTTP 202 只表示已受理,並非已完成。

可以先只對接查單。需要自動通知時,再一次性登記 HTTPS 回呼地址並取得獨立的 Webhook Secret,每筆業務不用重傳回呼地址。異常恢復介面僅在異常時使用。

範例號碼和目錄 ID 是佔位值,須替換為真實資料。ICCID 必須已歸屬本渠道;收費業務還需設定售價及足夠預存餘額,手動 WFC 免費。金額均為 USD 字串。

套餐、地址和唯一碼

每個唯一碼對應一個「套餐+城市+州+郵編+詳細地址」組合。渠道頁面可先選套餐,再從該套餐的目錄記錄中選擇城市及地址,最後提交所選記錄的 catalog_entry_id;使用者不需要手動輸入唯一碼。同一地址搭配不同套餐,對應不同目錄記錄。

GET /regional-catalog 返回已設定的套餐與地址目錄,可按 zip、state、area_code、product_code、orderable=true 等條件篩選,使用 page、per_page 翻頁。

orderable=true 僅返回可下單記錄;orderable=false 或省略此參數時,返回符合其他條件的全部記錄。明細包含:

欄位 含義
id / catalog_entry_id 地區套餐目錄唯一編號
revision 目錄版本;提交 catalog_revision 時,平台才會校驗是否與所選版本一致
product_code 平台產品編號,僅用於產品分類、篩選
plan_code / plan_id 業務介面使用的套餐代碼、套餐 ID
plan_name 套餐展示名稱
service_address 街道、城市、州和 ZIP
prices 本渠道按業務的報價;null 表示未設定
zip_region 城市和參考區號、歷史開卡區號資訊,只讀
orderable 目前設定是否支援辦理;提交時仍須再次驗證

GET /regional-catalog/{id} 讀取完整記錄。開卡時傳 catalog_entry_id 可自動匹配套餐和地址,也可同時傳 catalog_revision 校驗版本。目錄版本過期,或該明細的套餐、地址與目錄衝突時,該明細記為 failed;其餘有效明細繼續同批辦理。無效的批次結構仍會拒絕整個請求。

GET /zip-regions 與 GET /zip-regions/{zip} 單獨查詢城市、州和區號資料。區號不影響套餐唯一碼,不保證號碼供應。

開卡

POST /jobs/activations

{
  "txid": "channel-activation-001",
  "items": [
    {
      "esn": "89000000000000000001",
      "catalog_entry_id": "CATALOG_ENTRY_ID"
    }
  ]
}

傳入選中的目錄唯一碼,平台自動補齊套餐、街道、城市、州和 ZIP。這種方式不需要再傳 plan_code、defaults、customer 或 mode。需要拒絕選擇後已變更的目錄時,可另外傳 catalog_revision。批次開卡只需在 items 中增加明細。區號供參考,不能保證指定區號。

續費

POST /jobs/renewals

{
  "txid": "channel-renewal-001",
  "change_type": "ONEXPIRY",
  "items": [
    {
      "mdn": "2025550100"
    }
  ]
}

正常續費每條明細需提供一個線路標識,並建議提供 txid。使用 change_type 選擇以下兩種方式:

方式 change_type 週期與扣款時間
即日續費(預設) IMMEDIATE 從辦理當日重新開始一個套餐週期,並提供新的資源量;確認成功後立即扣款
到期續費 ONEXPIRY 保留目前週期,在原到期日追加一個週期;可提前提交,確認成功後立即扣款

到期續費可以現在辦理,成功後到期日即獲延長。它不會等到到期日才發送請求或扣款。 例如 9 月 29 日辦理、原到期日為 10 月 15 日:即日續費的典型新到期日約為 10 月 29 日;到期續費約為 11 月 15 日。實際到期日以返回結果為準;渠道仍按已設定的該筆報價結算。

上面的範例明確選擇到期續費;省略 change_type 使用 IMMEDIATE,即日續費。已有訂單保留提交時記錄的方式。即日續費範例:

{
  "txid": "channel-renewal-immediate-001",
  "change_type": "IMMEDIATE",
  "items": [
    {
      "mdn": "2025550100"
    }
  ]
}

無需傳辦理日期,不支援 schedule_date、months 等排程或月數欄位。續三個月時,明確使用 ONEXPIRY 並分別提交三次:確認第一筆成功及到期資訊後再提交第二筆,再確認後提交第三筆。沒有返回到期日欄位時,不自行推算或併發補續。

預設 plan_change=false,續費原套餐。需換套餐續費時,傳 plan_change=true 和從目錄獲取的 plan_id;目標套餐必須開放且設定渠道價格。不要將獨立換套餐介面與換套餐續費混淆。

重新啟用

POST /jobs/reactivations

{
  "txid": "channel-reactivation-001",
  "items": [
    {
      "mdn": "2025550100"
    }
  ]
}

恢復原線路,按原套餐續費價收費;不能傳新套餐。缺少 mdn 時可只傳已登記的 ICCID 或 enrollment_id。是否可恢復取決於線路實際狀態,介面受理不等於成功。

地址可省略,指線路的街道、城市、州和 ZIP。這套補齊規則也適用於手動 WFC:

優先順序 地址來源 具體含義
1 本次請求明確提供的欄位 items[].customer 覆蓋 defaults;ZIP 再以 items[].zip 為優先
2 本地號卡已登記的服務地址 使用該卡成功開卡時保存或後續同步取得的完整有效地址
3 同卡最近成功開卡的地址快照 本地號卡地址缺失或無效時,查找同一 ICCID 最近一次成功開卡的地址;不使用失敗訂單地址
4 線路目前登記的 WFC/服務地址 本地兩處均無有效地址時,將未填欄位交由線路目前記錄補齊

地區套餐目錄是開卡時可選的套餐與地址資料;不會僅按城市或 ZIP 從目錄任選一條地址。使用目錄成功開卡後,當時的地址會保存到該卡及訂單;後續修改目錄不改寫原開卡地址快照。建單時確定的地址隨本次請求保存,排隊及手動重試沿用原參數。

只傳 ZIP 不會強制要求重傳完整地址;明確覆蓋的 ZIP 應與街道、城市及州一致。是否符合 WFC 資格以實際結果為準。這些是線路服務地址,不是渠道公司或帳單收件地址。可選姓名、電子郵件及 address_two 的空字串按未填處理;必填的開卡地址仍須完整有效。

檢查 items[].result.wifi_calling。WFC 失敗不會撤銷已成功的重新啟用,主業務仍按成功結算。

手動開啟 Wi-Fi Calling

POST /jobs/wifi-calling

{"txid":"channel-wfc-001","items":[{"mdn":"2025550100"}]}

使用已登記的 mdn、esn 或 enrollment_id;feature_action 預設 Active,目前只支援開啟。地址補齊方式與重新啟用相同。不單獨收費、不扣渠道餘額,也不產生扣款流水;仍建立逐卡業務記錄並提供任務結果及簽名回呼。

補開是否成功以本次 WFC 任務結果為準;原重新啟用任務中的 wifi_calling 結果保留當時記錄,不會改寫歷史結果。

查詢結果

  • GET /jobs/{id}:按返回的任務 ID 或 txid 查詢。
  • GET /jobs?txid=...:按批次交易號或逐卡交易號查詢。
  • GET /jobs?status=running:返回本渠道的任務列表;預設每頁 100 條,page、per_page 可分頁,依據 pagination.has_more 繼續讀取。
  • GET /jobs/{id}/items?status=failed:查詢任務的失敗明細;返回該批全部匹配明細,不分頁。

使用逐卡 txid 查詢時,只返回該卡明細,match=item_txid;批次 txid 或任務 ID 返回整批。一次查詢任務即可讀取 items,不必逐卡發送查詢。

指定任務 ID 或 txid 查詢處理中任務時,會補取一次原批次結果;已確認完成的任務直接返回,不額外查詢。排隊中尚未發送的任務不會因查單而開始辦理。任務列表顯示已同步快照;補查失敗或已有查詢正在進行時,可能仍返回待確認狀態,請留意 last_error 並稍後查詢。

JSON 成功回應統一為 data 和 meta。業務結果 data 內有 job 和 items;job.id 是此介面可查詢的任務編號,items[].id 是重試使用的明細編號。

層級 狀態 含義
job queued 排隊;paused=true 時需儲值恢復
job running 處理中或結果待確認
job succeeded 全部成功
job failed 全部失敗
job partial 全部處理結束,部分成功、部分失敗
item pending / processing 未完成,不扣款
item succeeded 成功,按該明細報價扣款
item failed 失敗,不扣款

job.billing.amount 是已建立的逐卡報價合計;無法報價的本地失敗明細金額為 0,表示沒有有效報價,不代表免費業務。手動 WFC 為明確免費的例外。charged_amount 是已扣金額。items[].billing.price 是該條報價。result 保留已核實的業務結果,包括返回的號碼、Enrollment ID、到期日等;只展示實際返回的欄位,不保證每個介面都有到期日。finished_at 是處理完成時間,不是服務到期日。

結果若明確返回格式無效的手機號碼,或續費、重新啟用、WFC 返回與原號碼不符的號碼,該明細保持待核實且不扣款,並補查原任務。可選號碼欄位未返回不等同於號碼衝突;不會因此重新提交辦理。

單條業務的明細 txid 與批次 txid 相同;多條業務的明細 txid 為「批次 txid_卡號後八位」,返回的逐卡交易號最長為 73 位。若同批卡號後八位重複,請拆分提交。

業務通用規則

  • 一次請求對應一個任務,每批至少一條 items,不設固定條數上限,按每張卡記錄結果和計費。
  • 建議每筆請求提供 txid,渠道內唯一,1–64 位字母、數字、點、底線、冒號或連字符。相同 txid 再提交返回 409,使用原 txid 查詢結果。
  • 預設非同步處理,mode 可省略或傳 async。未完成返回 HTTP 202;若全部明細在本地校驗時已失敗,也會直接返回 HTTP 200。mode=sync 嘗試立即辦理,整批已有最終結果返回 200,否則返回 202。200 不代表業務成功,202 也只表示已受理;請讀取逐卡最終狀態。
  • 每條 items 使用 esn(ICCID)、mdn(10 位美國手機號碼)或 enrollment_id。開卡支援 esn、mdn;續費、重新啟用及手動 WFC 支援三種標識。多個標識同傳必須能在本渠道登記記錄中對應同一張卡。未登記手機號碼的舊卡可先呼叫 /cards/{iccid}/sync。
  • 辦理使用平台已登記的號卡、套餐、地址及渠道報價,不在提交前逐卡查詢線路或再次查詢套餐目錄。查詢與資料同步介面可按需單獨呼叫,不是辦理前置步驟。
  • 逐卡本地地址、套餐或報價校驗失敗,只記錄該卡錯誤,其餘明細繼續同批提交。身份、歸屬、重複卡號、共同參數或可辦理明細總額不足等整體錯誤仍拒絕請求。
  • 整批按提交時的渠道售價檢查餘額,不凍結。發送前再次檢查餘額;不足時暫停,儲值後 resume。成功明細才扣款,失敗不扣,部分成功只扣成功部分。
  • 每張卡的未完成業務互斥;同一渠道的前序扣費任務結果未明時,後續扣費任務排隊,避免在不凍結資金的前提下超額辦理。免費 WFC 與其他卡的收費業務互不阻塞;同一卡片仍須等待前序業務完成。
  • 套餐的開卡、續費、重新啟用按渠道價格單結算。已採用統一價格單的渠道不重複扣卡板或 eSIM 銷售費用。
  • 區號只是參考,不能傳 area_code 指定號碼。具體號碼和區號以實際辦理結果為準。

異常恢復

辦理中的內部重試不需要渠道再次提交;等待同一任務的最終結果即可。平台不因內部重試次數增加而另建訂單或重複扣款。

服務重啟時,確認尚未發送的任務自動恢復排隊;可能已送出或缺乏發送階段記錄的任務只查詢原任務。渠道無需另建 txid。

明確失敗先保留失敗結果並進入異常待解決,不自動重試。 渠道透過查單或已設定的回呼取得 status=failed、錯誤原因及 retryable;失敗不扣款。retryable=true 只代表可以主動重試,不代表必須重試。地址、套餐、報價等錯誤同樣保留在異常待解決;其他有效明細照常處理。待解決是營運處理標記,API 業務狀態仍是 failed,不會改成 pending。

未建立任務就被拒絕的請求,直接返回 HTTP 錯誤;已認證渠道的業務參數等拒絕也會記錄到異常。沒有任務就沒有逐卡回呼,可依 meta.request_id 與錯誤碼排查。修正已失敗任務的參數時,使用新 txid 建立新請求;需要保留原參數再辦時,才主動呼叫 retry。

以下三個操作可省略請求體,或傳空 JSON 物件 {},不需要重傳原業務參數。有請求體時須使用 Content-Type: application/json;非空物件或格式錯誤返回 400,超過 200,000 字節返回 413,非 JSON 類型返回 415。

POST /jobs/{id}/recheck:只查詢原任務,不重新提交辦理請求。首次確認成功時正常記帳,重複查詢不重複扣款。已受理的任務優先等待最終回呼;五分鐘仍無最終結果時補查原批次。結果不明、回呼不完整或衝突時可提前補查。累計嘗試達 20 次後(含首次發送),attention_required=true,仍每五分鐘補查,不會自動重辦。

POST /jobs/{id}/resume:儲值後恢復餘額不足而暫停的任務,繼續使用原報價。若餘額仍不足,返回 HTTP 402,任務保持暫停。

POST /jobs/{id}/items/{itemId}/retry:僅允許 result.retryable=true 且有原任務及明細編號的失敗明細,不要求 attempt_count 必返。核實問題後,即使同批其他明細仍在處理,也可主動提出重試;重試排隊等待前序處理完成,沿用原參數與報價。成功、處理中和結果不明的明細不允許重試。重試仍校驗本地歸屬、線路狀態、餘額及原套餐;修改業務參數需要新建任務。此介面的 HTTP 200 只表示已安排重試,須繼續查詢任務或等待回呼確認結果。

HTTP 409 重複 txid:查原單。提交請求網路超時:查原 txid,不換編號重複辦理。HTTP 402:餘額不足。HTTP 401:檢查渠道帳戶、API Key 及是否已重置金鑰。HTTP 429:遵循 Retry-After 等待。錯誤的 error.details.business_code 是具體業務原因;排障提供 meta.request_id、txid 和任務 ID,不提供密鑰。

回呼

後台登記渠道回呼 HTTPS 地址;也可在辦理時傳 webhook_url 覆蓋本任務地址。回呼在結果核實與記帳後發出,不因重複通知再次扣款。未設定回呼時通過任務查詢獲取結果。

通知寫入後即觸發投遞,已到投遞時間的通知會連續發送,不設每秒或每輪固定筆數限制。失敗通知才按下列間隔等待重送;實際送達時間取決於接收端與網路。

已驗簽、能關聯本次辦理的逐卡最終結果直接更新訂單,不要求再查一次才能確認。未確認的結果只有批次匯總、缺少關聯資訊、內容衝突或無法區分手動重試的新舊結果時,才補查原任務;缺少回呼時亦保留補查。已確認終態後再收到相反結果,保留原結算並記錄異常待核實,不自動改成成功、失敗或再次扣款。事件建立時間不能代替未返回的處理完成時間或服務到期日。

事件類型:activation.item.succeeded、activation.item.failed、activation.job.completed;續費將前綴替換為 renewal,重新啟用替換為 reactivation,手動開啟 WFC 替換為 wifi_calling。

請求頭:

  • X-RM-Event:與 JSON type 一致。
  • X-RM-Delivery-Id:本次投遞編號,重投時改變;事件去重使用 JSON id。
  • X-RM-Signature:sha256=<十六進制簽名>。

使用渠道 Webhook Secret 對未經 JSON 解析或重新序列化的原始請求體計算 HMAC-SHA256。簽名不拼接時間戳。驗簽通過後按 id 持久化去重並返回 HTTP 2xx。重複的有效事件也返回 2xx。首次投遞失敗後,平台最多自動重試 5 次,間隔為 30、60、120、240、480 秒,指數退避上限為 15 分鐘;包括首次在內最多投遞 6 次。管理員可在後台重新投遞原事件。重投只補發通知,不重新辦理業務或扣款。事件可能重複或亂序,最終狀態以任務查詢為準。

回呼不發送 X-Partner-Id 或 X-API-Key,created_at 表示事件建立時間;接收端使用上述獨立簽名驗證。

{
  "id": "evt_example",
  "created_at": "2026-10-02T12:00:00Z",
  "type": "activation.item.succeeded",
  "data": {
    "job_id": "ord_example",
    "item_id": "item_example",
    "job_txid": "channel-activation-001",
    "txid": "channel-activation-001",
    "esn": "89000000000000000001",
    "status": "succeeded",
    "mdn": "2025550100"
  }
}

參見資料包 webhook-verify.mjs。Node.js 22+ 可運行 node --test webhook-verify.test.mjs 驗證示例。

查詢、庫存和帳單介面

方法 路徑 用途
GET /status 服務狀態,不需認證
GET /customers?esn=... 查詢本渠道線路資料;esn、mdn、enrollment_id 只能選一個查詢鍵
GET /mdns/{mdn} 按手機號碼查詢線路
GET /mdns/{mdn}/usage 查詢用量,預設 summary=true;明細用 from、to,最近 90 天內
GET /esns/{esn}/status 查詢卡狀態
POST /addresses/validate 校驗真實地址與 WFC 地址資格;不會開啟 Wi-Fi Calling
GET /cards 本渠道號碼庫存,分頁
POST /cards/{iccid}/sync 同步已歸屬卡的線路、套餐和地址資料,不扣費
GET /cards/{iccid}/esim 讀取已登記的 eSIM 安裝資料,不生成新安裝碼
GET /balance 查詢可用餘額
GET /ledger 儲值、消耗及餘額流水,分頁
GET /ledger/summary 同篩選條件的流水匯總
GET /ledger/export 導出同條件 CSV
GET /plans 按 ZIP 查目前可售套餐及渠道報價
GET /regional-catalog 套餐、地址、唯一碼和區號目錄
GET /regional-catalog/{id} 讀取一條地區套餐目錄
GET /zip-regions 郵編、城市、州與參考區號
GET /zip-regions/{zip} 讀取一條地區記錄

線路、手機號碼、用量查詢及帶 enrollment_id 的地址校驗,若識別資料對應本渠道多張卡,返回 HTTP 409,error.details.business_code=AMBIGUOUS_IDENTIFIER;請先核實歸屬記錄。

POST /cards/{iccid}/sync 須使用 Content-Type: application/json 並傳空物件 {},只讀取並同步已登記線路資料;不能用它提交新號碼或修改套餐。非空請求物件返回 HTTP 400。

帳單 from、to 使用 America/New_York,與華盛頓特區對帳使用相同當地日期,包含起止日期當天並自動處理夏令時間。依實際入帳或扣款時間統計;時間欄位仍可用 UTC ISO 格式表示同一時刻。summary 涵蓋全部篩選結果,不受分頁影響,金額均為 USD 字串。

請求上限為每渠道每分鐘 120 次,已認證任務 GET 查詢不計入該額度。JSON 請求體不超過 200,000 字節。服務擁堵時任務會排隊。

目前開放開卡、續費、重新啟用、免費手動開啟 Wi-Fi Calling 及上述查詢、帳戶能力。獨立停機、加購、獨立換套餐、手動關閉 WFC 暫未開放。正式環境成功的收費業務會實際消耗渠道餘額;介面不包含自動儲值或線上收款。

進階選項與相容接入

下列選項不是日常辦理的必要步驟。

  • 自訂地址:不用目錄唯一碼時,改傳介面 plan_code 和完整地址,見下方範例。GET /plans?zip=36104 可取得套餐代碼、ID 及渠道價格。plan_code 不是 Plan 65 等展示名稱,也不是 product_code。cost 為相容欄位,目前為 null;結算請讀取 price、prices 或訂單 billing。
  • defaults 設定批次地址;items[].customer 覆蓋客戶或地址欄位,items[].zip 覆蓋 ZIP。姓名及 email 可選。carrier 僅支援 TMB;enrollment_type 預設 HANDOVER(卡已在使用者手中),SHIPMENT 表示待寄送。開卡不接受 address_two,套房或樓層資訊放在 address。/addresses/validate 可用於自訂地址資格校驗,使用目錄時不是必經步驟。
  • mode=sync 嘗試立即辦理,只有處理完成才返回 200,排隊或結果待確認仍返回 202,不能保證同步完成。
  • 請求體未傳 txid 時,可用 Idempotency-Key 或 txid 請求標頭;均未提供則生成。建議在 JSON 傳 txid,遇到提交結果不明時才能按原交易號查詢。
  • 已使用 token 的渠道可保留 POST /auth,傳 partner_id、api_key,再使用 Authorization: Bearer <token>,有效期 30 分鐘。相容認證介面每 IP 每分鐘最多 20 次。固定 Key 新接入無需呼叫;兩者使用相同的新版請求、結果和回呼格式。
  • 舊版 Authorization: Bearer <API Key> 保留原請求、結果及回呼格式。從舊版遷移時須同步修改這三種格式,不能只改標頭。固定 Key 新接入須同時傳帳戶和 Key,不傳 Authorization。

自訂地址開卡範例:

{
  "txid": "channel-activation-002",
  "defaults": {
    "enrollment_type": "HANDOVER",
    "address": "1 Example Street",
    "city": "Montgomery",
    "state": "AL",
    "zip": "36104"
  },
  "items": [
    {
      "esn": "89000000000000000001",
      "plan_code": "PLAN_CODE_FROM_CATALOG"
    },
    {
      "esn": "89000000000000000002",
      "plan_code": "PLAN_CODE_FROM_CATALOG"
    }
  ]
}

cost 是保留的相容欄位,目前為 null,不代表零成本或售價。GET /plans 的 price 是單週期續費價,未設定時為 null;其他業務報價讀取 prices,已建立訂單讀取 billing。缺省的 attempt_count 不阻止普通終態確認;只有明確較舊的次數才作為舊結果證據。對明確尚未受理、且可安全重試的暫時性服務拒絕,平台可在等待後使用原交易識別恢復發送。這不是對已失敗業務的自動重辦,渠道應繼續查詢原 txid。網路斷線、無法解析的成功回應或其他不明結果,平台只查原任務,不再次發送業務。