Support more payment method types

Created on 13 December 2023, about 1 year ago
Updated 6 January 2024, 12 months ago

Hello,

I am currently testing the new Payment Element integration you guys added to Commerce Stripe. Thanks for that by the way.

I would like to enable Paypal but also make it so that customers can quickly reuse their Paypal payment method and that we can also renew customers subscription (off session) using Paypal…
Which means that I want this Paypal payment method to be stored and also to be reusable later on.

It seems to me the code is not ready yet for that. I wanted to have your confirmation that I am correct about it.
What makes me say that is the followings:

1/ I've noticed the payment confirmation happens in JS inside commerce_stripe.payment_element.js
Either we want to add a new payment method, in that case we load the Payment Element JS form using stripe.confirmPayment()
or we've already selected a payment method, in that case settings.showPaymentForm is FALSE and we use stripe.confirmCardPayment() instead. If I am correct, this method only allows to go through with a credit card payment and will not work with a stored payment method of type Paypal, right? I have not been able to test this yet though because I cannot yet save a Paypal payment method. Which is problem 2 :

2/ In StripePaymentElement->onReturn() which is where we're supposed to store the payment method after the successful payment, I notice line 409 the payment_method_type is forced to 'credit_card'. I have been able to test this and with Paypal selected as the payment method, the payment successfully passes on Stripe's end, but this line 408 throws an error 'Invalid parameters were supplied to Stripe's API.' which makes sense… and finally PaymentCheckoutController->returnPage() catches the exception and displays the generic error message "Payment failed at the payment server. Please review your information and try again." and redirects to the Payment Information pane..

I just want to know if I am correct.
If I am, I will probably create another issue of type feature request this time, where I can eventually contribute code to help make it happen.

Thank you :)

💬 Support request
Status

Closed: duplicate

Version

1.1

Component

Payment Element

Created by

🇫🇷France nicolas bouteille

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @nicolas bouteille
  • Assigned to TomTech
  • 🇺🇸United States TomTech

    Correct, only credit card is supported at this time. We do have some other stripe payment methods in the pipeline.

    We won't be implementing them all. (At least not in the near term.) But will do so in a way that it would be fairly easy to extend.

  • 🇫🇷France nicolas bouteille

    Thanks for the quick feedback Tom!

    I just wanted to let you know I asked guys from Stripe if, in order to let my customers reuse a previously stored payment method, I needed to implement every stripe.confirmXXXXPayment possibilities from https://stripe.com/docs/js/payment_intents/payment_method
    Indeed, since you guys used stripe.confirmCardPayment for credit cards, I thought I was going to need to implement stripe.confirmPayPalPayment for Paypal, stripe.confirmSepaDebitPayment for SEPA Debit, etc.

    Here is their answer:
    "If you want to charge a saved PaymentMethod later on then you don't need to implement anything client-side except your own UI to indicate which PaymentMethod should be charged
    Then you just create/confirm a PaymentIntent server-side to charge that PaymentMethod
    https://stripe.com/docs/payments/save-and-reuse?platform=web&ui=elements... is an example of what this would look like"

    After reading that piece of documentation, I understand there's still the case where an authentication such as 3DS is required that requires us to use some JS script. However, in this case it seems we can use the generic JS function stripe.confirmPayment using the ClientSecret of the PaymentIntent that requires authentication, no matter what kind of payment method is concerned.
    So if I understand correctly, by using server side code first and only use stripe.confirmPayment if necessary, instead of going directly with client-side code such as stripe.confirmCardPayment or stripe.confirmPayPalPayment, it should be easier for us to have generic code that works for all payment method types.

    I'm not sure about that however. This is only my early - not tested - understanding. But I thought it might be worth sharing it now if I'm right about it, before you guys decide how you're gonna implement this…

  • 🇫🇷France nicolas bouteille

    Hi,
    I got some update:

    On my previous comments, I mentioned that the person from Stripe told me I did not need to do anything client-side, that I could confirm payments server-side only... and require client-side JS action of the customer only if 3DS is required. This is because they thought I wanted to charge the person in off-session mode. But we also need to deal with the client reusing its payment method in on-session mode.

    My readings made me believe that stripe.confirmPayment() could be used to confirm any kind of payment client-side, thus removing the need to implement every individual case with stripe.confirmCardPayment for credit cards, stripe.confirmPayPalPayment for Paypal, stripe.confirmSepaDebitPayment for SEPA Debit, etc.

    My tests confirm this.

    I've just been able to finalize / confirm a payment with a previously stored payment method of type Paypal by simply replacing in commerce_stripe.payment_element.js

    stripe.confirmCardPayment(
      settings.clientSecret,
      {
        payment_method: settings.paymentMethod
      }
    ).then(function (result) {
    

    with

    stripe.confirmPayment({
      clientSecret: settings.clientSecret,
      confirmParams: {
        return_url: settings.returnUrl,
        // payment_method: settings.paymentMethod // not even needed since it's already been added to the PaymentIntent
      }
    }).then(function (result) {
    

    using the same piece of code, I was able to confirm a payment with a stored credit card as well.

    So I can confirm that stripe.confirmPayment() seems indeed generic and allows to confirm all types of payment methods with no need to confirm the payment server-side.

    Only difference is, like when using PaymentElement form when adding new payment methods, the Promise never resolves and Stripe redirects us to the return_url. NB: this can be overridden with the 'redirect' parameter when possible if necessary...

    So we have to adapt StripePaymentElement->onReturn to not try to save a payment method twice.

    BTW as you may have guessed, I have been able to update StripePaymentElement->onReturn so that it can save payment methods other than credit cards. This does not require too much effort. I will probably create another issue to share my code when I'm done.

  • Status changed to Closed: duplicate 12 months ago
  • 🇺🇸United States TomTech

    Hi @Nicolas, Thanks for the request.

    We've actually already been working on refactoring in order to handler more than just credit card.

    Please take a look at the latest dev, and specifically the MR from this issue: 📌 Refactor Stripe payment element for additional payment method types Fixed , which implements the refactoring.

    It seems to align with observations you make here.

    Some other payment methods are in the pipeline, but MRs for ones not implemented are welcome!

Production build 0.71.5 2024