diff --git a/CRM/Stripe/AJAX.php b/CRM/Stripe/AJAX.php index 263b679990c38065255451b5d517b045ca491c5c..4bcce974a308ccc002c0d1c7cf1b35b54837c0ef 100644 --- a/CRM/Stripe/AJAX.php +++ b/CRM/Stripe/AJAX.php @@ -11,6 +11,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 */ @@ -23,7 +45,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,