我在使用 Stripe Webhooks 时遇到问题,尤其是 payment_intent.processing 事件。 在我必须维护的旧应用程序中,我们使用 3 种付款方式。其中之一是 SOFORT 付款。这种付款方式的主要区别在于,您应该等待几天的银行回复,然后从 Stripe Webhook 获得 Payment Succeeded 回复。但是我们的应用程序要求我们在客户付款的那一刻填写客户余额。 SOFORT 是值得信赖的,我们从未遇到过在处理过程中交易被取消的情况。
但是 2 天前,当 Stripe 以 1 秒的间隔创建了两个 payment_intent.processing 事件并且客户在其余额上获得了 2 次积分时,我面临了一个新问题。 这是一段代码来解释我的意思:
$paymentIntent = $event->data->object;
$order = Db_Orders::getOrderPaymentIntentId($paymentIntent->id);
switch ($event->type) {
case 'payment_intent.processing':
if ($order['wlo_payment_type'] == PAYMENT_METHOD_SOFORT && $order['wlo_status'] == W_LEADS_ORDER_STATUS_STARTED) Utils::activateOrderOffers($order['id']);
$orderObj = new Db_LeadOrder();
$orderObj->id = $order['id'];
$orderObj->wlo_status = W_LEADS_ORDER_STATUS_PENDING;
$orderObj->save();
break;
case 'payment_intent.succeeded':
if ($order['wlo_payment_type'] != PAYMENT_METHOD_SOFORT && $order['wlo_status'] != W_LEADS_ORDER_STATUS_SUCCESS) Utils::activateOrderOffers($order['id']);
$orderObj = new Db_LeadOrder();
$orderObj->id = $order['id'];
$orderObj->wlo_response_date = Utils::formatDateDb(time());
$orderObj->wlo_status = W_LEADS_ORDER_STATUS_SUCCESS;
$orderObj->save();
break;
default:
echo 'Received unknown event type ' . $event->type;
在activateOrderOffers 函数中,我使用客户余额进行所有操作。正如您在 payment_intent.processing 事件中看到的那样,我仅针对具有 STARTED(所有订单的初始值)状态的 SOFORT 付款方式执行它。
据我所知,就我而言,我正在侦听两个并行处理事件。我是对的,有什么想法可以解决这个问题吗?我知道,在付款尚未成功的情况下操纵余额可能是一种不好的做法,但这是客户的主要要求。 向大家致以最诚挚的问候。
答案 0 :(得分:2)
虽然不太可能,但可能会发送同一事件的多个副本,因此您需要 make your webhook handling code idempotent 以便正确处理。
答案 1 :(得分:2)
Stripe webhook 可能会重新发送事件。根据最佳实践,您可以考虑记录您已经收到的事件。
https://stripe.com/docs/webhooks/best-practices#duplicate-events
<块引用>Webhook 端点可能偶尔会多次收到相同的事件。我们建议您通过使您的事件处理具有幂等性来防止重复的事件收据。一种方法是记录您已处理的事件,然后不处理已记录的事件。