Partner API documentation

G-Starlink Hub Partner API -- 快速接入指南

接口地址: https://api.gstarlink.com API 版本: v1 认证方式: OAuth 2.0 Client Credentials

本指南面向需要对接 G-Starlink Hub Partner API 的代理商和经销商,涵盖产品浏览、下单、获取 eSIM 交付信息以及 Webhook 事件通知的完整流程。


官方 SDK

本指南中的示例使用原始 curl 命令,便于理解底层 HTTP 调用。我们同时提供四种语言的零依赖单文件 SDK,自动处理 OAuth 令牌管理和 Webhook 签名验证:

语言文件环境要求
TypeScript / JavaScriptsdk/esim-atlas-sdk.tsNode.js 18+ 或现代浏览器
Pythonsdk/esim_atlas_sdk.pyPython 3.8+(仅标准库)
PHPsdk/esim-atlas-sdk.phpPHP 8.0+(需 cURL 和 JSON 扩展)
Rubysdk/esim_atlas_sdk.rbRuby 3.0+(仅标准库)

安装方法、快速开始和完整方法列表见 SDK README


服务范围免责声明

我们的服务保障仅覆盖充值面额本身。 对于预付费 SIM 卡产品和充值, 我们保证所购面额足额到账(如 $39 充值即 $39 到账)。该面额对应的套餐 内容——流量额度、赠送流量(Bonus Data)、通话、有效期——完全由运营商 设定,可能随时变化,恕不另行通知

例如:运营商可能宣传 $39 预付费套餐含 65GB 流量,实际构成为 25GB 标准 流量 + 40GB 促销赠送流量。赠送部分属于运营商促销活动,可能在下个月 缩水、增加或直接取消。对于宣传套餐内容与实际到账内容之间的差异,我们 不承担任何责任。转售给您的客户之前,请务必以运营商官网当前公布的套餐 内容为准。


目录

  1. 获取 API 凭证
  2. 沙箱环境
  3. 认证
  4. 浏览产品
  5. 创建订单
  6. 获取 eSIM 交付信息
  7. 查询 eSIM 状态
  8. Webhook 事件通知
  9. 端到端集成示例
  10. 状态生命周期
  11. 错误处理
  12. 频率限制
  13. 完整 API 文档

0. 获取 API 凭证

密钥由您在合作伙伴门户中自助生成。我们为您开通账户并发送邀请,之后全部自助完成。

  1. 我们创建您的合作伙伴账户并向您发送邀请邮件。设置密码后登录 https://hub.gstarlink.com/dashboard/partner
  2. API Keys 中生成密钥,您会得到 client_id(以 sk_test_ 开头) 和 client_secret请立即复制保存密钥 —— 它只显示一次,无法找回,只能重新生成。
  3. 使用这些凭证获取访问令牌(参见下方认证章节)
  4. 在沙箱环境中完成并验证您的集成
  5. 准备上线时,请联系客户经理为您开通生产环境。开通后,您即可在同一页面 自助生成 sk_live_* 生产密钥。

门户中还可以注册 Webhook 端点、查看 API 用量,以及为订单扣款的钱包充值。

密钥可随时在门户中吊销和重新生成。


1. 沙箱环境

G-Starlink Hub 提供沙箱环境,供您在不影响生产数据且不产生费用的情况下测试集成。

沙箱工作方式

  • 沙箱使用相同的接口地址:https://api.gstarlink.com
  • 沙箱 API 密钥使用 sk_test_* 前缀;生产密钥使用 sk_live_*
  • 沙箱密钥请在合作伙伴门户的 "API Keys" 中自助生成
  • 使用沙箱凭证创建的订单会被标记为测试订单(metadata 中 "test": true), 并在数秒内自动履约——无需支付,不占用真实库存
  • 沙箱订单调用 GET /orders/{id}/esims 返回合成的测试 eSIM:确定性 ICCID(8999 前缀)、沙箱 SM-DP+ 地址、每条记录带 is_test: true。 这些 eSIM 无法在真实设备上激活
  • 沙箱订单会触发 order.createdorder.fulfilled Webhook, 完整的「下单 → Webhook → 取 eSIM」链路可以端到端测试

