PAYATHON 2026

如何通过 CSP Partner Center API 创建 Azure Subscription?

支付老李

结论

可以先通过 Partner Center API 创建 CSP Azure 订阅,再通过 Azure Resource Manager(ARM)API 部署 VM。客户通常不需要填写信用卡,也不需要进入 Azure Portal 创建订阅。

整个过程分为两个独立环节:

  1. Partner Center API 用于购买 Azure plan、创建 Azure subscription entitlement,并建立 CSP 计费关系。
  2. ARM API 用于在该 Azure subscription 中创建资源。调用 ARM 的身份必须存在于客户租户中,并拥有该订阅的 Azure RBAC 权限。

通过 Partner Center 创建订阅后,调用方不会自动获得 ARM 部署权限。很多集成问题出在第二步,并非订阅本身不可用。

为什么 Portal 会要求填写信用卡

CSP Azure 订阅由 CSP partner 或 indirect provider 结算,客户不需要再为该订阅绑定信用卡。

如果 Portal 要求补充 subscription profile 或付款方式,常见原因包括:

  • 登录 Azure Portal 时选择了错误的 Microsoft Entra tenant。
  • Portal 正在引导用户创建新的 Pay-As-You-Go 订阅,而不是使用已有的 CSP 订阅。
  • Azure entitlement 仍在 provisioning,尚未形成可用的 ARM subscription。
  • 当前用户没有 CSP 订阅的 RBAC 权限,因此 Portal 不会显示该订阅。
  • Partner Center 中只创建了 Azure plan 商业订阅,没有在该 plan 下创建 Azure entitlement。
  • CSP 商业关系、Microsoft Customer Agreement 或必要的客户确认尚未完成。

不要填写信用卡来「激活」CSP 订阅,否则可能会创建另一份与 CSP 计费无关的 Azure 订阅。

正确的对象关系

在 Azure plan 模型中,需要区分以下对象:

Customer
└── Azure plan                 Partner Center 中的计费容器
    └── Azure entitlement      对应一个实际 Azure subscription
        └── Resource group
            └── Virtual machine

Partner Center 中名为 Azure plan 的 subscription 通常只是计费容器。调用 ARM API 时,真正需要的是 Azure entitlement 对应的 Azure subscription ID。

如果只创建了 Azure plan,没有创建 entitlement,就不能使用 Azure plan 的 Partner Center subscription ID 部署 VM。

推荐流程

1. 创建客户并建立商业关系

通过 Partner Center API 创建客户,并确认已经完成当前 CSP 模型要求的以下事项:

  • reseller relationship;
  • Microsoft Customer Agreement 确认;
  • indirect reseller 与 indirect provider 之间的必要关系;
  • 客户租户和默认域创建。

客户创建完成后,保存其 Microsoft Entra tenant ID。后续从客户租户申请 ARM token 时会用到这个 ID。

2. 获取 Azure plan 的可售目录项

产品、SKU、availability 和 catalogItemId 可能随市场、CSP 类型和 Partner Center 当前目录变化,因此不应硬编码在程序中。

应查询客户所在市场的 Partner Center catalog,找到 Azure plan,再使用返回的 catalogItemId 创建订单。

订单结构示例如下:

POST https://api.partnercenter.microsoft.com/v1/customers/{customerId}/orders
Authorization: Bearer {partnerCenterAccessToken}
Content-Type: application/json
Accept: application/json
{
  "referenceCustomerId": "{customerId}",
  "lineItems": [
    {
      "lineItemNumber": 0,
      "offerId": "{catalogItemId}",
      "friendlyName": "Customer Azure Plan",
      "quantity": 1
    }
  ]
}

具体字段应以当前 Partner Center Azure plan 订单模型为准。不要用历史 Azure offer 的固定 ID 代替目录查询结果。

3. 在 Azure plan 下创建 Azure entitlement

取得 Azure plan 的 Partner Center subscription ID 后,在该 plan 下创建供客户实际使用的 Azure subscription。

典型请求如下:

