diff --git a/api/v3/StripePaymentintent.php b/api/v3/StripePaymentintent.php
index b4d9f43bc3d1002caf64c5a0f8409dcd9633c67e..fc6701b6a7b82cfd153aea47819d487e12ffa6a4 100644
--- a/api/v3/StripePaymentintent.php
+++ b/api/v3/StripePaymentintent.php
@@ -215,7 +215,7 @@ function civicrm_api3_stripe_paymentintent_process($params) {
       elseif ($e instanceof \Stripe\Exception\InvalidRequestException) {
         $message = 'Invalid request';
       }
-      return civicrm_api3_create_error(['message' => $message]);
+      return civicrm_api3_create_error($message);
     }
   }
 
@@ -236,7 +236,7 @@ function civicrm_api3_stripe_paymentintent_process($params) {
     // Tell the client to handle the action
     return civicrm_api3_create_success([
       'requires_action' => true,
-      'paymentintent_client_secret' => $intent->client_secret,
+      'paymentIntentClientSecret' => $intent->client_secret,
     ]);
   }
   elseif (($intent->status === 'requires_capture') || ($intent->status === 'requires_confirmation')) {
@@ -257,7 +257,7 @@ function civicrm_api3_stripe_paymentintent_process($params) {
   elseif ($intent->status === 'requires_payment_method') {
     return civicrm_api3_create_success([
       'requires_payment_method' => true,
-      'paymentintent_client_secret' => $intent->client_secret,
+      'paymentIntentClientSecret' => $intent->client_secret,
     ]);
   }
   else {
diff --git a/js/civicrmStripeConfirm.js b/js/civicrmStripeConfirm.js
index 3bb5825fc43713aa5dd9f892391fce3c9a64d3b7..0c79b9649cf439dac6007dde52e34c1db22be1e6 100644
--- a/js/civicrmStripeConfirm.js
+++ b/js/civicrmStripeConfirm.js
@@ -51,7 +51,7 @@
     handlePaymentIntentAction: function(response) {
       switch (CRM.vars.stripe.paymentIntentMethod) {
         case 'automatic':
-          confirm.stripe.handleCardPayment(response.payment_intent_client_secret)
+          confirm.stripe.handleCardPayment(response.paymentIntentClientSecret)
             .then(function(result) {
               if (result.error) {
                 // Show error in payment form
@@ -66,7 +66,7 @@
           break;
 
         case 'manual':
-          confirm.stripe.handleCardAction(response.payment_intent_client_secret)
+          confirm.stripe.handleCardAction(response.paymentIntentClientSecret)
             .then(function(result) {
               if (result.error) {
                 // Show error in payment form
diff --git a/js/civicrm_stripe.js b/js/civicrm_stripe.js
index b42bb679362de900c5e31d4a54c81cfa8c07e632..dc715ea79794d87147020977aeb9a9f96750957e 100644
--- a/js/civicrm_stripe.js
+++ b/js/civicrm_stripe.js
@@ -131,6 +131,7 @@
     }
     triggerEvent('crmBillingFormNotValid');
     if (notify) {
+      swalClose();
       swalFire({
         icon: 'error',
         text: errorMessage,
@@ -233,7 +234,7 @@
             }
           }, '', false);
           CRM.api3('StripePaymentintent', 'Process', {
-            payment_method_id: result.paymentMethod.id,
+            payment_method_id: createPaymentMethodResult.paymentMethod.id,
             amount: CRM.payment.getTotalAmount().toFixed(2),
             currency: CRM.payment.getCurrency(CRM.vars.stripe.currency),
             id: CRM.vars.stripe.id,
@@ -241,14 +242,43 @@
             csrfToken: CRM.vars.stripe.csrfToken,
             extra_data: CRM.payment.getBillingEmail() + CRM.payment.getBillingName()
           })
-            .done(function (result) {
-              // Handle server response (see Step 3)
+            .done(function (paymentIntentProcessResponse) {
               swalClose();
-              handleServerResponse(result);
+              debugging('StripePaymentintent.Process done');
+              if (paymentIntentProcessResponse.is_error) {
+                // Triggered for api3_create_error or Exception
+                displayError(paymentIntentProcessResponse.error_message, true);
+              }
+              else {
+                paymentIntentProcessResponse = paymentIntentProcessResponse.values;
+                if (paymentIntentProcessResponse.requires_action) {
+                  // Use Stripe.js to handle a pending card action (eg. 3d-secure)
+                  paymentData.clientSecret = paymentIntentProcessResponse.paymentIntentClientSecret;
+                  stripe.handleCardAction(paymentData.clientSecret)
+                    .then(function(cardActionResult) {
+                      if (cardActionResult.error) {
+                        // Show error in payment form
+                        displayError(cardActionResult.error.message, true);
+                      } else {
+                        // The card action has been handled
+                        // The PaymentIntent can be confirmed again on the server
+                        successHandler('paymentIntentID', cardActionResult.paymentIntent);
+                      }
+                    });
+                }
+                else {
+                  // All good, we can submit the form
+                  successHandler('paymentIntentID', paymentIntentProcessResponse.paymentIntent);
+                }
+              }
             })
-            .fail(function() {
-              swalClose();
-              displayError('Unknown error', true);
+            .fail(function(object) {
+              // Triggered when http code !== 200 (eg. 400 Bad request)
+              var error = 'Unknown error';
+              if (object.hasOwnProperty('statusText')) {
+                error = object.statusText;
+              }
+              displayError(error, true);
             });
         }
       }
@@ -274,55 +304,32 @@
       id: CRM.vars.stripe.id,
       description: document.title,
       csrfToken: CRM.vars.stripe.csrfToken
-      //metadata: {integration_check: accept_a_payment}
     })
-      .done(function(result) {
-        // Handle server response (see Step 3)
+      .done(function(paymentIntentProcessResponse) {
         swalClose();
-        // Trigger the paymentRequest dialog
-        paymentData.clientSecret = result.values.payment_intent_client_secret;
-        paymentData.paymentRequest.show();
-        // From here the on 'paymentmethod' of the paymentRequest handles completion/failure
+        debugging('StripePaymentintent.Process done');
+        if (paymentIntentProcessResponse.is_error) {
+          // Triggered for api3_create_error or Exception
+          displayError(paymentIntentProcessResponse.error_message, true);
+        }
+        else {
+          paymentIntentProcessResponse = paymentIntentProcessResponse.values;
+          // Trigger the paymentRequest dialog
+          paymentData.clientSecret = paymentIntentProcessResponse.paymentIntentClientSecret;
+          paymentData.paymentRequest.show();
+          // From here the on 'paymentmethod' of the paymentRequest handles completion/failure
+        }
       })
-      .fail(function(result) {
+      .fail(function(object) {
+        // Triggered when http code !== 200 (eg. 400 Bad request)
         var error = 'Unknown error';
-        if (result.hasOwnProperty('statusText')) {
-          error = result.statusText;
+        if (object.hasOwnProperty('statusText')) {
+          error = object.statusText;
         }
-        swalClose();
         displayError(error, true);
       });
   }
 
-  function handleServerResponse(result) {
-    debugging('handleServerResponse');
-    if (result.error) {
-      // Show error from server on payment form
-      displayError(result.error.message, true);
-    } else if (result.requires_action) {
-      // Use Stripe.js to handle required card action
-      handleAction(result);
-    } else {
-      // All good, we can submit the form
-      successHandler('paymentIntentID', result.paymentIntent);
-    }
-  }
-
-  function handleAction(result) {
-    paymentData.clientSecret = result.payment_intent_client_secret;
-    stripe.handleCardAction(paymentData.clientSecret)
-      .then(function(cardActionResult) {
-        if (cardActionResult.error) {
-          // Show error in payment form
-          displayError(cardActionResult.error.message, true);
-        } else {
-          // The card action has been handled
-          // The PaymentIntent can be confirmed again on the server
-          successHandler('paymentIntentID', cardActionResult.paymentIntent);
-        }
-      });
-  }
-
   /**
    * Payment processor is not Stripe - cleanup
    */