我正在尝试实现付款意图api,但我一直得到无效的付款意图状态,我看到了堆栈溢出的答案,但没有帮助, 我不知道它是在服务器端还是客户端方面执行不佳,因为我对此还很陌生
我已经尝试在收费下将require_action更改为require_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>
我不断收到错误消息:无效的付款意图状态
答案 0 :(得分:2)
看起来您可能正在处理较旧的文档。由于代码正在寻找状态requires_source_action
(不存在)https://stripe.com/docs/payments/intents#intent-statuses
实际状态可能是requires_confirmation
,在这种情况下,您必须确认服务器上的PaymentIntent。然后根据状态获得requires_action
或succeeded
的状态。您会获得哪一个取决于所涉及的卡是否需要3DS。
由于您的PaymentIntent使用的是手动确认流程,这意味着您必须在实际完成付款之前在前端和后端之间进行几次往返。我建议您改用自动确认。这样,您只有2个步骤:
handleCardPayment
完成付款此处提供有关该流程的更多信息:https://stripe.com/docs/payments/payment-intents/quickstart#automatic-confirmation-flow
除非您有充分的理由使用手动确认,否则我会坚持使用自动确认。