测试检查清单

  1. 生成沙箱 API 密钥(sk_test_*
  2. 使用沙箱凭证获取访问令牌
  3. 浏览产品(与生产环境使用相同的产品目录)
  4. 注册订阅 order.createdorder.fulfilled 事件的 Webhook
  5. 创建测试订单——返回 pending_payment 后自动履约, 数秒内收到 order.fulfilled Webhook
  6. 调用 GET /orders/{id}/esims 获取并处理合成测试 eSIM
  7. 集成验证通过后,切换到生产凭证(sk_live_*

沙箱限制

  • eSIM 为合成数据(is_test: true),无法安装到真实设备
  • 实体 SIM 卡激活(POST /activations不做模拟——会进入真实激活 队列,请只提交您自己持有的真实 SIM 卡
  • 支付/钱包扣款为模拟操作(沙箱订单跳过支付环节)

2. 认证

API 使用 OAuth 2.0 Client Credentials 流程。您需要从 G-Starlink Hub 账户管理员处获取 client_idclient_secret

第一步:获取访问令牌

curl -X POST https://api.gstarlink.com/api/v1/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "scope": "read:products write:orders read:orders read:esims write:webhooks read:webhooks"
  }'

返回结果:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read:products write:orders read:orders read:esims write:webhooks read:webhooks"
}

第二步:使用令牌

在后续所有请求中携带 Authorization 头:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

令牌有效期为 1 小时(3600 秒),过期后需重新获取。

可用权限范围

Scope说明
read:products浏览产品目录
read:orders查看订单
write:orders创建订单
read:esims获取 eSIM 交付详情
read:webhooks查看 Webhook 列表
write:webhooks创建/管理 Webhook

3. 浏览产品

获取产品列表

curl -X GET "https://api.gstarlink.com/api/v1/products?limit=10&region=Asia" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

返回结果:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "sku": "ASIA-5GB-30D",
      "name": "Asia 5GB - 30 Days",
      "description": "Data-only eSIM for 12 Asian countries",
      "region": "Asia",
      "coverage": ["JP", "KR", "TH", "SG"],
      "data_amount_mb": 5120,
      "validity_days": 30,
      "price_cents": 1999,
      "currency": "USD",
      "type": "data_only",
      "status": "active"
    }
  ],
  "pagination": {
    "has_more": true,
    "next_cursor": "eyJjcmVhdGVkX2F0Ijo..."
  }
}

查询参数

参数类型默认值说明
limitnumber20每页数量(最大 100)
cursorstring--上一页返回的分页游标
regionstring--按区域筛选(如 AsiaEurope
typestring--data_onlyvoice_data
statusstringactiveactiveinactiveout_of_stock
sort_bystringcreated_atcreated_atprice_centsname
sort_orderstringdescascdesc

获取单个产品详情

curl -X GET "https://api.gstarlink.com/api/v1/products/550e8400-e29b-41d4-a716-446655440001" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

4. 创建订单

单笔订单

curl -X POST https://api.gstarlink.com/api/v1/orders \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: YOUR_UNIQUE_IDEMPOTENCY_KEY" \
  -d '{
    "line_items": [
      {
        "product_id": "550e8400-e29b-41d4-a716-446655440001",
        "quantity": 5
      }
    ]
  }'

返回结果:

{
  "id": "order-uuid-here",
  "order_number": "ORD-20260413-ABC12",
  "status": "pending_payment",
  "total_amount_cents": 9995,
  "currency": "USD",
  "created_at": "2026-04-13T10:00:00Z"
}

注意: 务必传入 Idempotency-Key 请求头(建议使用 UUID)。相同的 key 会返回之前创建的订单,避免重复下单。

提示: 部分产品需要预约激活(如通过 EID 推送交付的 eSIM)。 对于这类产品,需要在订单中包含 activation_requests 字段。请检查产品的 delivery_method 字段 -- 如果值为 supplier_emaileid_push,则必须提供激活信息。

批量订单(电商平台集成)

单次请求最多可创建 100 笔订单:

curl -X POST https://api.gstarlink.com/api/v1/orders/bulk \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "orders": [
      {
        "external_order_id": "SHOP-10001",
        "line_items": [
          { "product_id": "PRODUCT_ID_1", "quantity": 1 }
        ],
        "customer": {
          "email": "customer1@example.com",
          "name": "Alice"
        }
      },
      {
        "external_order_id": "SHOP-10002",
        "line_items": [
          { "product_id": "PRODUCT_ID_2", "quantity": 2 }
        ],
        "customer": {
          "email": "customer2@example.com",
          "name": "Bob"
        }
      }
    ]
  }'

批量订单中每笔订单独立处理,返回结果包含每笔订单的成功/失败状态。

查看订单列表

curl -X GET "https://api.gstarlink.com/api/v1/orders?limit=20" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

查看订单详情

curl -X GET "https://api.gstarlink.com/api/v1/orders/ORDER_ID" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

5. 获取 eSIM 交付信息

订单履约后,可获取 eSIM 的激活码和二维码:

