Could you try following code?
Code:const stripe = Stripe (PublishableKey); let elements; initialize(); checkStatus(); document .querySelector("#payment-form") .addEventListener("submit", handleSubmit); // Fetches a payment intent and captures the client secret async function initialize(){ const { clientSecret } = await clientS; // const { clientSecret } =await fetch("/create.php", { // method: "POST", // headers: { "Content-Type": "application/json" }, // body: JSON.stringify({ items }), // }).then((r) => r.json()); elements = stripe.elements({ clientSecret }); const paymentElementOptions = { layout: "tabs", }; const paymentElement = elements.create("payment", paymentElementOptions); paymentElement.mount("#payment-element"); } async function handleSubmit(e) { e.preventDefault(); setLoading(true); const response = await stripe.confirmPayment({ elements, confirmParams: { return_url: confirmationURL, }, redirect: 'if_required' } ) if (response.error) { showMessage(response.error.message); } else { showMessage(`Payment Succeeded: ${response.paymentIntent.id}`); } setLoading(false); } // Fetches the payment intent status after payment submission async function checkStatus() { const clientSecret = new URLSearchParams(window.location.search).get( "payment_intent_client_secret" ); if (!clientSecret) { return; } const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret); switch (paymentIntent.status) { case "succeeded": document.getElementById('checkoutConfirmDefaultHeading').textContent = 'Payment succeeded!.'; document.getElementById("btn_submit").click(); showMessage("Payment succeeded!"); break; case "processing": document.getElementById('checkoutConfirmDefaultHeading').textContent='Your payment is processing.'; showMessage("Your payment is processing."); break; case "requires_payment_method": document.getElementById('checkoutConfirmDefaultHeading').textContent='Your payment was not successful, please try again.'; showMessage("Your payment was not successful, please try again."); break; default: document.getElementById('checkoutConfirmDefaultHeading').textContent='Something went wrong.'; showMessage("Something went wrong."); break; } } // ------- UI helpers ------- function showMessage(messageText) { const messageContainer = document.querySelector("#payment-message"); messageContainer.classList.remove("hidden"); messageContainer.textContent = messageText; setTimeout(function () { messageContainer.classList.add("hidden"); messageText.textContent = ""; }, 4000); } // Show a spinner on payment submission function setLoading(isLoading) { if (isLoading) { // Disable the button and show a spinner document.querySelector("#submit").disabled = true; document.querySelector("#spinner").classList.remove("hidden"); document.querySelector("#button-text").classList.add("hidden"); } else { document.querySelector("#submit").disabled = false; document.querySelector("#spinner").classList.add("hidden"); document.querySelector("#button-text").classList.remove("hidden"); } }
It does not work.
sorry.
Could you give me a few weeks?
and Try version 2.0.5.
Could you try following code?
Code:const stripe = Stripe (PublishableKey); let elements; initialize(); checkStatus(); document .querySelector("#payment-form") .addEventListener("submit", handleSubmit); // Fetches a payment intent and captures the client secret async function initialize(){ const { clientSecret } = await clientS; // const { clientSecret } =await fetch("/create.php", { // method: "POST", // headers: { "Content-Type": "application/json" }, // body: JSON.stringify({ items }), // }).then((r) => r.json()); elements = stripe.elements({ clientSecret }); const paymentElementOptions = { layout: "tabs", }; const paymentElement = elements.create("payment", paymentElementOptions); paymentElement.mount("#payment-element"); } async function handleSubmit(e) { e.preventDefault(); setLoading(true); const response = await stripe.confirmPayment({ elements, confirmParams: { return_url: confirmationURL, }, redirect: 'if_required' } ) if (response.error) { showMessage(response.error.message); } else { showMessage(`Payment Succeeded: ${response.paymentIntent.id}`); document.getElementById("btn_submit").click(); } setLoading(false); } // Fetches the payment intent status after payment submission async function checkStatus() { const clientSecret = new URLSearchParams(window.location.search).get( "payment_intent_client_secret" ); if (!clientSecret) { return; } const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret); switch (paymentIntent.status) { case "succeeded": document.getElementById('checkoutConfirmDefaultHeading').textContent = 'Payment succeeded!.'; showMessage("Payment succeeded!"); document.getElementById("btn_submit").click(); break; case "processing": document.getElementById('checkoutConfirmDefaultHeading').textContent='Your payment is processing.'; showMessage("Your payment is processing."); break; case "requires_payment_method": document.getElementById('checkoutConfirmDefaultHeading').textContent='Your payment was not successful, please try again.'; showMessage("Your payment was not successful, please try again."); break; default: document.getElementById('checkoutConfirmDefaultHeading').textContent='Something went wrong.'; showMessage("Something went wrong."); break; } } // ------- UI helpers ------- function showMessage(messageText) { const messageContainer = document.querySelector("#payment-message"); messageContainer.classList.remove("hidden"); messageContainer.textContent = messageText; setTimeout(function () { messageContainer.classList.add("hidden"); messageText.textContent = ""; }, 4000); } // Show a spinner on payment submission function setLoading(isLoading) { if (isLoading) { // Disable the button and show a spinner document.querySelector("#submit").disabled = true; document.querySelector("#spinner").classList.remove("hidden"); document.querySelector("#button-text").classList.add("hidden"); } else { document.querySelector("#submit").disabled = false; document.querySelector("#spinner").classList.add("hidden"); document.querySelector("#button-text").classList.remove("hidden"); } }
Just tested now and that did the trick thankyou :)
Klarna, clearpay and card payments work as expected, could possibly benefit from a pop up to confirm the order is processing between the redirect from payment succeeded to order confirmation page for people with slow connections? The payment form shows below the payment succeeded message, i waited momentarily knowing it may take a few moments, slightly confusing for folk but functional though :)
A message will be displayed after a successful payment.
To change this message, change the code of line6 TEXT_PAYMENT_STRIPE_SUCCESS in \includes\languages\----------\modules\payment\lang.stripe.php.
Fixed checkout.js
Code:const stripe = Stripe (PublishableKey); let elements; initialize(); checkStatus(); document .querySelector("#payment-form") .addEventListener("submit", handleSubmit); // Fetches a payment intent and captures the client secret async function initialize(){ const { clientSecret } = await clientS; // const { clientSecret } =await fetch("/create.php", { // method: "POST", // headers: { "Content-Type": "application/json" }, // body: JSON.stringify({ items }), // }).then((r) => r.json()); elements = stripe.elements({ clientSecret }); const paymentElementOptions = { layout: "tabs", }; const paymentElement = elements.create("payment", paymentElementOptions); paymentElement.mount("#payment-element"); } async function handleSubmit(e) { e.preventDefault(); setLoading(true); const response = await stripe.confirmPayment({ elements, confirmParams: { return_url: confirmationURL, }, redirect: 'if_required' } ) if (response.error) { showMessage(response.error.message); } else { document.getElementById('checkoutConfirmDefaultHeading').textContent = PaymentSuccess; showMessage(PaymentSuccess); document.getElementById("btn_submit").click(); } setLoading(false); } // Fetches the payment intent status after payment submission async function checkStatus() { const clientSecret = new URLSearchParams(window.location.search).get( "payment_intent_client_secret" ); if (!clientSecret) { return; } const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret); switch (paymentIntent.status) { case "succeeded": document.getElementById('checkoutConfirmDefaultHeading').textContent = PaymentSuccess; showMessage(PaymentSuccess); document.getElementById("btn_submit").click(); break; case "processing": document.getElementById('checkoutConfirmDefaultHeading').textContent='Your payment is processing.'; showMessage("Your payment is processing."); break; case "requires_payment_method": document.getElementById('checkoutConfirmDefaultHeading').textContent='Your payment was not successful, please try again.'; showMessage("Your payment was not successful, please try again."); break; default: document.getElementById('checkoutConfirmDefaultHeading').textContent='Something went wrong.'; showMessage("Something went wrong."); break; } } // ------- UI helpers ------- function showMessage(messageText) { const messageContainer = document.querySelector("#payment-message"); messageContainer.classList.remove("hidden"); messageContainer.textContent = messageText; setTimeout(function () { messageContainer.classList.add("hidden"); messageText.textContent = ""; }, 4000); } // Show a spinner on payment submission function setLoading(isLoading) { if (isLoading) { // Disable the button and show a spinner document.querySelector("#submit").disabled = true; document.querySelector("#spinner").classList.remove("hidden"); document.querySelector("#button-text").classList.add("hidden"); } else { document.querySelector("#submit").disabled = false; document.querySelector("#spinner").classList.add("hidden"); document.querySelector("#button-text").classList.remove("hidden"); } }
Please rewrite the contents of includes/checkout.js with this code until ver2.1.5 is available for download.
Code:const stripe = Stripe (PublishableKey); let elements; initialize(); checkStatus(); document .querySelector("#payment-form") .addEventListener("submit", handleSubmit); // Fetches a payment intent and captures the client secret async function initialize(){ const { clientSecret } = await clientS; // const { clientSecret } =await fetch("/create.php", { // method: "POST", // headers: { "Content-Type": "application/json" }, // body: JSON.stringify({ items }), // }).then((r) => r.json()); elements = stripe.elements({ clientSecret }); const paymentElementOptions = { layout: "tabs", }; const paymentElement = elements.create("payment", paymentElementOptions); paymentElement.mount("#payment-element"); } async function handleSubmit(e) { e.preventDefault(); setLoading(true); const response = await stripe.confirmPayment({ elements, confirmParams: { return_url: confirmationURL, }, redirect: 'if_required' } ) if (response.error) { showMessage(response.error.message); } else { document.getElementById('checkoutConfirmDefaultHeading').textContent = PaymentSuccess; showMessage(PaymentSuccess); document.getElementById("btn_submit").click(); } setLoading(false); } // Fetches the payment intent status after payment submission async function checkStatus() { const clientSecret = new URLSearchParams(window.location.search).get( "payment_intent_client_secret" ); if (!clientSecret) { return; } const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret); switch (paymentIntent.status) { case "succeeded": document.getElementById('checkoutConfirmDefaultHeading').textContent = PaymentSuccess; showMessage(PaymentSuccess); document.getElementById("btn_submit").click(); break; case "processing": document.getElementById('checkoutConfirmDefaultHeading').textContent='Your payment is processing.'; showMessage("Your payment is processing."); break; case "requires_payment_method": document.getElementById('checkoutConfirmDefaultHeading').textContent='Your payment was not successful, please try again.'; showMessage("Your payment was not successful, please try again."); break; default: document.getElementById('checkoutConfirmDefaultHeading').textContent='Something went wrong.'; showMessage("Something went wrong."); break; } } // ------- UI helpers ------- function showMessage(messageText) { const messageContainer = document.querySelector("#payment-message"); messageContainer.classList.remove("hidden"); messageContainer.textContent = messageText; setTimeout(function () { messageContainer.classList.add("hidden"); messageText.textContent = ""; }, 4000); } // Show a spinner on payment submission function setLoading(isLoading) { if (isLoading) { // Disable the button and show a spinner document.querySelector("#submit").disabled = true; document.querySelector("#spinner").classList.remove("hidden"); document.querySelector("#button-text").classList.add("hidden"); } else { document.querySelector("#submit").disabled = false; document.querySelector("#spinner").classList.add("hidden"); document.querySelector("#button-text").classList.remove("hidden"); } }
i found a slight quirk, if you head to the checkout confirmation page with a different payment method selected (for me it was in store credit card option via zxpos and standard checkout option) it throws an undefined stripe select warning. i slightly amended includes/modules/pages/checkout_confirmation/jscript_stripe.php to prevent the error...
basically checking stripe was chosen as the payment method and its module status is true instead of just checking it is set to true. error log was as follows....Code:<?php // Check if Stripe is active and if $stripe_select is defined and true if (defined('MODULE_PAYMENT_STRIPE_STATUS') && MODULE_PAYMENT_STRIPE_STATUS === 'True' && isset($stripe_select) && $stripe_select === 'True') { ?> <link rel="stylesheet" href="checkout_confirmation.css" /> <script src="https://js.stripe.com/v3/"></script> <script src="includes/checkout.js" defer></script> <?php } ?>
Code:[10-Nov-2024 16:01:05 UTC] Request URI: /checkout_confirmation, IP address: my ip address, Language id 1 #1 include(/includes/modules/pages/checkout_confirmation/jscript_stripe.php) called at [/includes/templates/wokiee/wt_common/tpl_wt_before_body_end.php:53] #2 require(/includes/templates/wokiee/wt_common/tpl_wt_before_body_end.php) called at [/includes/templates/wokiee/common/tpl_main_page.php:239] #3 require(/includes/templates/wokiee/common/tpl_main_page.php) called at [/index.php:96] --> PHP Warning: Undefined variable $stripe_select in /includes/modules/pages/checkout_confirmation/jscript_stripe.php on line 1.
I've run into an issue today, just received the following email....
looking on stripe it took a search for klarna in the search bar on their developers tab to get to a mini article where it states the following....Code:Why are we contacting you? We’re following up to remind you of the importance of keeping your promotional material in line with UK Financial Promotion regulations, and how Klarna’s On-site Messaging (OSM) can help. When advertising Klarna's BNPL products you MUST follow Klarna’s Rules for your advert to be compliant with the laws around advertising credit in the UK, and therefore approved by Klarna. If you are not the decision-maker or the individual responsible for implementing our OSM tool, please forward this email to the appropriate party within your organisation immediately. Why is this important? Compliance not only safeguards your business from regulatory risks but also builds customer trust. With Klarna’s OSM, you can ensure that your promotions meet UK regulations without the need for custom ads. The benefits of On-site Messaging • Guaranteed compliance: Automatically adheres to local regulations. • Time-saving: Eliminates the need for creating custom promotions. • Consistency: Provides clear Klarna payment options to customers. • Enhanced Shopping Experience: Delivers dynamic, relevant offers to your customers. Your responsibility When advertising Klarna's BNPL products, it's essential to comply with our advertising guidelines. Non-compliance may result in regulatory breaches if you're not FCA-authorised. Next steps To continue benefiting from compliant and effective promotions, please ensure you’ve implemented On-site Messaging. Klarna for Business
I also tried klarna's website first and found that they have been messing around with code and have issues with their htaccess and cors rules that is blocking the code snippets i suppossedly need from popping up, it seems to be region specific snippets, although stripe may have made a dynamic version for their api/sdk?Code:Klarna branding Let your customers know you accept payments with Klarna by including the Payment Method Messaging Element on your product and cart pages. You must comply with Klarna’s marketing compliance guides. If you’re in the UK, there are FCA regulatory requirements in the UK regarding advertising Klarna’s BNPL payment methods. Failure to comply can result in criminal charges. As per these requirements, you must only advertise Klarna with messaging approved by Klarna. You can find Klarna approved messaging in Klarna’s UK Financial Promotion Rules.
Bookmarks