PAYATHON 2026

WSO2 API Manager 货币化与计费用户权限问题

支付阿杰

结论

在这个场景中,API subscriber user 与所谓的 API developer user 通常并不是两个相互独立的 WSO2 API Manager 身份。负责开发消费端应用、在 API Store 创建 Application 并订阅 API 的用户就是 Subscriber。API developer 是一个容易引起歧义的业务称呼,既可能指 API 消费方的开发者,也可能指 API 创建者。

Subscriber 能在 Billing Engine 中创建 plan 和生成 invoice,通常说明 Billing Engine 的用户注册、默认角色或权限控制过于宽松,并非 APIM 订阅模型的必然结果。APIM 2.5.0 中的角色权限也不会自动转化为 Billing Engine 的财务权限。

要实现预期流程,需要同时处理以下三项配置:

  1. 在 APIM 中分离 Creator、Publisher 和 Subscriber 角色。
  2. 在 Billing Engine 中单独定义 Billing Admin、Billing Operator、Customer 等角色,禁止 Customer 管理 plan 和 invoice。
  3. 建立 throttling tier 到 billing plan 的单向映射。计费计划应由管理员同步,或由受信任的后台服务创建,不能交给 Subscriber 自行创建。

只修改 APIM 的 /permission/admin/manage/api/... 权限,通常无法解决 Billing Engine 中的越权问题。

如何理解这些用户

在 APIM 2.5.0 的典型模型中,各类用户的职责可以这样划分:

身份主要职责不应拥有的能力
API Creator创建和维护 API,选择可用的 subscription tiers开具财务发票、修改客户付款资料
API Publisher审核并发布 API以订阅者身份修改计费结果
API Subscriber在 API Store 创建 Application、订阅 API、获取调用凭证创建计费计划、生成或修改发票
Billing Admin维护计费计划、税率、币种及计费规则代表客户消费 API
Billing Operator根据用量生成、审核和发送发票任意修改 APIM 的 API 定义
Billing Customer维护自己的付款资料、查看账单并付款创建 plan、生成或修改 invoice

同一个自然人可以拥有多个角色,但不能因为用户完成了 Billing Engine 注册,就自动合并这些角色。例如,Subscriber 在 Billing Engine 中注册后,只应获得 BillingCustomer,不应获得 BillingAdmin 或 PlanManager。

如果“API developer”指消费 API 并开发客户端应用的人,那么它与 Subscriber 属于同一个业务角色。如果它指开发和发布 API 的人,则应明确称为 API Creator 或 API Publisher。授权时不能以 developer 这个含义模糊的名称作为依据。

为什么 Subscriber 可以创建 plan

APIM 和 Billing Engine 属于两个不同的授权边界。

APIM 负责:

  • API 的创建、发布和订阅;
  • Application 和凭证管理;
  • throttling tier 的选择与执行;
  • API 调用用量的采集。

Billing Engine 负责:

  • 客户账户和付款资料;
  • plan、价格、账期和税费;
  • invoice 的生成、发送及支付状态。

将用户重定向到 Billing Engine,只完成了注册或付款资料采集,并不能证明该用户只能以 Customer 身份操作。如果 Billing Engine 在自助注册时默认分配管理角色,或者创建 plan、生成 invoice 的接口只检查用户是否已登录,Subscriber 就会得到本不该拥有的权限。

因此,需要检查的不是重定向流程本身,而是 Billing Engine 的以下配置:

  • 新注册用户默认加入哪个角色;
  • plan 和 invoice 接口要求哪些权限;
  • 管理页面是否只对管理角色显示;
  • 后端接口是否同样执行权限检查;
  • APIM 用户、Billing Engine 客户账户和租户之间如何映射。

仅在前端隐藏按钮并不能阻止越权操作,相关 REST API 必须返回 403 Forbidden。

推荐的角色和权限配置

APIM 侧可以采用下面的职责划分。角色名称可以自定义,真正决定权限的是授予各角色的 permission:

api-creator
  - 创建和编辑 API

api-publisher
  - 发布、阻止和管理 API 生命周期

api-subscriber
  - 登录 API Store
  - 创建 Application
  - 订阅 API
  - 生成和管理消费端凭证

不要为了让 Subscriber 完成 Billing Engine 注册,就向其授予 Creator、Publisher 或系统管理权限。

Billing Engine 侧应采用独立的角色体系:

BillingAdmin
  plan:create
  plan:update
  plan:delete
  invoice:create
  invoice:approve
  invoice:send
  customer:read
  usage:read

BillingOperator
  invoice:create
  invoice:approve
  invoice:send
  customer:read
  usage:read

BillingCustomer
  customer:self:read
  customer:self:update-payment-method
  invoice:self:read
  invoice:self:pay

新用户从 APIM 跳转并完成注册时,只能获得 BillingCustomer。管理角色应由管理员预先分配,或通过受保护的后台配置流程授予,不能根据公开注册参数分配。

后端授权逻辑至少应实现下面的限制:

@POST
@Path("/plans")
@RolesAllowed("BillingAdmin")
public Response createPlan(PlanRequest request) {
    return planService.create(request);
}

@POST
@Path("/invoices")
@RolesAllowed({"BillingAdmin", "BillingOperator"})
public Response createInvoice(InvoiceRequest request) {
    return invoiceService.create(request);
}

