You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Stripe的invoice.payment_succeeded事件中关联创建Checkout Session时保存的唯一ID

如何在Stripe的invoice.payment_succeeded事件中关联创建Checkout Session时保存的唯一ID

我来帮你搞定这个关联问题!其实Stripe提供了几种实用的方式,能让你把Checkout Session阶段的自定义标识传递到后续的invoice相关事件里,下面结合你的代码场景给出具体方案:

方案一:利用Subscription Metadata传递自定义标识(最推荐)

你代码里已经用了setClientReferenceId(transaction.getTransactionId()),但这个字段不会直接出现在invoice.payment_succeeded事件里。不过我们可以在创建Checkout Session时,把你的transaction ID放到Subscription的Metadata里——因为每个Invoice都会关联对应的Subscription,这样后续所有周期的Invoice事件都能拿到这个标识。

修改你创建Session的代码,添加subscription_data.metadata的设置:

SessionCreateParams params = new SessionCreateParams.Builder()
    .setSuccessUrl("https://example.com/success.html?session_id={CHECKOUT_SESSION_ID}")
    .setCancelUrl("https://example.com/canceled.html")
    .setMode(SessionCreateParams.Mode.SUBSCRIPTION)
    .setClientReferenceId(transaction.getTransactionId())
    // 新增:把transaction ID存入Subscription的元数据
    .setSubscriptionData(
        new SessionCreateParams.SubscriptionData.Builder()
            .putMetadata("transaction_id", transaction.getTransactionId())
            .build()
    )
    .addLineItem(new SessionCreateParams.LineItem.Builder()
        .setQuantity(1L)
        .setPrice(priceId)
        .build()
    )
    .build();

处理invoice.payment_succeeded事件时的步骤:

  1. 解析事件对象,拿到Invoice实例
  2. 从Invoice中获取关联的subscription字段(即Subscription ID)
  3. 调用Stripe的API查询该Subscription详情:Subscription.retrieve(subscriptionId)
  4. 从Subscription的metadata里取出transaction_id,就能关联到你数据库里的交易记录了

方案二:提前存储Checkout Session与Subscription的映射

checkout.session.completed事件中,你可以拿到Checkout Session对应的Subscription ID,这时把它和你之前保存的Session ID/transaction ID做映射存储到数据库里。

处理checkout.session.completed事件的示例代码:

// 解析事件得到Checkout Session对象
Session session = (Session) event.getDataObjectDeserializer().getObject().get();
String transactionId = session.getClientReferenceId();
String subscriptionId = session.getSubscription();
// 将transactionId与subscriptionId的映射关系存入数据库

之后处理invoice.payment_succeeded事件时,直接从Invoice里拿到subscriptionId,查数据库就能找到对应的transaction ID,不需要额外调用Stripe API,效率更高。

方案三:通过Payment Intent反向关联Checkout Session

如果以上两种方式都没法用,还可以通过Invoice里的payment_intent字段反向追溯:

  1. invoice.payment_succeeded事件中拿到Payment Intent ID
  2. 调用Stripe API查询Payment Intent详情:PaymentIntent.retrieve(paymentIntentId)
  3. 从Payment Intent的checkout_session字段拿到Checkout Session ID,再关联到你的交易记录

不过这种方式需要多一次API调用,不如前两种高效,只建议作为 fallback 方案。

总结一下,最稳妥的是方案一+方案二结合:既在Subscription里存元数据做兜底,又提前在数据库里存映射关系,处理Invoice事件时优先查数据库,这样既高效又可靠。

备注:内容来源于stack exchange,提问作者Teddy Kossoko

火山引擎 最新活动