curl -X GET "https://api.gstarlink.com/api/v1/orders/ORDER_ID/esims" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

返回结果:

{
  "order_id": "order-uuid-here",
  "esims": [
    {
      "id": "esim-uuid",
      "iccid": "8944501234567890123",
      "activation_code": "LPA:1$smdp.example.com$ACTIVATION_CODE",
      "qr_code_url": "https://api.gstarlink.com/qr/esim-uuid.png",
      "status": "inactive"
    }
  ],
  "count": 5
}

交付给终端用户的关键信息:

  • activation_code -- 用户在设备上手动输入的 LPA 激活码
  • qr_code_url -- 可扫描安装的二维码图片链接

6. 查询 eSIM 状态

通过 ICCID 查询单个 eSIM 的实时状态:

curl -X GET "https://api.gstarlink.com/api/v1/esims/8944501234567890123/status" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

查询订单激活状态

对于供应商交付的产品,可查询激活进度:

curl -X GET "https://api.gstarlink.com/api/v1/orders/ORDER_ID/activation-status" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

返回结果:

{
  "order_id": "order-uuid",
  "order_number": "ORD-20260413-ABC12",
  "has_scheduled_activations": true,
  "total_activations": 1,
  "pending_count": 0,
  "submitted_count": 1,
  "activated_count": 0,
  "failed_count": 0,
  "activations": [
    {
      "item_id": "order-item-uuid",
      "product_name": "Europe 10GB - Orange",
      "status": "submitted",
      "customer_email": "customer@example.com",
      "activation_date": "2026-05-01",
      "submitted_at": "2026-04-13T10:30:00Z"
    }
  ]
}

激活状态说明:

状态说明
pending待处理,尚未提交给供应商
submitted已提交给供应商
confirmed供应商已确认收到
activated激活成功
failed激活失败
cancelled已取消

6b. 查询钱包余额

curl -X GET "https://api.gstarlink.com/api/v1/balance" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

返回结果:

{
  "balances": [
    {
      "currency": "USD",
      "balance_cents": 250000,
      "last_transaction_at": "2026-07-13T08:15:00Z"
    }
  ],
  "count": 1
}

余额按币种分别记账。订单以产品所属币种扣款,请确保对应币种的钱包已充值。


7. Webhook 事件通知

注册 Webhook

curl -X POST https://api.gstarlink.com/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/esim-atlas",
    "events": [
      "order.created",
      "order.fulfilled",
      "esim.activated",
      "activation.activated",
      "activation.failed"
    ]
  }'

返回结果:

{
  "webhook": {
    "id": "wh_uuid",
    "url": "https://your-app.com/webhooks/esim-atlas",
    "events": ["order.created", "order.fulfilled", "esim.activated", "activation.activated", "activation.failed"],
    "status": "active"
  },
  "secret": "whsec_..."
}

请立即保存 secret 该密钥仅在创建时显示一次,用于验证 Webhook 签名。

支持的事件类型

事件说明
order.created订单已创建
order.fulfilledeSIM 已分配
order.cancelled订单已取消
esim.activatedeSIM 已在设备上激活
esim.expiredeSIM 已过期
payment.completed支付成功
payment.failed支付失败
activation.submitted激活请求已提交给供应商
activation.confirmed供应商已确认收到
activation.activated激活完成
activation.failed激活失败

Webhook 载荷示例

每次 Webhook 推送会发送一个 JSON 载荷,包含事件类型、唯一事件 ID、时间戳和事件数据。

order.created

{
  "event": "order.created",
  "event_id": "evt_abc123",
  "timestamp": "2026-04-13T10:00:00Z",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "order_number": "ORD-20260413-A1B2C",
    "status": "pending_payment",
    "total_price_cents": 1500,
    "currency": "USD",
    "line_items": [{ "product_id": "...", "quantity": 1 }]
  }
}

order.fulfilled

{
  "event": "order.fulfilled",
  "event_id": "evt_def456",
  "timestamp": "2026-04-13T10:05:00Z",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "order_number": "ORD-20260413-A1B2C",
    "status": "fulfilled",
    "esims": [
      {
        "iccid": "8901234567890123456",
        "activation_code": "LPA:1$smdp.example.com$MATCHING_ID",
        "qr_code_url": "https://api.gstarlink.com/qr/esim-uuid.png"
      }
    ]
  }
}

activation.activated

{
  "event": "activation.activated",
  "event_id": "evt_ghi789",
  "timestamp": "2026-04-13T10:10:00Z",
  "data": {
    "id": "75f7b6f8-1234-5678-9abc-def012345678",
    "iccid": "8961030000012345678",
    "carrier": "Lycamobile",
    "mobile_number": "0402033268",
    "status": "completed"
  }
}

