commerce-stripe icon indicating copy to clipboard operation
commerce-stripe copied to clipboard

Adding a payment source redirects to wrong URL

Open peterurban opened this issue 1 year ago • 9 comments

When adding a payment source as part of a subscription flow. The page redirects to: /index.php/actions/commerce-stripe/customers/confirm-setup-intent and not index.php?p=actions/commerce-stripe/customers/confirm-setup-intent causing a 404.

Redirect works as expected in local development, but not production.

Form:

{% set returnUrl = 'shop/subscriptions/payment' %}

{% if chosenPlan|length > 0 %}
  {% set returnUrl = returnUrl ~ '?plan=' ~ chosenPlan %}
{% endif %}

<form id="gateway-{{ plan.gateway.id }}"
        method="post"
        action=""
        class="cards-details__form"
  >
    {{ csrfInput() }}
    {{ actionInput('commerce/payment-sources/add') }}
    {{ hiddenInput('gatewayId', plan.gateway.id) }}
    {{ hiddenInput('successMessage', 'Added payment source.'|hash) }}
    {{ hiddenInput('cancelUrl', returnUrl|hash) }}
    {{ redirectInput(returnUrl) }}

    <div class="cards-details__form__fields">
      {% namespace plan.gateway.handle|commercePaymentFormNamespace %}
        {{ plan.gateway.getPaymentFormHtml({
          paymentFormType: 'elements',
          appearance: {
            theme: 'stripe'
          },
          elementOptions: {
            layout: {
              type: 'accordion',
              defaultCollapsed: false,
              radios: false,
              spacedAccordionItems: false
            }
          },
          submitButtonClasses: 'cards-details__button button',
          submitButtonText: 'Add card',
        })|raw }}
      {% endnamespace %}
    </div>

    <label>
      {{ 'Make primary payment source' }} {{ input('checkbox', 'isPrimaryPaymentSource', 1) }}
    </label>
</form>

Steps to reproduce

  1. Add payment card using above form (3DS in my case)
  2. Submit

Additional info

  • Craft CMS version: 4.7.0
  • Stripe for Craft Commerce version: 4.1.1
  • PHP version: 8.1.27
  • Database driver & version: MariaDB 10.11.5
  • Plugins & versions
    • Admin Bar (4.1.0)
    • Craft Commerce (4.4.1.1)
    • Dumper (3.0.1)
    • Elements Panel (2.0.0)
    • Formie (2.1.2)
    • ImageOptimize (4.0.5)
    • Mailjet Adapter (1.0.4)
    • Navigation (2.0.24)
    • Neo (4.0.1)
    • QuickPay for Craft Commerce (4.1.9)
    • Redactor (3.0.4)
    • SEOmatic (4.0.38)
    • Servd Assets and Helpers (3.5.7)
    • Stripe for Craft Commerce (4.1.1)
    • Twigpack (4.0.0-beta.4)
    • Webhooks (3.0.5)

peterurban avatar Jan 28 '24 14:01 peterurban

Having the same issue here when trying to add a payment source. Any luck in resolving this?

damonadigital avatar Feb 28 '24 10:02 damonadigital

Having the same issue here when trying to add a payment source. Any luck in resolving this?

Unfortunately, the issue remains. I had to make an ugly workaround with redirects and session variables. None of the related issues are getting any attention from the team, so I wouldn't get my hopes up for a fix anytime soon.

peterurban avatar Feb 28 '24 11:02 peterurban

That is unfortunate, thank you for the update.

damonadigital avatar Mar 01 '24 12:03 damonadigital

@peterurban would you mind sharing your workaround please? Suffering from the same issue. Thanks

antcooper avatar Mar 01 '24 14:03 antcooper

@peterurban would you mind sharing your workaround please? Suffering from the same issue. Thanks

It's not pretty, but it works for my use case. Essentially, I added a redirect in my 404.twig, pointing the user to the desired url. In my case, I also need to keep track of the chosen plan, for which I use a session variable ("plan").

If this bug gets fixed at some point, the system would just send users to the correct redirectUrl and skip this step.

{% set path = craft.app.request.url %}
{% set chosenPlan = craft.app.getSession().get('plan') %}

{% if path starts with '/index.php/actions/commerce-stripe/customers/confirm-setup-intent' %}
  {% if chosenPlan %}
    {% set redirectUrl = '/shop/subscriptions/payment/received?plan=' ~ chosenPlan %}
    {% redirect redirectUrl %}
  {% else%}
    {% redirect '/shop/subscriptions/payment/received' %}
  {% endif %}
{% else %}
  {% redirect '/' %}
{% endif %}

peterurban avatar Mar 04 '24 09:03 peterurban

@peterurban thanks for the pointer. Skipping the confirm-setup-intent step and going straight to confirmation didn't set the payment method as primary for me, so it broke the rest of the subscription flow. I found a way to rewrite the malformed URL so it works and doesn't need the redirect in the session (if it's included in the original form post)

{% if craft.app.request.url starts with '/index.php/actions/commerce-stripe/customers/confirm-setup-intent' %}
  {% redirect craft.app.request.url
    |replace({'/actions/': '?p=actions/', '?setup_intent': '&setup_intent'}) %}

{% endif %}

antcooper avatar Mar 05 '24 10:03 antcooper

Thank you @antcooper - that worked for me.

smalomo avatar Mar 07 '24 18:03 smalomo

Hey @peterurban @antcooper I can’t seem to replicate this in local development in various browsers, I can't see how production would be any different unless they were configured differently.

What URL does it generate for you in local vs production?

I get this: https://craft4.ddev.site/index.php?p=actions/commerce/payments/complete-payment

lukeholder avatar Mar 08 '24 03:03 lukeholder

@lukeholder this works fine locally in DDEV. On Servd in Staging and Production, the URL is as below. I've shortened all the hashed values for readability. The ? doesn't appear until much further along the string:

  https://example.com/index.php/actions/commerce-stripe/customers/confirm-setup-intent
    &CRAFT_CSRF_TOKEN=nn93h3pKMm-LhlxG_KxrHi
    &action=commerce%2Fpayment-sources%2Fadd
    &successMessage=7c3c3607c4bd12345Payment%20Method%20Added
    &gatewayId=2
    &isPrimaryPaymentSource=1
    ?setup_intent=seti_000000
    &setup_intent_client_secret=seti_0000
    &redirect_status=succeeded

antcooper avatar Mar 08 '24 14:03 antcooper