POST https://api.partnercenter.microsoft.com/v1/customers/{customerId}/subscriptions/{azurePlanSubscriptionId}/azureEntitlements
Authorization: Bearer {partnerCenterAccessToken}
Content-Type: application/json
Accept: application/json
{
  "friendlyName": "Production Subscription"
}

随后查询 entitlement:

GET https://api.partnercenter.microsoft.com/v1/customers/{customerId}/subscriptions/{azurePlanSubscriptionId}/azureEntitlements
Authorization: Bearer {partnerCenterAccessToken}
Accept: application/json

响应中的 Azure subscription 标识才是调用 ARM API 时使用的 ID:

/subscriptions/{azureSubscriptionId}

创建过程可能异步执行。必须等到 entitlement 状态可用,并确认 ARM 已经能够查询对应的 subscription,才能继续部署 VM。不要在 Partner Center 返回创建成功后立即开始部署。

不同 Partner Center API 版本或合作伙伴类型使用的资源字段可能略有差异,应以实际响应中表示 Azure subscription/resource identifier 的字段为准。

两类 API 必须使用不同的 access token

Partner Center token

Partner Center API 使用面向 Partner Center 的 token:

POST https://login.microsoftonline.com/{partnerTenantId}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={appId}
&client_secret={clientSecret}
&grant_type=client_credentials
&scope=https%3A%2F%2Fapi.partnercenter.microsoft.com%2F.default

这个 token 只能调用 Partner Center API,不能直接用于 ARM。

ARM token

ARM token 必须从客户租户申请,audience/scope 应指向 Azure Resource Manager:

POST https://login.microsoftonline.com/{customerTenantId}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={appId}
&client_secret={clientSecret}
&grant_type=client_credentials
&scope=https%3A%2F%2Fmanagement.azure.com%2F.default

取得 token 后,使用它调用:

GET https://management.azure.com/subscriptions/{azureSubscriptionId}?api-version={supportedApiVersion}
Authorization: Bearer {armAccessToken}

如果返回 401,通常说明 token 的租户、audience 或应用凭据有误。

如果返回 403,通常说明身份验证已经成功,但应用对应的 service principal 没有该订阅的 Azure RBAC 权限。

必须解决客户租户中的身份和 RBAC

通过 client credentials 调用客户的 ARM,至少要满足以下条件:

  • 应用在客户 tenant 中存在 service principal;
  • 客户已经给予必要的租户级同意;
  • 该 service principal 在目标 subscription 或 resource group 上具有 Azure RBAC role assignment;
  • 申请 ARM token 时使用客户 tenant ID,而不是只使用 partner tenant ID。

角色应按最小权限原则分配。仅需创建和管理 VM 时,可以组合使用:

  • Virtual Machine Contributor
  • Network Contributor
  • Managed Identity Operator,如果 VM 使用托管身份
  • 目标 resource group 所需的其他权限

初次验证时也可以临时使用 Contributor,但该角色不能向其他主体授予 Azure RBAC 权限。验证完成后,应缩小权限范围。

创建角色分配的 ARM 请求示例如下:

PUT https://management.azure.com/subscriptions/{azureSubscriptionId}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentGuid}?api-version={supportedApiVersion}
Authorization: Bearer {bootstrapAccessToken}
Content-Type: application/json
{
  "properties": {
    "roleDefinitionId": "/subscriptions/{azureSubscriptionId}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionGuid}",
    "principalId": "{customerTenantServicePrincipalObjectId}",
    "principalType": "ServicePrincipal"
  }
}

执行该请求的引导身份必须已经拥有 Owner、User Access Administrator 或其他能够创建角色分配的权限。

还要注意,GDAP 是 Microsoft 365/客户租户的委派管理关系,不等同于 Azure subscription 上的 RBAC。Azure 管理权限仍需通过 Azure RBAC、适用的 CSP 委派机制或 Azure Lighthouse 明确配置。

使用 ARM API 创建 VM

开始部署资源前,先确认以下调用能够成功:

