I'm trying to implement a pretty straightforward flow for my product:
Customer adds card to his account
Customer makes a request -> Create a hold on his card for the request price
On request delivered -> Execute the initial hold made on the card
Upon reading through loads of docs on Stripe's new Intent API, this seemed pretty simple.
A. Create a Stripe customer
stripe.customers.create({ email: user.email, description:
Customer for ${user.email}});
B. Attach a card (payment method) to the customer, create a setup intent
with this card to authorize future charges
stripe.setupIntents.create({ 'customer': customer_id, 'payment_method': paymentMethodId });
C. On a request made by the customer, create paymentIntent with capture_method
set to manual
const paymentIntent = await stripe.paymentIntents.create({
'amount': price * 100, //convert shekels to agorot
'currency': 'ILS',
'customer': customer_id,
'payment_method': payment_method,
'payment_method_types': ['card'],
'capture_method': 'manual'
});
D. On request delivered, simply capture
the original paymentIntent
created in step C.
const captureHoldIntent = await stripe.paymentIntents.capture(paymentIntentId);
The issue I'm getting actually is occurring between steps C and D:
Failed to save transaction for user_id KAJSD92 error Error: This PaymentIntent could not be captured because it has a status of requires_confirmation. Only a PaymentIntent with one of the following statuses may be captured: requires_capture.
While I understand this error message, my confusion is as to why the paymentIntent
created in step C doesn't change to the requires_capture
status and is instead always require_confirmation
, even though it has already been confirmed?
The missing piece was calling paymentIntents.confirm
to "confirm" that the service actually wants to place a hold on the card. After that, the intents status was changed to requires_capture
which allowed me to call the capture
method.
const paymentIntent = await stripe.paymentIntents.create({
'amount': price * 100, //convert shekels to agorot
'currency': 'ILS',
'customer': customer_id,
'payment_method': payment_method,
'payment_method_types': ['card'],
'capture_method': 'manual'
});
const confirmPaymentIntent = await stripe.paymentIntents.confirm(intentId);
const captureHoldIntent = await stripe.paymentIntents.capture(intentId);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With