activation.failed

{
  "event": "activation.failed",
  "event_id": "evt_jkl012",
  "timestamp": "2026-04-13T10:10:00Z",
  "data": {
    "id": "75f7b6f8-1234-5678-9abc-def012345678",
    "iccid": "8961030000012345678",
    "carrier": "Lycamobile",
    "error_type": "carrier_error",
    "error_message": "ID verification failed",
    "status": "failed"
  }
}

推送机制

  • 重试策略: 最多 5 次,指数退避间隔(1s, 2s, 4s, 8s, 16s)
  • 超时: 接收端点须在 10 秒内响应
  • 预期响应: HTTP 2xx 状态码

签名验证(Node.js 示例)

每个 Webhook 请求都包含 X-Webhook-Signature 请求头,格式为 t=TIMESTAMP,v1=SIGNATURE

const crypto = require('crypto');

function verifyWebhookSignature(payload, signatureHeader, secret) {
  // Parse the signature header
  const parts = signatureHeader.split(',');
  const timestampPart = parts.find(p => p.startsWith('t='));
  const signaturePart = parts.find(p => p.startsWith('v1='));

  if (!timestampPart || !signaturePart) {
    return false;
  }

  const timestamp = timestampPart.split('=')[1];
  const receivedSignature = signaturePart.split('=')[1];

  // Reject requests older than 5 minutes (replay attack prevention)
  const age = Math.abs(Date.now() / 1000 - parseInt(timestamp, 10));
  if (age > 300) {
    return false;
  }

  // Compute expected signature: HMAC-SHA256(timestamp + "." + payload, secret)
  const signedPayload = `${timestamp}.${payload}`;
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');

  // Timing-safe comparison
  return crypto.timingSafeEqual(
    Buffer.from(receivedSignature),
    Buffer.from(expectedSignature)
  );
}

// Usage in an Express handler
app.post('/webhooks/esim-atlas', (req, res) => {
  const payload = JSON.stringify(req.body);
  const signature = req.headers['x-webhook-signature'];

  if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const event = req.body;
  console.log('Received event:', event.type);

  // Process the event...

  res.status(200).send('OK');
});

查看 Webhook 列表

curl -X GET "https://api.gstarlink.com/api/v1/webhooks" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

8. 端到端集成示例

完整工作流程:认证、查找产品、下单、获取 eSIM。

#!/bin/bash
# G-Starlink Hub Partner API — Complete Integration Example
# G-Starlink Hub Partner API — 完整集成示例
# Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with real credentials
# 请将 YOUR_CLIENT_ID 和 YOUR_CLIENT_SECRET 替换为真实凭证

BASE_URL="https://api.gstarlink.com"

# Step 1: Get access token / 第一步:获取访问令牌
echo "=== Step 1: Authenticate ==="
TOKEN=$(curl -s -X POST "$BASE_URL/api/v1/oauth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET"
  }' | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
echo "Token: ${TOKEN:0:20}..."

# Step 2: Browse products (find Japan eSIM) / 第二步:浏览产品(查找日本 eSIM)
echo "=== Step 2: Find Products ==="
curl -s "$BASE_URL/api/v1/products?region=Asia&limit=3" \
  -H "Authorization: Bearer $TOKEN" | python3 -m json.tool | head -30

# Step 3: Get a specific product ID (use the first result) / 第三步:获取产品 ID(使用第一个结果)
PRODUCT_ID=$(curl -s "$BASE_URL/api/v1/products?region=Asia&limit=1" \
  -H "Authorization: Bearer $TOKEN" | python3 -c "import sys,json; print(json.load(sys.stdin)['data'][0]['id'])")
echo "Product ID: $PRODUCT_ID"

# Step 4: Check inventory / 第四步:检查库存
echo "=== Step 4: Check Availability ==="
curl -s "$BASE_URL/api/v1/inventory/status?product_ids=$PRODUCT_ID" \
  -H "Authorization: Bearer $TOKEN" | python3 -m json.tool

# Step 5: Create order / 第五步:创建订单
echo "=== Step 5: Create Order ==="
ORDER=$(curl -s -X POST "$BASE_URL/api/v1/orders" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: demo-$(date +%s)" \
  -d "{
    \"line_items\": [{
      \"product_id\": \"$PRODUCT_ID\",
      \"quantity\": 1
    }]
  }")
