使用Stripe SDK获取分层定价详情遇tiers字段为空,如何获取分层价格及各层级最小/最大单元数?
Stripe SDK获取分层定价详情遇tiers字段为空,如何获取分层价格及各层级最小/最大单元数?
嘿,这个问题我太熟了!之前用Stripe SDK拉分层定价的时候也踩过这个坑——明明后台配置得好好的分层,结果Price对象里的tiers字段居然是null,当时差点以为自己在后台的配置错了😅
先解决tiers字段为空的核心问题
Stripe API默认不会返回所有嵌套的字段,像tiers这种属于Price对象的嵌套结构,必须在请求的时候显式指定要展开它,否则SDK只会返回null。
你需要在构建PriceListParams的时候,添加expand参数来告诉Stripe要返回tiers字段的数据。比如在你的参数构建代码里加上这一行:
.addExpand("data.tiers")
用原生tiers字段替代自定义metadata,更可靠
你现在的代码是通过metadata存min_seats和max_seats来判断范围,但其实完全可以用Stripe原生的tiers字段来处理,这样不用自己维护额外的元数据,也避免了手动同步metadata的出错风险。
修改后的完整代码
fun getEnterprisePriceForSeats(seats: Int): Price { // 构建参数时添加expand来获取tiers字段 val params = PriceListParams.builder() .setProduct(stripeEnterpriseSubscriptionProductId) .setActive(true) .setLimit(100) .addExpand("data.tiers") // 关键:显式展开tiers字段 .build() val prices = Price.list(params).data // 先筛选出采用分层定价的价格 val tieredPrices = prices.filter { it.billingScheme() == Price.BillingScheme.TIERED } return tieredPrices.firstOrNull { price -> price.tiers()?.let { tiers -> // 根据分层定价的模式(总量/阶梯)判断座位数是否匹配 when (price.tiersMode()) { Price.TiersMode.VOLUME -> { // VOLUME模式:整个数量范围按该层级单价计算 tiers.any { tier -> val tierMin = if (tiers.indexOf(tier) == 0) 1 else tiers[tiers.indexOf(tier)-1].upTo()!! + 1 val tierMax = tier.upTo() ?: Int.MAX_VALUE seats in tierMin..tierMax } } Price.TiersMode.GRADUATED -> { // GRADUATED模式:数量分段按对应层级单价计算 tiers.any { tier -> val tierMin = if (tiers.indexOf(tier) == 0) 1 else tiers[tiers.indexOf(tier)-1].upTo()!! + 1 seats >= tierMin } } else -> false } } ?: false } ?: throw IllegalArgumentException("No Enterprise tiered price found for $seats seats") }
一些需要注意的细节
- tiersMode的差异:Stripe的分层定价分
VOLUME(总量)和GRADUATED(阶梯)两种模式,判断逻辑略有不同:- VOLUME模式下,整个数量都按匹配层级的单价计算,所以要判断座位数是否在该层级的min到max范围内;
- GRADUATED模式下,数量是分段计算的,只要座位数大于等于该层级的min值就会触发对应部分的定价。
- up_to字段的含义:如果某个tier的
up_to是null,就表示这个层级没有上限,直接对应Int.MAX_VALUE即可。 - SDK版本兼容:如果你的Stripe SDK版本比较旧,
addExpand的用法可能略有不同,比如有些版本需要传入一个列表(比如.setExpand(listOf("data.tiers"))),可以检查下SDK的对应文档。
内容来源于stack exchange
相关产品推荐
相关产品推荐

