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

Gabotronix's avatar

Help with Stripe subscription and PaymentIntents API

Hi everybody, I use Stripe PHP's SDK for handling charges in Europe, I just recently got on-session charges working using PaymentIntent's API in regulation with SCA rules, now I want to have users be able to subscribe to various plans for monthly payments, reading the docs and looking in the internet for examples using PaymentIntent's API for recurring examples hasn't helped much, so my question is how can I hanfle it?

My workflow is like this:

  1. Collect a payment method with elements and create stripe customer
  2. User chooses plan
  3. Subscribe user for recurring payments

This is my controller method, how can I complete subscription using PaymentIntent:

public function addSubscription(Request $request)
    {    
        $validatedData = $request->validate(StripeValidator::$addSubscription);

        $customer = Auth::check() && Auth::user()->stripeId ? Customer::retrieve(Auth::user()->stripeId) : false;

        if(!$customer)
        {
            return response()->json([
                'message' => 'Registrate para disfrutar de nuestras mejores promociones.',
            ], 500);
        }

        $paymentMethod = PaymentMethod::retrieve($request->input('paymentMethodId'));

        $plan = Plan::create([
            "product" => 
            [
                "name" => "Product name"
            ],
            "interval" => "month",
            "interval_count" => "1",
            "currency" => "eur",
            "amount" => "3000",
        ]);

        $subscription = Subscription::create([
            "customer" => $customer->id,
            "items" => 
            [
                ["plan" => $plan->id ],
            ],
        ]);

        return response()->json([
            'subscription' => $subscription,
            'message' => 'Te suscribiste a el plan con éxito.',
        ], 200);
    }

And just in case here is how I handle one-off on-session payments:

public function createCustomerAndPaymentMethod(Request $request)
    {
        $validatedData = $request->validate(StripeValidator::$createCustomerAndPaymentMethod);
        
        $user = Auth::user();
        
        if(!$user){
            return response()->json([
                'message' => 'Debes estar registrado para realizar una compra.',
            ], 400);
        }

        $customer = Customer::create([
            'email' => $user['email'],
            "description" => 'Customer for'.config('app.name')
        ]);

        $user->stripeId = $customer->id;
        $user->save();

        $paymentMethod = PaymentMethod::retrieve($request->input('paymentMethodId'));
        $paymentMethod->attach(['customer' => $customer->id]);

        $paymentMethods = PaymentMethod::all([
            'customer' => $customer->id,
            'type' => 'card',
        ]);

        return response()->json([
            'message' => 'Añadiste una tarjeta como forma de pago.',
            'customer' => $customer,
            'paymentMethods' => $paymentMethods
        ]);
    }


    public function confirmPayment(Request $request)
    {
        $customer = Auth::check() && Auth::user()->stripeId ? Customer::retrieve(Auth::user()->stripeId) : false;

        if(!$customer)
        {
            return response()->json([
                'message' => 'Registrate para disfrutar de nustras mejores promociones.',
                'customer' => null,
            ], 500);
        }

        //dd( $request->input('paymentMethodId'));
        
        $paymentIntent = PaymentIntent::create([
            'payment_method' => $request->input('paymentMethodId'),
            'customer' => $customer->id,
            'amount' => 2000,
            'currency' => 'eur',
            'confirmation_method' => 'manual',
            'payment_method_types' => ['card'],
            'confirm' => true,
            'setup_future_usage' => 'on_session',
        ]);

        $this->generatePaymentResponse($paymentIntent);
    }

Any suggestion is welcomed, there's not much documentation about this ...

0 likes
0 replies

Please or to participate in this conversation.