diff --git a/CRM/Stripe/AJAX.php b/CRM/Stripe/AJAX.php index 032e7cd58c8c961ff4d96fbbe0414531e2d04c91..f8d33bf564634be8bf92079d51bab8eba3d128a3 100644 --- a/CRM/Stripe/AJAX.php +++ b/CRM/Stripe/AJAX.php @@ -12,6 +12,28 @@ class CRM_Stripe_AJAX { /** * Generate the paymentIntent for civicrm_stripe.js * + * In the normal flow of a CiviContribute form, this will be called with a + * payment_method_id (which is generated by Stripe via its javascript code), + * in which case it will create a PaymentIntent using that and *attempt* to + * 'confirm' it. + * + * This can also be called with a payment_intent_id instead, in which case it + * will retrieve the PaymentIntent and attempt (again) to 'confirm' it. This + * is useful to confirm funds after a user has completed SCA in their + * browser. + * + * 'confirming' a PaymentIntent refers to the process by which the funds are + * reserved in the cardholder's account, but not actually taken yet. + * + * Taking the funds ('capturing') should go through without problems once the + * transaction has been confirmed - this is done later on in the process. + * + * Nb. confirmed funds are released and will become available to the + * cardholder again if the PaymentIntent is cancelled or is not captured + * within 1 week. + * + * Outputs an array as a JSON response see generatePaymentResponse + * * @throws \CRM_Core_Exception * @throws \CiviCRM_API3_Exception */ @@ -24,7 +46,14 @@ class CRM_Stripe_AJAX { $processor = new CRM_Core_Payment_Stripe('', civicrm_api3('PaymentProcessor', 'getsingle', ['id' => $processorID])); $processor->setAPIParams(); - if (!$paymentIntentID) { + if ($paymentIntentID) { + // We already have a PaymentIntent, retrieve and attempt confirm. + $intent = \Stripe\PaymentIntent::retrieve($paymentIntentID); + $intent->confirm(); + } + else { + // We don't yet have a PaymentIntent, create one using the + // Payment Method ID and attempt to confirm it too. try { $intent = \Stripe\PaymentIntent::create([ 'payment_method' => $paymentMethodID,