在 PHP 中使用 Stripe webhook 时出现“无法从标头中提取时间戳和签名”错误

Stu*_*art 5 php webhooks stripe-payments

我正在使用客户端 PHP 代码将网站从使用 Stripe Checkout v2 迁移到 v3(此处所有内容均处于测试模式)。我已成功设置结帐流程,付款后重定向到成功页面。

在成功页面上,我放置了webhook代码,因为我想验证付款是否已完成,然后显示一个表单。

Webhook 已在 Stripe 仪表板中设置,并在 Webhook 日志中显示为“成功”。

以下是用于结帐的 PHP 代码:

require('includes/stripe/stripe-v3/init.php');

\Stripe\Stripe::setApiKey('sk_test_...');

$session = \Stripe\Checkout\Session::create([
  'payment_method_types' => ['card'],
  'line_items' => [[
    'name' => 'Example',
    'description' => 'Example description',
    'images' => ['https://example/com/image.png'],
    'amount' => 99,
    'currency' => 'gbp',
    'quantity' => 1,
  ]],
  'success_url' => 'https://example.com/test-payment.php?checkout=v3&payment=success&session_id={CHECKOUT_SESSION_ID}',
  'cancel_url' => 'https://example.com/test-payment?payment=failed',
]);

$session_id = $session->id;
Run Code Online (Sandbox Code Playgroud)

这是 JavaScript:

var stripe = Stripe('pk_test_4iEnGexyFSJgXFumnmEXWDlG');
function checkout_redirect() {
    stripe.redirectToCheckout({
      // Make the id field from the Checkout Session creation API response
      // available to this file, so you can provide it as parameter here
      // instead of the {{CHECKOUT_SESSION_ID}} placeholder.
      sessionId: '<?php echo $session_id; ?>'
    }).then(function (result) {
      // If `redirectToCheckout` fails due to a browser or network
      // error, display the localized error message to your customer
      // using `result.error.message`.
    });
}
Run Code Online (Sandbox Code Playgroud)

这是在 test- payment.php 中验证 webhook 的代码:

var stripe = Stripe('pk_test_4iEnGexyFSJgXFumnmEXWDlG');
function checkout_redirect() {
    stripe.redirectToCheckout({
      // Make the id field from the Checkout Session creation API response
      // available to this file, so you can provide it as parameter here
      // instead of the {{CHECKOUT_SESSION_ID}} placeholder.
      sessionId: '<?php echo $session_id; ?>'
    }).then(function (result) {
      // If `redirectToCheckout` fails due to a browser or network
      // error, display the localized error message to your customer
      // using `result.error.message`.
    });
}
Run Code Online (Sandbox Code Playgroud)

当被重定向到 test- payment.php 时,它在“SignatureVerification”上失败并出现以下错误:

异常“Stripe\Error\SignatureVerification”,消息“无法从标头中提取时间戳和签名”

我试图回显 $_SERVER['HTTP_STRIPE_SIGNATURE'] 但它是空的,所以我认为这可能是问题所在,但我对如何修复它感到困惑。

大家有什么想法吗?或者是否有更简单的方法来验证付款已完成?

小智 2

问题是在解析 sigHeader 时。标头值为[t=1571998117,v1=ba786269057f295aa2a67795f7a70e07f71ff8eb4f5a24ecde0721453a09a461,v0=2d3802ff7fd896b7c4c01b297997e126405e5e2af7938b7ae2a28c11f3ef0d8f]

在传递给 construct() 之前,需要修剪掉 '[' 和 ']' 。

代码:

String signature = headers.get(HEADER_STRIPE_SIGNATURE);
signature = trimSignature(signature)    
Event event = StripeUtil.constructEvent(request, signature, key)
Run Code Online (Sandbox Code Playgroud)