echo "$ORDER" | python3 -m json.tool
ORDER_ID=$(echo "$ORDER" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "Order ID: $ORDER_ID"

# Step 6: Check order status (poll until fulfilled) / 第六步:查询订单状态(轮询直到履约完成)
echo "=== Step 6: Check Order Status ==="
curl -s "$BASE_URL/api/v1/orders/$ORDER_ID" \
  -H "Authorization: Bearer $TOKEN" | python3 -m json.tool

# Step 7: Get eSIM delivery (only works when order is fulfilled) / 第七步:获取 eSIM 交付信息(仅在订单履约后可用)
echo "=== Step 7: Get eSIM Delivery ==="
curl -s "$BASE_URL/api/v1/orders/$ORDER_ID/esims" \
  -H "Authorization: Bearer $TOKEN" | python3 -m json.tool

echo "=== Done ==="

9. 状态生命周期

订单状态

pending_payment ──> paid ──> fulfilled
   │                 │
   │                 ├──> waiting_review ──> fulfilled
   │                 └──> failed
   │
   └──> cancelled
状态说明
pending_payment订单已创建,等待付款
paid已收到付款,开始履约
waiting_review履约前需人工审核
fulfilled订单完成,eSIM 已交付
failed履约失败(请查看错误详情)
cancelled订单已被合作伙伴或管理员取消

支付与履约如何进行

生产订单从您的预付钱包余额中扣款,API 中没有刷卡或收银台环节:

  1. 您通过银行转账为钱包充值(账户信息请向客户经理索取)。我们确认到账后, 余额即时入账。
  2. POST /orders原子性地从钱包扣除订单金额,订单直接创建为 paid 状态。若余额不足,订单不会被创建,返回 402 Insufficient Balance (见下)。
  3. 履约系统分配 eSIM,订单变为 fulfilled——此时 order.fulfilled Webhook 触发,GET /orders/{id}/esims 可获取交付详情。

随时可用 GET /balance 查询余额。每笔成功订单的响应中也会返回 wallet_balance_after_cents,无需额外请求即可掌握余额。

沙箱环境中支付为模拟:订单不会扣除钱包余额(无需充值),且数秒内自动履约。

余额不足(402)

{
  "type": "https://docs.gstarlink.com/errors/insufficient_balance",
  "title": "Insufficient Balance",
  "status": 402,
  "detail": "Wallet balance is too low for this order. Top up your account and retry.",
  "currency": "USD",
  "balance_cents": 905,
  "required_cents": 8190,
  "shortfall_cents": 7285
}

订单不会被创建,也不会扣款——充值后重试同一请求即可。

激活状态(实体 SIM 卡)

pending ──> processing ──> completed
                │
                └──> failed ──> manual_required
状态说明
pending激活请求已提交,排队等待处理
processing正在与运营商处理激活
completedSIM 卡激活成功,已分配手机号码
failed激活失败(身份验证失败、会话超时等)
manual_required达到最大重试次数后仍失败,需要人工介入

10. 错误处理

所有错误响应遵循 RFC 7807 Problem Details 标准格式:

{
  "type": "https://docs.gstarlink.com/errors/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "Invalid product_id in line_items[0]",
  "requestId": "req_abc123",
  "timestamp": "2026-04-13T10:00:00Z"
}

HTTP 状态码

状态码含义
200请求成功
201创建成功
400请求参数错误 -- 查看 detailtype 字段
401未认证 -- 令牌无效或已过期
403权限不足 -- 缺少所需的 scope
404资源不存在
409冲突 -- 幂等 key 重复但请求内容不同
429请求频率超限
500服务器内部错误

令牌过期处理

当令牌过期时,API 返回 401。重新获取令牌后重试即可:

# 1. Renew the token
curl -X POST https://api.gstarlink.com/api/v1/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET"
  }'

# 2. Retry the failed request with the new token

11. 频率限制

API 请求按 API Key 进行频率限制,当前限额如下:

级别每分钟请求数
标准版60
高级版300

触发限制时,API 返回 HTTP 429 并在 Retry-After 响应头中标明需要等待的秒数。


12. 完整 API 文档

完整的 OpenAPI 规范文件:


接入检查清单

  1. 从账户管理员处获取 client_idclient_secret
  2. 通过 OAuth 端点获取访问令牌
  3. 浏览产品目录,选择要销售的产品
  4. 使用幂等 key 创建测试订单
  5. 获取 eSIM 交付信息(二维码 + 激活码)
  6. 注册 Webhook 端点接收订单和激活事件
  7. 实现 Webhook 签名验证逻辑
  8. 在沙箱环境(sk_test_* 密钥)中完成端到端测试
  9. 确认无误后切换到生产密钥(sk_live_*)正式上线