From 49d4eebddb37315ed85bfb67037ebb38fcfa7f87 Mon Sep 17 00:00:00 2001
From: Jamie McClelland <jm@mayfirst.org>
Date: Wed, 18 Apr 2018 11:53:09 -0400
Subject: [PATCH] allow multiple stripe payment processor on back end

Without this patch, you can the error "no such token" if:

 * You have two different stripe payment processors configured.
 * you are making an offline contribution
 * using the provided payment processor back end, you choose the
 non-default payment processor.

The stripe javascript submits the payment using the default payment
processor, but the PHP codes tries to charge it using the user-selected
payment processor, which leads to the error.

This fix also ensures that if a non-stripe payment processor is chosen
we won't try to send it to stripe.
---
 js/civicrm_stripe.js | 46 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/js/civicrm_stripe.js b/js/civicrm_stripe.js
index 6d4fd698..06407691 100644
--- a/js/civicrm_stripe.js
+++ b/js/civicrm_stripe.js
@@ -64,6 +64,48 @@
     // /civicrm/contact/view/participant occurs when payproc is first loaded on event credit card payment
     if ((settings.url.match("/civicrm/payment/form?"))
        || (settings.url.match("/civicrm/contact/view/participant?"))) {
+      // See if there is a payment processor selector on this form
+      // (e.g. an offline credit card contribution page).
+      if ($('#payment_processor_id').length > 0) {
+        // There is. Check if the selected payment processor is different
+        // from the one we think we should be using.
+        var ppid = $('#payment_processor_id').val();
+        if (ppid != $('#stripe-id').val()) {
+          debugging('payment processor changed to id: ' + ppid);
+          // It is! See if the new payment processor is also a Stripe
+          // Payment processor. First, find out what the stripe
+          // payment processor type id is (we don't want to update
+          // the stripe pub key with a value from another payment processor).
+          CRM.api3('PaymentProcessorType', 'getvalue', {
+            "sequential": 1,
+            "return": "id",
+            "name": "Stripe"
+          }).done(function(result) {
+            // Now, see if the new payment processor id is a stripe
+            // payment processor.
+            var stripe_pp_type_id = result['result'];
+            CRM.api3('PaymentProcessor', 'getvalue', {
+              "sequential": 1,
+              "return": "password",
+              "id": ppid,
+              "payment_processor_type_id": stripe_pp_type_id,
+            }).done(function(result) {
+              var pub_key = result['result'];
+              if (pub_key) {
+                // It is a stripe payment processor, so update the key.
+                debugging("Setting new stripe key to: " + pub_key);
+                $('#stripe-pub-key').val(pub_key);
+              }
+              else {
+                debugging("New payment processor is not Stripe, setting stripe-pub-key to null");
+                $('#stripe-pub-key').val(null);
+              }
+              // Now reload the billing block.
+              loadStripeBillingBlock();
+            });
+          });
+        }
+      }
       loadStripeBillingBlock();
     }
   });
@@ -183,8 +225,8 @@
       $form = getBillingForm();
 
       // Don't handle submits generated by non-stripe processors
-      if (!$('input#stripe-pub-key').length) {
-        debugging('submit missing stripe-pub-key element');
+      if (!$('input#stripe-pub-key').length || !($('input#stripe-pub-key').val())) {
+        debugging('submit missing stripe-pub-key element or value');
         return true;
       }
       // Don't handle submits generated by the CiviDiscount button.
-- 
GitLab