PAYATHON 2026

azure-arm-consumption:如何获取 CSP subscription 的消费数据

支付阿杰

结论

对于 CSP subscription,已经产生的 Azure 消费明细应通过 ConsumptionManagementClient 的 usageDetails.list() 获取,不应使用 forecasts.list()。

forecasts.list() 返回的是消费预测。旧版 azure-arm-consumption 对该接口的支持有限,通常只适用于 EA subscription,因此不能用它查询实际用量。

获取消费明细

完成 Service Principal 登录并取得 credentials 后,以 subscription 为查询范围调用 usageDetails.list():

const MsRest = require('ms-rest-azure');
const {
  ConsumptionManagementClient
} = require('azure-arm-consumption');

async function getConsumption() {
  const credentials =
    await MsRest.loginWithServicePrincipalSecret(
      keys.appId,
      keys.pass,
      keys.tenantId
    );

  const client = new ConsumptionManagementClient(
    credentials,
    subscriptionId
  );

  const scope = `/subscriptions/${subscriptionId}`;

  const result = await client.usageDetails.list(scope);

  return result;
}

getConsumption()
  .then(result => {
    console.log(result);
  })
  .catch(error => {
    console.error(error);
  });

在部分旧版本 SDK 中,usageDetails.list() 不接收 scope,而是直接使用创建客户端时传入的 subscriptionId:

const result = await client.usageDetails.list();

具体应以项目所安装版本的 TypeScript 定义或 API 文档为准,不要混用这两种调用方式。

处理分页

消费明细可能分多页返回。分页字段会因 SDK 版本而异,常见的处理方式是读取 nextLink,再调用 listNext():

async function getAllUsageDetails(client, scope) {
  const records = [];

  let page = await client.usageDetails.list(scope);
  records.push(...page);

  while (page.nextLink) {
    page = await client.usageDetails.listNext(page.nextLink);
    records.push(...page);
  }

  return records;
}

如果返回对象不能直接作为数组展开,需要检查其中的 value、nextLink 等字段。不同版本的自动生成 SDK 可能采用不同的返回结构。

权限要求

Service Principal 必须拥有读取目标 subscription 消费数据所需的权限。只有普通资源读取权限时,接口仍可能返回 403 Forbidden。

需要确认以下事项:

  • Service Principal 已分配到正确的 subscription。
  • Service Principal 具有 Cost Management Reader、Billing Reader,或包含相应消费读取操作的自定义角色。
  • CSP 租户、客户租户和订阅之间的授权关系正确。
  • 查询的 subscription 属于当前认证上下文。

usageDetails 和账单数据的区别

usageDetails.list() 返回 Azure 使用量和费用明细,可用于统计某个 subscription 已经产生的消费,但这些数据不一定等同于 CSP 合作伙伴最终收到的账单:

  • 数据可能存在延迟。
  • 税费、合作伙伴折扣、信用额度和价格调整未必会完整体现。
  • 最终结算金额可能与用量明细的汇总结果不同。
  • CSP 跨客户对账通常需要通过 Partner Center 的账单或 reconciliation API 获取数据。

如果只需查看某个 CSP subscription 当前已经产生的 Azure 消费,可以使用 usageDetails.list()。如果需要合作伙伴级别的最终账单、发票或对账数据,则不能只依赖 azure-arm-consumption,还应使用相应的 Partner Center 账单接口。

备注:内容仅供参考。