我正在尝试实现付款意图 api,但我不断收到无效的付款意图状态,我在堆栈溢出上看到了答案,但没有帮助, 我不知道它是一个糟糕的服务器端还是客户端实现,因为我对此仍然陌生
我尝试将requires_action更改为requires_source_action,但没有任何帮助,尝试修改html,但我不知道出了什么问题。
负责,我有
<?php
# vendor using composer
require_once('vendor/autoload.php');
\Stripe\Stripe::setApiKey(getenv('sk_test_HERE'));
header('Content-Type: application/json');
# retrieve json from POST body
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
//$amount=$POST['amount'];
//----------------🤒 changed the intent from null;
$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' => 1000,
'currency' => 'eur',
'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()
]);
}
//--------------------updated from requires action to requires source action
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_source_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']);
}
}
?>
在我的 JavaScript 文件中
// Create a Stripe client.
var stripe = Stripe('pk_test_HERE');
// Create an instance of Elements.
var elements = stripe.elements();
// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
var style = {
base: {
color: '#32325d',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
// Create an instance of the card Element.
var card = elements.create('card', {style: style});
// Add an instance of the card Element into the `card-element` <div>.
// added an extra s for form control
card.mount('#card-elements');
// Handle real-time validation errors from the card Element.
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
// Handle form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server.
stripeTokenHandler(result.token);
}
});
});
// Submit the form with the token ID.
function stripeTokenHandler(token) {
// Insert the token ID into the form so it gets submitted to the server
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
// Submit the form
form.submit();
}
这是为了收集详细信息,如果您看到任何业余的东西,请原谅我
<div class="container">
<h2 class="my-4 text-center">Service Payments</h2>
<form action="./charge.php" method="post" id="payment-form">
<div class="form-row">
<input type="text" name="first_name" class="form-control mb-3 StripeElement StripeElement--empty" placeholder="First Name" required>
<input type="text" name="last_name" class="form-control mb-3 StripeElement StripeElement--empty" placeholder="Last Name" required>
<!-- <label for="t2">What's your e-mail?</label> -->
<input type="email" name="email" id="t2" class="form-control mb-3 StripeElement StripeElement--empty" placeholder="Email Address" required>
<input type="amount" name="amount" class="form-control mb-3 StripeElement StripeElement--empty" placeholder="1000 translates to 10.00" required>
<!-- changed card element to elements with an s, form control is another possible option -->
<input id="cardholder-name" type="text">
<div id="card-elements" class="form-control">
<!-- / a Stripe Element will be inserted here. / -->
</div>
<!-- Used to display form errors -->
<div id="card-errors" role="alert"></div>
</div>
<button id="card-button" data-secret="<?= $intent->client_secret ?>">Submit Payment</button>
</form>
</div>
我不断收到错误:付款意向状态无效
最佳答案
看起来您可能正在处理旧文档。您收到“无效的付款意向状态”,因为您的代码正在查找不存在的状态 requires_source_action
:https://stripe.com/docs/payments/intents#intent-statuses
实际状态可能是requires_confirmation
,在这种情况下,您必须在服务器上确认 PaymentIntent。然后,根据状态,您要么获得 requires_action
状态,要么获得 succeeded
。您选择哪一张取决于相关卡是否需要 3DS。
由于您的 PaymentIntent 使用手动确认流程,这意味着您必须在前端和后端之间进行多次往返才能真正完成付款。我建议考虑使用自动确认。这样您只需 2 个步骤:
- 在服务器上创建 PaymentIntent,将客户端 key ID 传递给前端
- 像现在一样使用 Elements 收集付款详细信息,使用第 1 步中的客户端 key 和 Stripe.js 的
handleCardPayment
完成付款
有关该流程的更多信息:https://stripe.com/docs/payments/payment-intents/quickstart#automatic-confirmation-flow
除非您有充分的理由使用手动确认,否则我会坚持使用自动确认。
关于php - 如何正确使用付款意图,我不断收到错误无效付款意图状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57650812/