Stripe即将在平台上推广使用强客户身份验证进行支付。他们的文档中有相当一部分内容。
https://stripe.com/docs/payments/payment-intents/quickstart#manual-confirmation-flow
该过程具有以下流程:
原始的PHP实现如下:
<?php
# vendor using composer
require_once('vendor/autoload.php');
\Stripe\Stripe::setApiKey(getenv('STRIPE_SECRET_KEY'));
header('Content-Type: application/json');
# retrieve json from POST body
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$intent = null;
try {
if (isset($json_obj->payment_method_id)) {
# Create the PaymentIntent
$intent = \Stripe\PaymentIntent::create([
'payment_method' => $json_obj->payment_method_id,
'amount' => 1099,
'currency' => 'gbp',
'confirmation_method' => 'manual',
'confirm' => true,
]);
}
if (isset($json_obj->payment_intent_id)) {
$intent = \Stripe\PaymentIntent::retrieve(
$json_obj->payment_intent_id
);
$intent->confirm();
}
generatePaymentResponse($intent);
} catch (\Stripe\Error\Base $e) {
# Display error on client
echo json_encode([
'error' => $e->getMessage()
]);
}
function generatePaymentResponse($intent) {
# Note that if your API version is before 2019-02-11, 'requires_action'
# appears as 'requires_source_action'.
if ($intent->status == 'requires_action' &&
$intent->next_action->type == 'use_stripe_sdk') {
# Tell the client to handle the action
echo json_encode([
'requires_action' => true,
'payment_intent_client_secret' => $intent->client_secret
]);
} else if ($intent->status == 'succeeded') {
# The payment didn’t need any additional actions and completed!
# Handle post-payment fulfillment
echo json_encode([
"success" => true
]);
} else {
# Invalid status
http_response_code(500);
echo json_encode(['error' => 'Invalid PaymentIntent status']);
}
}
?>
与Stripe Elements配合使用所需的JavaScript如下所示:
var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
cardButton.addEventListener('click', function(ev) {
stripe.createPaymentMethod('card', cardElement, {
billing_details: {name: cardholderName.value}
}).then(function(result) {
if (result.error) {
// Show error in payment form
} else {
// Otherwise send paymentMethod.id to your server (see Step 2)
fetch('/ajax/confirm_payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ payment_method_id: result.paymentMethod.id })
}).then(function(result) {
// Handle server response (see Step 3)
result.json().then(function(json) {
handleServerResponse(json);
})
});
}
});
});
function handleServerResponse(response) {
if (response.error) {
// Show error from server on payment form
} else if (response.requires_action) {
// Use Stripe.js to handle required card action
stripe.handleCardAction(
response.payment_intent_client_secret
).then(function(result) {
if (result.error) {
// Show error in payment form
} else {
// The card action has been handled
// The PaymentIntent can be confirmed again on the server
fetch('/ajax/confirm_payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ payment_intent_id: result.paymentIntent.id })
}).then(function(confirmResult) {
return confirmResult.json();
}).then(handleServerResponse);
}
});
} else {
// Show success message
}
}
在我自己的项目中,我使用的是Laravel,它完全基于MVC架构,在大多数事情上对您来说都很不错。
我试图重构一些,但是我有一个问题。
为什么为什么要尝试从Laravel中使用的$json_str = file_get_contents('php://input');
对象中获取已发布的变量而不是使用Request
行?
我还从PHP手册中阅读了以下文章:
https://www.php.net/manual/en/wrappers.php.php
说实话,我一直没有使用过程PHP,这使我感到无休止。
答案 0 :(得分:0)
为什么在POST超全局变量上使用'php:// input'-Stripe SCA示例
主体被编码为JSON。您可以知道,因为下一行会对其进行显式解码。
PHP无法理解application/json
请求。如果数据使用$_POST
或application/x-www-form-urlencoded
格式编码,则只会填充multipart/form-data
。
为什么只尝试从Laravel中使用的Request对象中获取发布的变量,而不是使用
$json_str = file_get_contents('php://input');
行?
如果您使用的是Laravel,则没有理由这样做。
由于在您给出的示例中没有任何Laravel的迹象,因此可能并不是为了引入对Laravel的依赖而编写的。