If you are using Stripe on public forms (without authentication) it is **strongly** recommended that you upgrade and consider installing the new **firewall** extension.
Increasingly spammers are finding CiviCRM sites and spamming the linked Stripe account with 1000s of attempted payments
and potentially causing your Stripe account to be temporarily blocked.
#### Changes
* Add support for firewall extension
* Add system check to recommend installing firewall extension
* Add checks and restrictions to AJAX endpoint
* Add cache code to js/css resources so they are reloaded immediately after cache clear.
*[#168](https://lab.civicrm.org/extensions/stripe/issues/168) Improve handling of webhooks with mismatched API versions - now we track the dashboard API version and don't try to explicitly set a webhook API version.
You may still need to delete and re-add your webhook but should not need to next time the API version changes.
#### Features
*[#126](https://lab.civicrm.org/extensions/stripe/issues/126) Stripe element now uses the CMS/CiviCRM locale so it will appear in the same language as the page instead of the browser language.
* Don't explicitly set webhook version when creating webhook. It will automatically track the dashboard API version.
* Add action button to webhook check.
* Improve workaround for [#147](https://lab.civicrm.org/extensions/stripe/issues/147) to also work with radio buttons and profiles.
CRM.$(function(d){g("civicrm_stripe loaded, dom-ready function firing.");if(window.civicrmStripeHandleReload){g("calling existing civicrmStripeHandleReload.");window.civicrmStripeHandleReload();return}varr;varb;varc;varv;varp=false;window.onbeforeunload=null;window.civicrmStripeHandleReload=function(){g("civicrmStripeHandleReload");varD=document.getElementById("card-element");if((typeofD!=="undefined")&&(D)){if(!D.children.length){g("checkAndLoad from document.ready");n()}}};window.civicrmStripeHandleReload();functionx(F,D){g(F+": success - submitting form");varE=document.createElement("input");E.setAttribute("type","hidden");E.setAttribute("name",F);E.setAttribute("value",D.id);c.appendChild(E);c.submit()}functionq(){for(i=0;i<v.length;++i){v[i].setAttribute("disabled",true)}returnc.submit()}functionj(D){g("error: "+D.error.message);varE=document.getElementById("card-errors");E.style.display="block";E.textContent=D.error.message;document.querySelector("#billing-payment-block").scrollIntoView();window.scrollBy(0,-50);c.dataset.submitted=false;for(i=0;i<v.length;++i){v[i].removeAttribute("disabled")}}functionB(){g("handle card payment");r.createPaymentMethod("card",b).then(function(D){if(D.error){j(D)}else{if(h()||a()){x("paymentMethodID",D.paymentMethod)}else{varE=CRM.url("civicrm/stripe/confirm-payment");d.post(E,{payment_method_id:D.paymentMethod.id,amount:s().toFixed(2),currency:CRM.vars.stripe.currency,id:CRM.vars.stripe.id,description:document.title}).then(function(F){y(F)})}}})}functiony(D){g("handleServerResponse");if(D.error){j(D)}else{if(D.requires_action){t(D)}else{x("paymentIntentID",D.paymentIntent)}}}functiont(D){r.handleCardAction(D.payment_intent_client_secret).then(function(E){if(E.error){j(E)}else{x("paymentIntentID",E.paymentIntent)}})}d(document).ajaxComplete(function(F,G,E){if((E.url.match("civicrm(/|%2F)payment(/|%2F)form")!==null)||(E.url.match("civicrm(/|%2F)contact(/|%2F)view(/|%2F)participant")!==null)){if(typeofCRM.vars.stripe==="undefined"){return}varD=l();if(D!==null){if(D!==parseInt(CRM.vars.stripe.id)){g("payment processor changed to id: "+D);if(D===0){returnm()}CRM.api3("PaymentProcessor","getvalue",{"return":"user_name",id:D,payment_processor_type_id:CRM.vars.stripe.paymentProcessorTypeID}).done(function(H){varI=H.result;if(I){g("Setting new stripe key to: "+I);CRM.vars.stripe.publishableKey=I}else{returnm()}g("checkAndLoad from ajaxComplete");n()})}}}});functionm(){g("New payment processor is not Stripe, clearing CRM.vars.stripe");if((typeofb!=="undefined")&&(b)){g("destroying card element");b.destroy();b=undefined}delete (CRM.vars.stripe)}functionn(){if(typeofCRM.vars.stripe==="undefined"){g("CRM.vars.stripe not defined! Not a Stripe processor?");return}if(typeofStripe==="undefined"){if(p){return}p=true;g("Stripe.js is not loaded!");d.getScript("https://js.stripe.com/v3",function(){g("Script loaded and executed.");p=false;f()})}else{f()}}functionf(){g("loadStripeBillingBlock");if(typeofr==="undefined"){r=Stripe(CRM.vars.stripe.publishableKey)}varK=r.elements({locale:CRM.vars.stripe.locale});varH={base:{fontSize:"20px"}};varE=document.getElementById("billing_postal_code-"+CRM.vars.stripe.billingAddressID).value;g("existing postcode: "+E);b=K.create("card",{style:H,value:{postalCode:E}});b.mount("#card-element");g("created new card element",b);e();if(document.getElementById("billing_postal_code-5").value){document.getElementById("billing_postal_code-5").setAttribute("disabled",true)}else{document.getElementsByClassName("billing_postal_code-"+CRM.vars.stripe.billingAddressID+"-section")[0].setAttribute("hidden",true)}b.addEventListener("change",function(L){w(L)});c=k();if(typeofc.length==="undefined"||c.length===0){g("No billing form!");return}v=C();c.dataset.submitdontprocess=false;varD=c.querySelectorAll('[type="submit"][formnovalidate="1"], [type="submit"][formnovalidate="formnovalidate"], [type="submit"].cancel, [type="submit"].webform-previous'),G;for(G=0;G<D.length;++G){D[G].addEventListener("click",J())}functionJ(){g("adding submitdontprocess");c.dataset.submitdontprocess=true}for(G=0;G<v.length;++G){v[G].addEventListener("click",F)}functionF(L){if(c.dataset.submitted===true){return}c.dataset.submitted=true;if(typeofCRM.vars.stripe==="undefined"){returnq()}g("clearing submitdontprocess");c.dataset.submitdontprocess=false;returnI(L)}for(G=0;G<v.length;++G){v[G].removeAttribute("onclick")}o();if(A()){d("[type=submit]").click(function(){u(this.value)});c.addEventListener("keydown",function(L){if(L.keyCode===13){u(this.value);I(event)}});d("#billingcheckbox:input").hide();d('label[for="billingcheckbox"]').hide()}functionI(N){N.preventDefault();g("submit handler");if(d(c).valid()===false){g("Form not valid");document.querySelector("#billing-payment-block").scrollIntoView();window.scrollBy(0,-50);returnfalse}if(typeofCRM.vars.stripe==="undefined"){g("Submitting - not a stripe processor");returntrue}if(c.dataset.submitted===true){g("form already submitted");returnfalse}varP=parseInt(CRM.vars.stripe.id);varM=null;if(A()){if(!d('input[name="submitted[civicrm_1_contribution_1_contribution_payment_processor_id]"]').length){M=P}else{M=parseInt(c.querySelector('input[name="submitted[civicrm_1_contribution_1_contribution_payment_processor_id]"]:checked').value)}}else{if((c.querySelector(".crm-section.payment_processor-section")!==null)||(c.querySelector(".crm-section.credit_card_info-section")!==null)){P=CRM.vars.stripe.id;if(c.querySelector('input[name="payment_processor_id"]:checked')!==null){M=parseInt(c.querySelector('input[name="payment_processor_id"]:checked').value)}}}if((M===0)||(P===null)||((M===null)&&(P===null))){g("Not a Stripe transaction, or pay-later");returnq()}else{g("Stripe is the selected payprocessor")}if(typeofCRM.vars.stripe.publishableKey==="undefined"){g("submit missing stripe-pub-key element or value");returntrue}if(c.dataset.submitdontprocess===true){g("non-payment submit detected - not submitting payment");returntrue}if(A()){if(d("#billing-payment-block").is(":hidden")){g("no payment processor on webform");returntrue}varO=d('[name="submitted[civicrm_1_contribution_1_contribution_payment_processor_id]"]');if(O.length){if(O.filter(":checked").val()==="0"||O.filter(":checked").val()===0){g("no payment processor selected");returntrue}}}varL=s();if(L===0){g("Total amount is 0");returnq()}if(c.dataset.submitted===true){alert("Form already submitted. Please wait.");returnfalse}else{c.dataset.submitted=true}for(G=0;G<v.length;++G){v[G].setAttribute("disabled",true)}B();returntrue}}functionA(){if(c!==null){returnc.classList.contains("webform-client-form")||c.classList.contains("webform-submission-form")}returnfalse}functionk(){varD=d("div#card-element").closest("form").prop("id");if((typeofD==="undefined")||(!D.length)){D=d("input[name=hidden_processor]").closest("form").prop("id")}returndocument.getElementById(D)}functionC(){varD=null;if(A()){D=c.querySelectorAll('[type="submit"].webform-submit');if(!D){D=c.querySelectorAll('[type="submit"].webform-button--submit')}}else{D=c.querySelectorAll('[type="submit"].validate')}returnD}functions(){varD=0;if(a()){D=null}else{if(document.getElementById("totalTaxAmount")!==null){D=parseFloat(z());g("Calculated amount using internal calculateTaxAmount()")}else{if(typeofcalculateTotalFee=="function"){D=parseFloat(calculateTotalFee())}else{if(A()){d(".line-item:visible","#wf-crm-billing-items").each(function(){D+=parseFloat(d(this).data("amount"))})}else{if(document.getElementById("total_amount")){D=parseFloat(document.getElementById("total_amount").value)}}}}}g("getTotalAmount: "+D);returnD}functionz(){varD=0;if(document.getElementById("totalTaxAmount")===null){returnD}if(document.getElementById("totalTaxAmount").textContent.length===0){D=document.getElementById("total_amount").value}else{D=document.getElementById("totalTaxAmount").textContent.split("").pop()}returnD}functionh(){varD=false;if(A()){if(d('input[id$="contribution-installments"]').length!==0&&d('input[id$="contribution-installments"]').val()>1){D=true}}if(document.getElementById("is_recur")!==null){if(document.getElementById("is_recur").type=="hidden"){D=(document.getElementById("is_recur").value==1)}else{D=Boolean(document.getElementById("is_recur").checked)}}else{if(d('input[name="auto_renew"]').length!==0){if(d('input[name="auto_renew"]').prop("checked")){D=true}else{if(document.getElementById("auto_renew").type=="hidden"){D=(document.getElementById("auto_renew").value==1)}else{D=Boolean(document.getElementById("auto_renew").checked)}}}}g("isRecur is "+D);returnD}functionw(D){if(!D.complete){return}document.getElementById("billing_postal_code-"+CRM.vars.stripe.billingAddressID).value=D.value.postalCode}functiono(){cividiscountElements=c.querySelectorAll("input#discountcode");varD=function(E){if(E.keyCode===13){E.preventDefault();g("adding submitdontprocess");c.dataset.submitdontprocess=true}};for(i=0;i<cividiscountElements.length;++i){cividiscountElements[i].addEventListener("keydown",D)}}functione(){d(".billing_name_address-section div.label span.crm-marker").each(function(){d(this).closest("div").next("div").children("input").addClass("required")})}functiona(){if((document.getElementById("additional_participants")!==null)&&(document.getElementById("additional_participants").value.length!==0)){g("We don't know the final price - registering additional participants");returntrue}returnfalse}functiong(D){if((typeof(CRM.vars.stripe)==="undefined")||(Boolean(CRM.vars.stripe.jsDebug)===true)){console.log(newDate().toISOString()+" civicrm_stripe.js: "+D)}}functionu(E){varD=null;if(document.getElementById("action")!==null){D=document.getElementById("action")}else{D=document.createElement("input")}D.setAttribute("type","hidden");D.setAttribute("name","op");D.setAttribute("id","action");D.setAttribute("value",E);c.appendChild(D)}functionl(){if((typeofc==="undefined")||(!c)){c=k();if(!c){returnnull}}varD=c.querySelector('input[name="payment_processor_id"]:checked');if(D!==null){returnparseInt(D.value)}returnnull}});
\ No newline at end of file
CRM.$(function(d){g("civicrm_stripe loaded, dom-ready function firing.");if(window.civicrmStripeHandleReload){g("calling existing civicrmStripeHandleReload.");window.civicrmStripeHandleReload();return}varr;varb;varc;varv;varp=false;window.onbeforeunload=null;window.civicrmStripeHandleReload=function(){g("civicrmStripeHandleReload");varD=document.getElementById("card-element");if((typeofD!=="undefined")&&(D)){if(!D.children.length){g("checkAndLoad from document.ready");n()}}};window.civicrmStripeHandleReload();functionx(F,D){g(F+": success - submitting form");varE=document.createElement("input");E.setAttribute("type","hidden");E.setAttribute("name",F);E.setAttribute("value",D.id);c.appendChild(E);c.submit()}functionq(){for(i=0;i<v.length;++i){v[i].setAttribute("disabled",true)}returnc.submit()}functionj(D){g("error: "+D.error.message);varE=document.getElementById("card-errors");E.style.display="block";E.textContent=D.error.message;document.querySelector("#billing-payment-block").scrollIntoView();window.scrollBy(0,-50);c.dataset.submitted=false;for(i=0;i<v.length;++i){v[i].removeAttribute("disabled")}}functionB(){g("handle card payment");r.createPaymentMethod("card",b).then(function(D){if(D.error){j(D)}else{if(h()||a()){x("paymentMethodID",D.paymentMethod)}else{varE=CRM.url("civicrm/stripe/confirm-payment");d.post(E,{payment_method_id:D.paymentMethod.id,amount:s().toFixed(2),currency:CRM.vars.stripe.currency,id:CRM.vars.stripe.id,description:document.title,csrfToken:CRM.vars.stripe.csrfToken}).then(function(F){y(F)})}}})}functiony(D){g("handleServerResponse");if(D.error){j(D)}else{if(D.requires_action){t(D)}else{x("paymentIntentID",D.paymentIntent)}}}functiont(D){r.handleCardAction(D.payment_intent_client_secret).then(function(E){if(E.error){j(E)}else{x("paymentIntentID",E.paymentIntent)}})}d(document).ajaxComplete(function(F,G,E){if((E.url.match("civicrm(/|%2F)payment(/|%2F)form")!==null)||(E.url.match("civicrm(/|%2F)contact(/|%2F)view(/|%2F)participant")!==null)){if(typeofCRM.vars.stripe==="undefined"){return}varD=l();if(D!==null){if(D!==parseInt(CRM.vars.stripe.id)){g("payment processor changed to id: "+D);if(D===0){returnm()}CRM.api3("PaymentProcessor","getvalue",{"return":"user_name",id:D,payment_processor_type_id:CRM.vars.stripe.paymentProcessorTypeID}).done(function(H){varI=H.result;if(I){g("Setting new stripe key to: "+I);CRM.vars.stripe.publishableKey=I}else{returnm()}g("checkAndLoad from ajaxComplete");n()})}}}});functionm(){g("New payment processor is not Stripe, clearing CRM.vars.stripe");if((typeofb!=="undefined")&&(b)){g("destroying card element");b.destroy();b=undefined}delete (CRM.vars.stripe)}functionn(){if(typeofCRM.vars.stripe==="undefined"){g("CRM.vars.stripe not defined! Not a Stripe processor?");return}if(typeofStripe==="undefined"){if(p){return}p=true;g("Stripe.js is not loaded!");d.getScript("https://js.stripe.com/v3",function(){g("Script loaded and executed.");p=false;f()})}else{f()}}functionf(){g("loadStripeBillingBlock");if(typeofr==="undefined"){r=Stripe(CRM.vars.stripe.publishableKey)}varK=r.elements({locale:CRM.vars.stripe.locale});varH={base:{fontSize:"20px"}};varE=document.getElementById("billing_postal_code-"+CRM.vars.stripe.billingAddressID).value;g("existing postcode: "+E);b=K.create("card",{style:H,value:{postalCode:E}});b.mount("#card-element");g("created new card element",b);e();if(document.getElementById("billing_postal_code-5").value){document.getElementById("billing_postal_code-5").setAttribute("disabled",true)}else{document.getElementsByClassName("billing_postal_code-"+CRM.vars.stripe.billingAddressID+"-section")[0].setAttribute("hidden",true)}b.addEventListener("change",function(L){w(L)});c=k();if(typeofc.length==="undefined"||c.length===0){g("No billing form!");return}v=C();c.dataset.submitdontprocess=false;varD=c.querySelectorAll('[type="submit"][formnovalidate="1"], [type="submit"][formnovalidate="formnovalidate"], [type="submit"].cancel, [type="submit"].webform-previous'),G;for(G=0;G<D.length;++G){D[G].addEventListener("click",J())}functionJ(){g("adding submitdontprocess");c.dataset.submitdontprocess=true}for(G=0;G<v.length;++G){v[G].addEventListener("click",F)}functionF(L){if(c.dataset.submitted===true){return}c.dataset.submitted=true;if(typeofCRM.vars.stripe==="undefined"){returnq()}g("clearing submitdontprocess");c.dataset.submitdontprocess=false;returnI(L)}for(G=0;G<v.length;++G){v[G].removeAttribute("onclick")}o();if(A()){d("[type=submit]").click(function(){u(this.value)});c.addEventListener("keydown",function(L){if(L.keyCode===13){u(this.value);I(event)}});d("#billingcheckbox:input").hide();d('label[for="billingcheckbox"]').hide()}functionI(N){N.preventDefault();g("submit handler");if(d(c).valid()===false){g("Form not valid");document.querySelector("#billing-payment-block").scrollIntoView();window.scrollBy(0,-50);returnfalse}if(typeofCRM.vars.stripe==="undefined"){g("Submitting - not a stripe processor");returntrue}if(c.dataset.submitted===true){g("form already submitted");returnfalse}varP=parseInt(CRM.vars.stripe.id);varM=null;if(A()){if(!d('input[name="submitted[civicrm_1_contribution_1_contribution_payment_processor_id]"]').length){M=P}else{M=parseInt(c.querySelector('input[name="submitted[civicrm_1_contribution_1_contribution_payment_processor_id]"]:checked').value)}}else{if((c.querySelector(".crm-section.payment_processor-section")!==null)||(c.querySelector(".crm-section.credit_card_info-section")!==null)){P=CRM.vars.stripe.id;if(c.querySelector('input[name="payment_processor_id"]:checked')!==null){M=parseInt(c.querySelector('input[name="payment_processor_id"]:checked').value)}}}if((M===0)||(P===null)||((M===null)&&(P===null))){g("Not a Stripe transaction, or pay-later");returnq()}else{g("Stripe is the selected payprocessor")}if(typeofCRM.vars.stripe.publishableKey==="undefined"){g("submit missing stripe-pub-key element or value");returntrue}if(c.dataset.submitdontprocess===true){g("non-payment submit detected - not submitting payment");returntrue}if(A()){if(d("#billing-payment-block").is(":hidden")){g("no payment processor on webform");returntrue}varO=d('[name="submitted[civicrm_1_contribution_1_contribution_payment_processor_id]"]');if(O.length){if(O.filter(":checked").val()==="0"||O.filter(":checked").val()===0){g("no payment processor selected");returntrue}}}varL=s();if(L===0){g("Total amount is 0");returnq()}if(c.dataset.submitted===true){alert("Form already submitted. Please wait.");returnfalse}else{c.dataset.submitted=true}for(G=0;G<v.length;++G){v[G].setAttribute("disabled",true)}B();returntrue}}functionA(){if(c!==null){returnc.classList.contains("webform-client-form")||c.classList.contains("webform-submission-form")}returnfalse}functionk(){varD=d("div#card-element").closest("form").prop("id");if((typeofD==="undefined")||(!D.length)){D=d("input[name=hidden_processor]").closest("form").prop("id")}returndocument.getElementById(D)}functionC(){varD=null;if(A()){D=c.querySelectorAll('[type="submit"].webform-submit');if(!D){D=c.querySelectorAll('[type="submit"].webform-button--submit')}}else{D=c.querySelectorAll('[type="submit"].validate')}returnD}functions(){varD=0;if(a()){D=null}else{if(document.getElementById("totalTaxAmount")!==null){D=parseFloat(z());g("Calculated amount using internal calculateTaxAmount()")}else{if(typeofcalculateTotalFee=="function"){D=parseFloat(calculateTotalFee())}else{if(A()){d(".line-item:visible","#wf-crm-billing-items").each(function(){D+=parseFloat(d(this).data("amount"))})}else{if(document.getElementById("total_amount")){D=parseFloat(document.getElementById("total_amount").value)}}}}}g("getTotalAmount: "+D);returnD}functionz(){varD=0;if(document.getElementById("totalTaxAmount")===null){returnD}if(document.getElementById("totalTaxAmount").textContent.length===0){D=document.getElementById("total_amount").value}else{D=document.getElementById("totalTaxAmount").textContent.split("").pop()}returnD}functionh(){varD=false;if(A()){if(d('input[id$="contribution-installments"]').length!==0&&d('input[id$="contribution-installments"]').val()>1){D=true}}if(document.getElementById("is_recur")!==null){if(document.getElementById("is_recur").type=="hidden"){D=(document.getElementById("is_recur").value==1)}else{D=Boolean(document.getElementById("is_recur").checked)}}else{if(d('input[name="auto_renew"]').length!==0){if(d('input[name="auto_renew"]').prop("checked")){D=true}else{if(document.getElementById("auto_renew").type=="hidden"){D=(document.getElementById("auto_renew").value==1)}else{D=Boolean(document.getElementById("auto_renew").checked)}}}}g("isRecur is "+D);returnD}functionw(D){if(!D.complete){return}document.getElementById("billing_postal_code-"+CRM.vars.stripe.billingAddressID).value=D.value.postalCode}functiono(){cividiscountElements=c.querySelectorAll("input#discountcode");varD=function(E){if(E.keyCode===13){E.preventDefault();g("adding submitdontprocess");c.dataset.submitdontprocess=true}};for(i=0;i<cividiscountElements.length;++i){cividiscountElements[i].addEventListener("keydown",D)}}functione(){d(".billing_name_address-section div.label span.crm-marker").each(function(){d(this).closest("div").next("div").children("input").addClass("required")})}functiona(){if((document.getElementById("additional_participants")!==null)&&(document.getElementById("additional_participants").value.length!==0)){g("We don't know the final price - registering additional participants");returntrue}returnfalse}functiong(D){if((typeof(CRM.vars.stripe)==="undefined")||(Boolean(CRM.vars.stripe.jsDebug)===true)){console.log(newDate().toISOString()+" civicrm_stripe.js: "+D)}}functionu(E){varD=null;if(document.getElementById("action")!==null){D=document.getElementById("action")}else{D=document.createElement("input")}D.setAttribute("type","hidden");D.setAttribute("name","op");D.setAttribute("id","action");D.setAttribute("value",E);c.appendChild(D)}functionl(){if((typeofc==="undefined")||(!c)){c=k();if(!c){returnnull}}varD=c.querySelector('input[name="payment_processor_id"]:checked');if(D!==null){returnparseInt(D.value)}returnnull}});