如何利用Stripe API查询客户已购未退款的产品?
如何通过Stripe API查询客户已购买未退款的指定产品
完全可行,你之前找错了关联层级——Charges和Payment Intent属于支付执行层对象,仅记录资金流转信息,产品/价格的关联关系需要从订单交易层的对象(Invoice或Checkout Session)获取。针对你的一次性终身会员场景,具体实现方案如下:
核心逻辑
Stripe中,一次性购买的交易链路通常是:Product → Price → (Checkout Session / Invoice) → Payment Intent → Charge
所以要关联客户与产品,需要从已完成的Checkout Session或已支付的Invoice入手,再验证对应的支付是否未被全额退款。
具体实现方法
方法1:通过已支付Invoice查询(适用于通过发票发起的购买)
- 调用
Invoices ListAPI,传入客户ID,筛选status: paid的发票:const invoices = await stripe.invoices.list({ customer: "cus_XXXXXX", // 目标客户ID status: "paid", limit: 100 // 根据你的客户交易数量调整 }); - 遍历发票,排除全额退款的记录:
- 检查发票的
refunded字段是否为true,或amount_refunded是否等于amount_paid,满足任一条件则跳过该发票。
- 检查发票的
- 查询发票的Line Items,匹配目标产品:
对每一张有效发票,调用Invoices List Line ItemsAPI,获取关联的价格与产品ID:
若找到匹配项,即可判定客户已购买该产品。const lineItems = await stripe.invoices.listLineItems(invoice.id); const hasTargetProduct = lineItems.data.some(item => item.price.product === "prod_XXXXXX"); // 你的终身会员产品ID
方法2:通过已完成的Checkout Session查询(适用于通过Stripe Checkout发起的购买)
- 调用
Checkout Sessions ListAPI,传入客户ID,筛选status: complete的会话:const sessions = await stripe.checkout.sessions.list({ customer: "cus_XXXXXX", status: "complete", limit: 100 }); - 遍历会话,验证支付状态并匹配产品:
- 检查会话关联的
payment_intent状态是否为succeeded; - 查看会话的
line_items(需调用Checkout Sessions Retrieve Line ItemsAPI),直接匹配目标产品ID:const lineItems = await stripe.checkout.sessions.listLineItems(session.id); const hasTargetProduct = lineItems.data.some(item => item.price.product === "prod_XXXXXX"); - 同时确认该Payment Intent未被全额退款:检查
payment_intent对象的amount_refunded是否小于amount。
- 检查会话关联的
关键注意点
- 若你的业务同时使用Invoice和Checkout两种购买方式,需要同时查询这两类对象,避免遗漏记录;
- 对于部分退款的情况,只要产品对应的交易未被全额退款,就应视为客户已购买该产品,需根据你的业务规则调整判断逻辑。
内容的提问来源于stack exchange,提问作者Paymahn Moghadasian
相关产品推荐
相关产品推荐

