Stripe订阅:获取成功支付次数及三次支付后触发事件方案
获取Stripe订阅的成功支付次数方案
我正好处理过类似的需求,Stripe确实没有直接在invoice.payment_succeeded webhook里提供支付次数字段,但有几种可靠的方式来实现这个需求:
方法1:通过Stripe API查询已支付发票数量
你可以直接调用Stripe的发票列表API,筛选对应订阅的所有已支付发票,统计数量就是成功支付次数。这种方法不需要额外存储,适合偶尔查询的场景。
示例代码(Python):
import stripe stripe.api_key = "你的Stripe密钥" def get_subscription_payment_count(subscription_id): # 拉取该订阅下所有状态为paid的发票 invoices = stripe.Invoice.list( subscription=subscription_id, status="paid", limit=100 # 调整上限以覆盖可能的支付次数 ) # 返回已支付发票的总数 return len(invoices.data)
注意:如果订阅周期很长、支付次数极多,可能需要分页获取所有发票,但一般3次支付的场景用这个方法完全足够。
方法2:自行在数据库维护支付计数
这是最灵活且实时性最高的方案,适合需要频繁判断或触发后续逻辑的场景。
步骤:
- 你的数据库中为订阅记录添加一个字段(比如
successful_payments),初始值设为0 - 在处理
invoice.payment_succeededwebhook时:- 先检查当前发票是否已经被处理过(避免webhook重复发送导致计数错误,可通过存储发票ID到数据库实现幂等)
- 如果未处理,将对应订阅的
successful_payments字段加1 - 检查计数是否达到3,若达到则触发你的自定义事件
示例逻辑伪代码:
def handle_invoice_payment_succeeded(event): invoice = event.data.object subscription_id = invoice.subscription invoice_id = invoice.id # 幂等校验:检查该发票是否已处理过 if is_invoice_processed(invoice_id): return # 更新数据库中的支付计数 update_subscription_payment_count(subscription_id, increment=1) # 获取更新后的计数 current_count = get_subscription_payment_count(subscription_id) if current_count == 3: # 触发你的指定事件 trigger_custom_event(subscription_id) # 标记该发票已处理 mark_invoice_as_processed(invoice_id)
方法3:利用Stripe元数据存储计数
如果不想维护自己的数据库,可以直接把支付次数存在Stripe订阅对象的元数据(Metadata)中,每次支付成功后更新这个值。
示例代码(Python):
def handle_invoice_payment_succeeded(event): invoice = event.data.object subscription_id = invoice.subscription invoice_id = invoice.id # 先获取当前订阅的元数据 subscription = stripe.Subscription.retrieve(subscription_id) current_count = int(subscription.metadata.get("successful_payments", 0)) # 幂等校验:避免重复计数(可在元数据中存储已处理的发票ID) processed_invoices = subscription.metadata.get("processed_invoices", "").split(",") if invoice_id in processed_invoices: return # 更新计数和已处理发票列表 new_count = current_count + 1 new_processed_invoices = processed_invoices + [invoice_id] stripe.Subscription.modify( subscription_id, metadata={ "successful_payments": str(new_count), "processed_invoices": ",".join(new_processed_invoices) } ) if new_count == 3: trigger_custom_event(subscription_id)
关键注意事项
- 幂等性处理:Stripe的webhook可能会重复发送,一定要通过发票ID来判断是否已经处理过本次支付,避免计数错误
- 异常情况:如果用户有退款、支付失败后重试的情况,要根据你的业务需求决定是否重新计数(比如只统计最终成功的支付,忽略失败后重试的次数)
内容的提问来源于stack exchange,提问作者Mukesh Godara