GET https://management.azure.com/subscriptions/{azureSubscriptionId}?api-version={supportedApiVersion}

首先创建 resource group:

PUT https://management.azure.com/subscriptions/{azureSubscriptionId}/resourcegroups/app-production?api-version={supportedApiVersion}
Authorization: Bearer {armAccessToken}
Content-Type: application/json
{
  "location": "eastasia"
}

然后依次创建:

  1. Virtual network 和 subnet
  2. Public IP(如果需要)
  3. Network interface
  4. VM、磁盘和相关扩展

VM 请求示例如下:

PUT https://management.azure.com/subscriptions/{azureSubscriptionId}/resourceGroups/app-production/providers/Microsoft.Compute/virtualMachines/app-vm-01?api-version={supportedApiVersion}
Authorization: Bearer {armAccessToken}
Content-Type: application/json
{
  "location": "eastasia",
  "properties": {
    "hardwareProfile": {
      "vmSize": "Standard_B2s"
    },
    "storageProfile": {
      "imageReference": {
        "publisher": "Canonical",
        "offer": "0001-com-ubuntu-server-jammy",
        "sku": "22_04-lts-gen2",
        "version": "latest"
      },
      "osDisk": {
        "createOption": "FromImage"
      }
    },
    "osProfile": {
      "computerName": "app-vm-01",
      "adminUsername": "azureadmin",
      "linuxConfiguration": {
        "disablePasswordAuthentication": true,
        "ssh": {
          "publicKeys": [
            {
              "path": "/home/azureadmin/.ssh/authorized_keys",
              "keyData": "{sshPublicKey}"
            }
          ]
        }
      }
    },
    "networkProfile": {
      "networkInterfaces": [
        {
          "id": "/subscriptions/{azureSubscriptionId}/resourceGroups/app-production/providers/Microsoft.Network/networkInterfaces/app-vm-01-nic"
        }
      ]
    }
  }
}

api-version 应选择各 Azure resource provider 当前支持的稳定版本,不要将示例版本长期写死。部署前还需要注册所需的 provider,例如:

POST https://management.azure.com/subscriptions/{azureSubscriptionId}/providers/Microsoft.Compute/register?api-version={supportedApiVersion}
Authorization: Bearer {armAccessToken}

通常还需要注册:

Microsoft.Compute
Microsoft.Network
Microsoft.Storage
Microsoft.ManagedIdentity

provider 注册也可能异步完成。

是否能做到完全不跳转 Microsoft Portal

资源购买、订阅创建、RBAC 配置和 VM 部署都可以通过 API 完成。

但能否完全不出现 Microsoft 页面,取决于前置关系是否已经建立。以下操作可能需要客户管理员完成一次交互确认:

  • CSP reseller relationship;
  • Microsoft Customer Agreement;
  • 应用的 Microsoft Entra admin consent;
  • Azure Lighthouse onboarding 或其他委派授权。

这些操作涉及授权或合同确认,无法通过普通后台 API 静默绕过。一次性授权完成后,日常创建 Azure entitlement 和部署资源可以由应用后台自动执行。

排查顺序

可以按以下顺序检查:

  1. Partner Center 中是否创建了 Azure plan,而不是其他订阅产品。
  2. Azure plan 下是否存在状态可用的 Azure entitlement。
  3. 当前使用的是否为 entitlement 对应的 Azure subscription ID。
  4. ARM token 是否从客户 tenant 获取。
  5. token 的 scope 是否为 https://management.azure.com/.default。
  6. 应用的 service principal 是否存在于客户 tenant。
  7. service principal 是否在目标 subscription/resource group 上拥有 RBAC 权限。
  8. GET /subscriptions/{id} 是否成功。
  9. 所需 resource provider 是否已经注册。
  10. 客户所在区域、配额和 CSP offer 是否允许使用目标 VM SKU。

需要完成的并不是让客户补充信用卡资料,而是打通「Azure plan → Azure entitlement → 客户租户身份 → Azure RBAC → ARM 部署」这条链路。

备注:内容仅供参考。