【问题标题】:Webhooks testing inconsistencies whilst debugging using Stripe CLI and event triggersWebhook 在使用 Stripe CLI 和事件触发器进行调试时测试不一致
【发布时间】:2020-08-07 18:56:48
【问题描述】:

问题是如果我多次触发同一个事件,我会得到不同的结果。

我打开了三个终端

  1. 聆听使用:
   listen --forward-to localhost:8888/my-endpoint.php
  1. 触发使用
    stripe trigger + event

(例如,条带触发 payment_intent.succeeded)

  1. 记录来自本地主机的错误

疑难解答

  • 我也可以通过运行 Stripe 结帐来触发。结帐有效,但终端中的结果与描述的相似。

  • 我还在 xdebug 监听时运行了触发器,并且可以看到代码以预期的确切方式逐步执行(即为正文分配简单的文本响应并调用 200/400 代码)。

重要提示

下面的截图显示了日志(左)、监听(右上)和事件触发(右下)。

(第 1 次和第 4 次尝试有效。第 2 次和第 3 次无效。它们不包括日志或:

2020-04-24 16:17:16   --> payment_intent.succeeded [evt_1GbMikFOnngxtrI1EfZyfaNo]
2020-04-24 16:17:16  <--  [200] POST http://localhost:8888/scripts/stripe/webhook-endpoint.php [evt_1GbMikFOnngxtrI1EfZyfaNo]

请注意,您可以在右上角看到不同事件的时间码。

而且日志只会在第一次触发时更新一次。

另一个有趣的事情是,有时响应会出现在 Stripe 仪表板中,有时却不会。

有什么想法吗?

Webhooks 代码(签名和 api 密钥在上面设置,但在这里隐藏)

$payload = @file_get_contents('php://input'); //get json POST data stripe sends
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;

try {
    $event = \Stripe\Webhook::constructEvent(
      $payload, $sig_header, $endpoint_secret, //get data
    );
  } catch(\UnexpectedValueException $e) {
    // Invalid payload
    printf("Invalid payload");
    http_response_code(400);
    exit();
  } catch(\Stripe\Exception\SignatureVerificationException $e) {
    // Invalid signature
    printf("Invalid signature.");
    http_response_code(400);
    exit();
  }
// Handle the event(s)
switch ($event->type) {
    case 'checkout.session.completed': 
        $session = $event->data->object;
        printf("Checkout Session Completed");
        http_response_code(200); 
        break;
    case 'payment_intent.succeeded': 
        $paymentIntent = $event->data->object; 
        $intent = $event->data->object;
        printf("Payment Intent Succeeded: %s", $intent->id);
        http_response_code(200);
        error_log( json_encode( $intent, JSON_PRETTY_PRINT ) );
        break;
    case 'payment_intent.payment_failed': 
        $paymentMethod = $event->data->object;
        $intent = $event->data->object;
        $error_message = $intent->last_payment_error ? $intent->last_payment_error->message : "";
        printf("Failed: %s, %s", $intent->id, $error_message);
        http_response_code(200);
        break;
    case 'payment_intent.processing':
        printf("Payment Intent Processing: %s", $intent->id);
        http_response_code(200);
        break;
    case 'payment_intent.canceled': 
        printf("Payment Intent canceled: %s", $intent->id);
        http_response_code(200);
        break;
    default:
        http_response_code(400);
        exit();
}

http_response_code(200);
return false;

【问题讨论】:

    标签: php webhooks stripe-payments


    【解决方案1】:

    我希望我理解正确,如果我跑题了,我深表歉意。

    我认为这里的问题是使用 stripe trigger payment_intent.succeeded 最终会创建 3 个事件:

    • payment_intent.created
    • charge.succeeded
    • payment_intent.succeeded

    case 语句似乎没有前两种事件类型的子句,因此它们默认为 400s。

    根据您想要做什么,您可以扩展 case 语句来处理这些事件。也可能这与您的发现有关,但事件没有保证的顺序,这是正常行为,您在构建系统时必须牢记 [0]。希望这会有所帮助!

    [0]https://stripe.com/docs/webhooks/best-practices#event-ordering

    【讨论】:

    • 这是一个好点!我想知道投掷 400 是否会造成惊吓。我会测试它并在不久的将来回到这个线程。
    • 有效!很好的分析,非常感谢。我认为这在直播时不会成为问题,因为您在仪表板中选择了事件条带发送,但在这里似乎是必要的。我现在可以安心睡觉了……
    • 没错,您可以完全控制所看到的事件。很高兴它成功了!
    猜你喜欢
    • 2019-04-14
    • 2020-06-10
    • 2020-01-21
    • 2020-11-18
    • 2017-10-25
    • 2021-11-30
    • 2021-04-03
    • 2022-01-17
    • 2021-10-24
    相关资源
    最近更新 更多