# 商戶自有授權系統適配器示例

此 Python 3.10+ 示例實現 Launch 外部 HTTP 橋接，使用 SQLite 持久化事件和 nonce，并提供恢復工作進程。它**不會**生成許可證、驗證受保護功能或替代你的授權系統。

實現提供以下鉤子的 Python 模塊：

```python
def apply_snapshot(snapshot):
    # Call your licensing system with snapshot["event_id"] as its durable
    # idempotency key. Apply desired_state and the absolute purchased dates.
    # Return only after confirming the original operation was applied.
    # Raise ValueError for a result requiring manual review.
    ...

def delivery(snapshot):
    # Read an existing result owned by this purchase; do not issue here.
    return {"type": "instructions", "value": "Your own delivery instructions", "expires_at": None}
```

配置后端前，必須用真實接入實現替換 `...`。如果沒有配置后端模塊，內置鉤子會拋出 `NotImplementedError`；事件轉入人工審核，絕不會聲稱已簽發授權。示例工作進程可能在崩潰或結果不確定的錯誤后重試鉤子，因此授權后端必須按同一事件 ID 去重和恢復結果。

通過環境變量配置適配器，密鑰不得進入源碼管理或命令歷史：

- `CUSTOM_LICENSING_KEY`：32–128 個隨機位元組的標準 Base64 編碼，必須與 Launch 一致。
- `CUSTOM_LICENSING_KEY_ID`：`key-1`，或你配置的密鑰標識。
- `CUSTOM_LICENSING_CONNECTION_REF`：相匹配的連接引用。
- `CUSTOM_LICENSING_ENVIRONMENT`：`sandbox` 或 `live`。
- `CUSTOM_LICENSING_DATABASE`：源碼目錄之外私有且可寫的 SQLite 路徑；重啟后仍須保留。
- `CUSTOM_LICENSING_BACKEND`：實現上述鉤子、可導入的模塊。
- `CUSTOM_LICENSING_PORT`：本地監聽連接埠，預設 `18883`。

運行 `python server.py`。本地 sandbox 測試時，在 Launch 中配置 `http://127.0.0.1:18883`，并明確啟用其回環 HTTP 例外。生產環境應使用 HTTPS 終止、進程監管、受保護的資料庫備份，以及后端自身的 SDK 或運行時授權校驗。只聲明后端實際支持的購買和交付類型，相應調整 `capabilities`。

修復后端問題后，`python server.py --retry-event ORIGINAL_EVENT_UUID` 會在本地將原來保存的同一請求內容重新入隊。還應在 Launch 的授權任務頁重試原事件。不得通過更換 ID 或再次增加時長來恢復響應。

該示例只提供起點，不能作為生產驗收證明。工作進程租約為 60 秒；鉤子調用超時必須更短，或續租。接收正式購買前，應補齊監控、密鑰輪換流程、更嚴格的業務與結構校驗，以及部署所需的運維控制。[接入指南](/zh-hant/launch-documents/external-licensing/)和 [OpenAPI](/zh-hant/assets/launch/external-licensing-openapi.json) 定義了協議。絕不能把 Launch 狀態響應當作運行受保護代碼的許可。
