我正在使用客户端PHP代码(此处为测试模式)将站点从使用Stripe Checkout v2迁移到v3。我已经成功设置了结帐流程,付款后将重定向到成功页面。
在成功页面上,我要输入webhook代码以确认已付款,然后显示一个表格。
已在Stripe仪表板中设置了Webhook,并在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;
这是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`.
});
}
然后这是用于验证test-payment.php中的webhook的代码:
require('includes/stripe/stripe-v3/init.php');
\Stripe\Stripe::setApiKey('sk_test_...');
$endpoint_secret = 'whsec_...';
$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400); // PHP 5.4 or greater
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400); // PHP 5.4 or greater
exit();
}
// Handle the checkout.session.completed event
if ($event->type == 'checkout.session.completed') {
$session = $event->data->object;
// Fulfill the purchase...
handle_checkout_session($session);
}
http_response_code(200);
当重定向到test-payment.php时,它在“ SignatureVerification”上失败,并显示以下错误:
异常“ Stripe \ Error \ SignatureVerification”,消息为“无法从标头中提取时间戳和签名”
我试图回显$ _SERVER ['HTTP_STRIPE_SIGNATURE'],但它为空,因此我认为这可能是问题所在,但在解决方法上却陷入困境。
有创意的人吗?还是有一种更简单的方法来验证已付款?
答案 0 :(得分:0)
问题在于解析sigHeader时。
标头值为[t=1571998117,v1=ba786269057f295aa2a67795f7a70e07f71ff8eb4f5a24ecde0721453a09a461,v0=2d3802ff7fd896b7c4c01b297997e126405e5e2af7938b7ae2a28c11f3ef0d8f]
在传递给constuct()之前,需要先修剪掉[[和']'。
代码:
String signature = headers.get(HEADER_STRIPE_SIGNATURE);
signature = trimSignature(signature)
Event event = StripeUtil.constructEvent(request, signature, key)