我在我的 Spring 应用程序中使用Stripe checkout 我的订阅。
public StripeCashoutResponse createSession(Transaction transaction){
Stripe.apiKey = secretKey;
logger.info("init stripe subscription payment");
// The price ID passed from the client
String priceId = passPriceId;
StripeCashoutResponse cashoutResponse = null;
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())
.addLineItem(new SessionCreateParams.LineItem.Builder()
// For metered billing, do not pass quantity
.setQuantity(1L)
.setPrice(priceId)
.build()
)
.build();
try {
Session session = Session.create(params);
StripeResponse response = session.getLastResponse();
//convert to object to get the url
Gson gson = new Gson();
cashoutResponse = gson.fromJson(response.body(), StripeCashoutResponse.class);
cashoutResponse.setPaymentStatus(session.getPaymentStatus());
cashoutResponse.setCode(response.code());
logger.info(cashoutResponse.getUrl());
} catch (StripeException e) {
transaction.setStatus(TransactionStatus.PAYMENT_FAILED);
logger.error("Payment Failed: Unable to process the payment due to an error during the calling of stripe", e);
}
return cashoutResponse;
}
字符串
这个调用的响应给了我一个像cs_test_a1GoqW9TGTJgZnGuplZJ49Y2oxD70jtLKXBrVlQA23C7skzUJd8GlUJZSY
这样的ID,我将这个ID保存在数据库中。
一旦订阅被验证,我就会在我的webhooks中收到多个事件:
charge.succeeded
payment_method.attached
customer.created
customer.updated
customer.subscription.created
customer.subscription.updated
payment_intent.succeeded
payment_intent.created
invoice.created
invoice.finalized
invoice.updated
invoice.paid
invoice.payment_succeeded
checkout.session.completed
型
我们想要处理事件invoice.payment_succeeded
,但是这个事件没有我们在 checkout 的第一步中保存的id。
我们在第一步中保存的id只在最后一步checkout.session.completed
中出现。
在第一次结账会话期间,我们没有订阅ID。
现在我不知道如何在第一步( checkout )中保存一个id,我可以在我的事件invoice.payment_succeeded
中找到它,所以当这个事件由Stripe发送时,我可以正确地处理它。
谢谢
2条答案
按热度按时间eit6fx6z1#
当使用Checkout时,Stripe建议依赖
checkout.session.completed
事件来实现。他们在文档here中详细记录了这一点。问题是在Checkout完成付款的过程中,您会收到许多其他事件类型,并且您没有一种简单的方法来知道是否忽略这些事件。我建议您将自定义元数据添加到将由Checkout创建的底层订阅。这是通过传递
subscription_data[metadata]
参数来完成的。这样做将确保生成的订阅将在其上设置元数据。生成的发票也将在subscription_details[metadata]
属性下具有该元数据的副本。现在使用这种方法,当您获得
customer.subscription.*
或invoice.paid
事件时,您可以查找相关的元数据,将其与此订单/付款的内部数据库记录相匹配。最后,Stripe建议忽略
invoice.payment_succeeded
,而是依赖invoice.paid
。该事件类型是较新的,并修复了一些长期存在的问题,例如在Stripe考虑支付的金额低于最低金额的情况下,触发事件。pgky5nke2#
最后,经过与Stripe团队几天的讨论,在结帐过程中不可能有唯一的id。即使您添加元数据,这些元数据也不会在所有事件中可用。