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

Gabotronix's avatar

Is there an easier alternative to Stripe SDK

Hi everybody, in my personal EU based project I want to have one time charges and posibly subscription billing in the future, I heard good things abut Stripe so I decided to use it in my projects.

But after the new EU SCA regulations becoming SCA compliant has made my sync charge workflow much harder to test. With paymentIntents confirmations now I have to take extra trips between client and server, using the same endpoint, having a method to generate different responses based on required action, it was much more easy before.

So I'm asking , is there an alternative to Stripe, SCA compliant with an easier dev workflow than Stripe, maybe Paypal does it easier?

Currently, for a one time charge my workflow looks like this, before it was much SHORTER and STRAIGHTFORWARD.

public function confirmPayment(Request $request)
    {
        //Check if customer was created and user is logged
        $customer = Auth::check() && Auth::user()->stripeId ? Customer::retrieve(Auth::user()->stripeId) : false;
        $user = Auth::user();

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

        //If request has a payment method then customer was just created and credit card introduced, 3d secure not completed yet
        if ($request->input('paymentMethodId'))
        {
            $outOfStock = Discount::outOfStockItems($request->input('cartItems'));

            if(!empty($outOfStock)){
                return response()->json([
                    'message' => 'No nos quedan suficientes existencias de '.$outOfStock[0].'. Escoge una cantidad menor.',
                ], 500);   
            }

            $amount = (int) ($request->input('cartTotal')*100);
            /*
            $receiptData = 
            [
                'userId' => $user['id'],
                'stripeCustomerId' => $customer->id,
                'paymentIntentId' => $paymentIntent->id,
                'cartItems' => $request->input('cartItems'),
                'cartTotal' => $request->input('cartTotal'),
            ];
            */

            $user->cartItems = $request->input('cartItems');
            $user->cartTotal = $request->input('cartTotal');
            $user->save();
            
            $paymentIntent = PaymentIntent::create([
                'payment_method' => $request->input('paymentMethodId'),
                'customer' => $customer->id,
                'amount' => $amount,
                'currency' => 'eur',
                'confirmation_method' => 'manual',
                'payment_method_types' => ['card'],
                'confirm' => true,
                'setup_future_usage' => 'off_session',
                'save_payment_method' => true,
            ], 
            [
                "idempotency_key" => sha1(Carbon::now()) 
            ]);

        }

        //If request has paymentIntent object then 3d secure was completed
        if ($request->input('paymentIntent'))
        {
            $paymentIntent = PaymentIntent::retrieve($request->input('paymentIntent')['id']);
            $paymentIntent->confirm();

            $this->completePayment($paymentIntent);
        }

        //After one of the two options is completed, generate the proper response to client
        return $this->generatePaymentResponse($paymentIntent);
    }


    public function generatePaymentResponse($paymentIntent)
    {

        if ($paymentIntent->status == 'requires_source_action' && $paymentIntent->next_action->type == 'use_stripe_sdk')
        {
            
            # Tell the client to handle the action, this is completing 3D Secure Auth.
            return response()->json([
                'message' => 'El pago requiere confirmación',
                'requires_action' => true,
                'payment_intent_client_secret' => $paymentIntent->client_secret,
            ], 200);  
        }
        else if ($paymentIntent->status == 'succeeded')
        {
            # The payment didn’t need any additional actions and completed succesfully!
            $this->completePayment($paymentIntent);
            
            return response()->json([
                'message' => 'Completaste el pago con exito',
            ], 200);  
        } 
        else
        {
            # Invalid status, something wrong happened
            return response()->json([
                'message' => 'Intención de pago invalida, intentalo de nuevo.',
            ], 500);  
        }
    }


    public function completePayment($paymentIntent)
    {

        $user = Auth::user();
        
        $orderData = 
        [
            'userId' => $user['id'],
            'paymentiIntent' => $paymentIntent['id'],
            'cartItems' => $user->cartItems,
            'cartTotal' => $user->cartTotal,
        ];

        $order = Item::purchaseItems($orderData);

        $item = new Item();
        $item->sendMail1($order);

        return response()->json([
            'message' => '¡Exito! Pago completado con exito',
        ], 200); 
    }
0 likes
2 replies
martinbean's avatar

@gabotronix You’re going to have to deal with SCA no matter what payment processor you use.

I’d argue Stripe’s is probably one of the most easiest to use implementations. Stripe’s engineers are some pretty intelligent people who really sweat the details in their APIs and client libraries.

Gabotronix's avatar

Yeah I know, I think it's just too much code, my vue/vuex components also lots of logic in them, I actually feel "safer" myself, handling all this in my code.

Maybe people want to post their Stripe PHP implementation in here?

Please or to participate in this conversation.