@GET
@Path("/customers/{customerId}/invoices")
@RolesAllowed({"BillingAdmin", "BillingOperator", "BillingCustomer"})
public Response getInvoices(@PathParam("customerId") String customerId) {
    securityService.requireSelfOrBillingStaff(customerId);
    return invoiceService.findByCustomer(customerId);
}

这段代码只用于说明授权结构,不表示 APIM 2.5.0 或某个 Billing Engine 一定提供完全相同的注解、角色名称和接口路径。具体实现取决于所集成 Billing Engine 的产品和版本。

throttling tier 与 billing plan 如何保持一致

throttling tier 和 billing plan 是两类不同的对象:

  • tier 决定流量限制,例如每分钟请求数、配额和超额行为;
  • plan 决定价格,例如固定订阅费、超额单价、币种和账期。

subscription_fee 和 charge_per_extra 是计费需要的扩展属性,但仅靠这两个属性无法构成完整的财务计划。币种、结算周期、税率、舍入方式、试用期和计划版本仍需由 Billing Engine 管理。

一种较稳妥的做法是以 APIM tier 作为计费定义的来源,并维护一份 Subscriber 无权修改的映射,例如:

{
  "Gold": {
    "billingPlanId": "api-gold-v1",
    "subscriptionFee": "49.00",
    "chargePerExtra": "0.0020",
    "currency": "USD",
    "billingPeriod": "MONTH"
  },
  "Silver": {
    "billingPlanId": "api-silver-v1",
    "subscriptionFee": "19.00",
    "chargePerExtra": "0.0040",
    "currency": "USD",
    "billingPeriod": "MONTH"
  }
}

订阅事件中应保存确定的映射,不能信任浏览器提交的价格:

APIM subscription
    API + version + application + tier
                    |
                    v
Trusted billing integration
    tier -> billingPlanId
                    |
                    v
Billing Engine customer subscription

创建 Billing Engine 订阅时,后台服务应根据 APIM 返回的 tier 查找 billingPlanId:

String tierName = subscription.getTier();
BillingPlanMapping mapping = mappingRepository.findByTier(tierName);

if (mapping == null) {
    throw new IllegalStateException(
        "No billing plan configured for tier: " + tierName
    );
}

billingClient.subscribeCustomer(
    customerId,
    mapping.getBillingPlanId(),
    subscription.getId()
);

只有平台管理员可以创建和修改映射。Subscriber 最多只能从 APIM 提供的 tier 中进行选择,不能自行提交 subscriptionFee、chargePerExtra 或任意 billingPlanId。

发票生成流程

完整流程可以按以下方式设计:

  1. API Creator 定义 API,并关联管理员批准的 commercial tiers。
  2. Billing Admin 创建对应的 plan,或者由受信任的同步任务根据 tier 创建。
  3. Subscriber 在 API Store 中为 Application 选择 tier 并订阅。
  4. APIM 将用户引导至 Billing Engine,建立 Customer 和付款资料。
  5. Billing Engine 只向该用户分配 Customer 权限。
  6. Analytics 汇总实际请求量。
  7. 受信任的计费任务根据订阅、账期和 tier 计算费用。
  8. Billing Operator 或自动化任务生成并发送 invoice。
  9. Subscriber 只能查看并支付自己的 invoice。

费用可以采用下面的简化计算方式:

invoice_amount =
    subscription_fee
    + max(0, actual_requests - included_requests) * charge_per_extra

正式实现还需要明确统计窗口、失败请求和重试是否计费,以及时区、精度、税费和舍入规则。不能仅依据 API Gateway 的某个累计计数直接开票。

必须同时保护界面和接口

如果 Subscriber 登录后仍能看到管理菜单,应调整 Billing Engine 的菜单权限。不过,更重要的是验证后端接口是否正确执行权限检查:

POST /billing/plans
Authorization: Bearer <subscriber-token>

预期响应应为:

HTTP/1.1 403 Forbidden

还需要验证以下接口:

POST /billing/invoices
PUT  /billing/plans/{id}
DELETE /billing/plans/{id}
GET  /billing/customers/{otherCustomerId}/invoices

Customer 只能访问与自身绑定的数据。即使用户知道其他客户或 invoice 的 ID,也不能读取或修改相关内容。

版本与实现注意事项

WSO2 API Manager 2.5.0 已是较早的版本。它的 monetization 集成更接近一套集成流程和扩展点,并不保证任意 Billing Engine 都会自动具备生产环境所需的 RBAC、计划同步和发票审批机制。

因此,不能假设 APIM 中存在一个配置项,可以直接完成“禁止 Subscriber 创建 plan”的全部权限控制。如果所用的 Billing Engine 没有角色授权机制,就需要修改其实现、在 API Gateway 前增加授权层,或者改用能够区分 Customer 与 Billing Admin 权限的计费系统。

最终配置应满足以下要求:

  • Subscriber 注册时只获得 Customer 角色;
  • plan 只能由 Billing Admin 管理;
  • invoice 只能由 Billing Admin、Billing Operator 或受信任的定时任务生成;
  • tier 与 plan 通过服务器端映射关联;
  • 用量数据只能由可信的 Analytics 或计量服务提交;
  • 所有对象都按 tenant、customer 和 subscription 隔离;
  • 价格变更通过计划版本处理,不应追溯修改已经生效的订阅和历史发票。

备注:内容仅供参考。