Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

msr2406's avatar
Level 10

No such thing as a dumb question...

Hey, I'm doing OK with Cashier 10, I've got my payment card verified by Stripe then I read...

After the card has been verified by Stripe, you may pass the resulting setupIntent.payment_method identifier to your Laravel application, where it can be attached to the customer.

Erm. I have no idea how to pass the resulting payment_method back to the Laravel application, to the addPaymentMethod() Billable trait method.

Feels like i'm missing a 101 somewhere.

tl;dr how do I get json data from javascript back to laravel?

0 likes
6 replies
softdot's avatar

Did you figure out how to pass the setupIntent.payment_method identifier to Laravel?

As I am stuck at the same point! :(

Romax's avatar

Hello guys.

                <form action="{{ your-route-to-form }}" method="post" id="payment-form">
                    @csrf
                    <div class="form form-cb">
                        <label for="card-element">
                            Carte de crédit
                        </label>
                        <div id="card-element">
                        <!-- A Stripe Element will be inserted here. -->
                        </div>
                    
                        <!-- Used to display form errors. -->
                        <div id="card-errors" role="alert"></div>
                    </div>
                    <div class="button-cbpayment">
                        <button id="card-button" data-secret="{{ $intent->client_secret }}">S'abonner</button>
                    </div>
                </form>

This is my form, where you are blocked.

After that is the js script

    var stripe = Stripe('{{ config('services.stripe.key') }}');

    // Create an instance of Elements.
    var elements = stripe.elements();

    // Custom styling can be passed to options when creating an Element.
    // (Note that this demo uses a wider set of styles than the guide below.)
    var style = {
    base: {
        color: '#32325d',
        fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
        fontSmoothing: 'antialiased',
        fontSize: '16px',
        '::placeholder': {
        color: '#aab7c4'
        }
    },
    invalid: {
        color: '#fa755a',
        iconColor: '#fa755a'
    }
    };

    // Create an instance of the card Element.
    var card = elements.create('card', {hidePostalCode: true, style: style});

    // Add an instance of the card Element into the `card-element` <div>.
    card.mount('#card-element');

    // Handle real-time validation errors from the card Element.
    const cardHolderName = document.getElementById('card-holder-name');
    const cardButton = document.getElementById('card-button');
    const clientSecret = cardButton.dataset.secret;

    cardButton.addEventListener('click', async (e) => {
        const { setupIntent, error } = await stripe.handleCardSetup(
            clientSecret, cardElement, {
                payment_method_data: {
                    billing_details: { name: cardHolderName.value }
                }
            }
        );

        if (error) {
            displayError.textContent = event.error.message;
        } else {
            displayError.textContent = '';
        }
    });

    // Handle form submission.
    var form = document.getElementById('payment-form');

    form.addEventListener('submit', function(event) {
        event.preventDefault();

        stripe.handleCardSetup(clientSecret, card).then(function(result) {
            if (result.error) {
                var errorElement = document.getElementById('card-errors');
                errorElement.textContent = result.error.message;
            } else {
                stripePaymentHandler(result.setupIntent);
            }
        });
    });

    

    // Submit the form with the token ID.
    function stripePaymentHandler(setupIntent) {
    // Insert the token ID into the form so it gets submitted to the server
    var form = document.getElementById('payment-form');
    var hiddenInput = document.createElement('input');
    hiddenInput.setAttribute('type', 'hidden');
    hiddenInput.setAttribute('name', 'stripePaymentMethod');
    hiddenInput.setAttribute('value', setupIntent.payment_method);
    form.appendChild(hiddenInput);

    // Submit the form
    form.submit();
    }

Here we simply create in the form a hidden input with our result. Of course before that we have to verify the payment method.

And the in controller you simply do

$paymentMethod = $request->get('stripePaymentMethod'); $plan = 'Your plan in a cae of subcription'; $user->newSubscription('main', $plan)->create($paymentMethod)

And that's all ;)

Hope it will help ;)

1 like
msr2406's avatar
Level 10

Many thanks for this. Very helpful. I'm getting:

Uncaught IntegrationError: You have an in-flight handleCardSetup! Please be sure to disable your form submit button when handleCardSetup is called.

in my Chrome inspect and I can't work out why.

hardiksadhu008's avatar
Level 1
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="csrf-token" content="{{ csrf_token() }}">

</head>
<body>
        <script src="https://js.stripe.com/v3/"></script>
        <form method="post" action="{{route('subscription')}}" id="payment-form">
        @csrf
        <div class="form form-cb">           
                        
                        <input type="text" id="card-holder-name">           
                        <div id="card-element" style="width: 400px;">
                        <!-- A Stripe Element will be inserted here. -->           
                        </div>
                    
                        <!-- Used to display form errors. -->
                        <div id="card-errors" role="alert"></div>
                        <button id="card-button" data-secret="{{ $intent->client_secret }}" />Pay
                        </button>   
        </div>
        </form>

<script>
   
    var stripe = Stripe('Your Stripe-key');
    var elements = stripe.elements();
    var cardElement = elements.create('card');

    cardElement.mount('#card-element');

    // Add an instance of the card UI component into the `card-element` <div>
    var cardHolderName = document.getElementById('card-holder-name');
    var cardButton = document.getElementById('card-button');
    var clientSecret = cardButton.dataset.secret;

     cardButton.addEventListener('click', async (e) => {
        var { setupIntent, error } = await stripe.handleCardSetup(
            clientSecret, cardElement, {
                payment_method_data: {
                    billing_details: { name: cardHolderName.value }
                }
            }
        );

        if (error) {
            console.log('error');
        } else {
            stripePaymentHandler(setupIntent);
        }
    });

    // Handle form submission.
    var form = document.getElementById('payment-form');
    form.addEventListener('submit', function(event) {
        event.preventDefault();
    });

    // Submit the form with the token ID.
    function stripePaymentHandler(setupIntent) {
    // Insert the token ID into the form so it gets submitted to the server
    var form = document.getElementById('payment-form');
    var hiddenInput = document.createElement('input');
    hiddenInput.setAttribute('type', 'hidden');
    hiddenInput.setAttribute('name', 'stripePaymentMethod');
    hiddenInput.setAttribute('value', setupIntent.payment_method);
    form.appendChild(hiddenInput);

    // Submit the form
    form.submit();
    } 

</script>


</body>
</html>
1 like

Please or to participate in this conversation.