Black Friday sale is now on! 50% off Laravel: The Modular Way. Learn more

Sell products with Stripe

David Carr

Stripe API Laravel Framework

    In this tutorial, I will cover how to use Stripe to take payment for products using their hosted checkout.

    The first step is to create a stripe account at https://dashboard.stripe.com/register

    Once registered go to the developer's link and take note of the API keys.

    Stripe has 2 different types of keys test keys and live keys. When in test mode the keys are prefixed with pk_test and sk_test. Use the test keys when testing your integration.

    Stripe API Keys

    Next, open a Laravel application.

    Install Stripe SDK using composer

    composer require stripe/stripe-php

    Add your API keys to .env

    #test keys
    STRIPE_KEY=pk_test_...
    STRIPE_SECRET=sk_test_...
    STRIPE_WEBHOOK_SECRET=
    
    #live keys
    #STRIPE_KEY=
    #STRIPE_SECRET=
    #STRIPE_WEBHOOK_SECRET=

    Open config/services.php add the following stripe array. This allows your code to refer to these keys using the format of config('services.stripe.key')

    'stripe' => [
        'key'     => env('STRIPE_KEY'),
        'secret'  => env('STRIPE_SECRET'),
        'webhook' => env('STRIPE_WEBHOOK_SECRET'),
    ],

    When you want to take a payment for a single product create a controller method to load a product based on its slug / id 

    Select the product from the database, set the Stripe API key and pass in the secret.

    Create a Session object using Session:create() 

    Inside this object specify the line items, in this example I'm using a product defined in Stripe, refer to the product ID as the price in line_items.

    Use metadata to pass any custom data that will be passed back in a webhook, this is a perfect place for a product / price or any other references you may want to use when fulfilling the order.

    To add a product to stripe go to https://dashboard.stripe.com/test/products/create

    <?php
    
    namespace Modules\Products\Http\Controllers;
    
    use Illuminate\Routing\Controller;
    use Stripe\Checkout\Session;
    use Stripe\Stripe;
    
    class PayController extends Controller
    {
        public function buy($slug)
        {
            $product = Product::where('slug', $slug)->firstOrFail();
    
            Stripe::setApiKey(config('services.stripe.secret'));
    
            $domain = config('app.url');
    
            $user = auth()->user();
    
            $checkout_session = Session::create([
                'line_items'            => [
                    [
                        'price'    => $product->price_id,
                        'quantity' => 1,
                    ]
                ],
                'mode'                  => 'payment',
                'allow_promotion_codes' => true,
                'metadata'              => [
                    'product_id' => $product->id
                ],
                'customer_email'        => $user->email,
                'success_url'           => $domain.'/success',
                'cancel_url'            => $domain.'/cancel',
                'automatic_tax'         => [
                    'enabled' => true,
                ],
            ]);
    
            return redirect()->away($checkoutSession->url);
        }
    
    }
    

    In order to go to the checkout redirect to $checkout_session->url this will take you to the hosted checkout.

    If you want to handle multiple products that are not setup on Stripe, create a dynamic array of product data, in this example I need the product name, currency, value and quantity.

    public function pay($products)
    {
        Stripe::setApiKey(config('services.stripe.secret'));
        $user         = auth()->user();
        $productItems = [];
        $total = 0;
        $domain = config('app.url');
    
        foreach ($products as $item) {  
            $item->cash_price = $item->cash_price + $discount;
            
            $productItems[] = [
                'price_data' => [
                    'product_data' => [
                        'name' => $item->name,
                    ],
                    'currency'     => 'gbp',
                    'unit_amount'  => $item->cash_price * 100,
                ],
                'quantity' => $item->quantity
            ];  
        }
    
        $checkoutSession = Session::create([
            'line_items'            => [$productItems],
            'mode'                  => 'payment',
            'allow_promotion_codes' => true,
            'metadata'              => [
                'user_id' => $user->id
            ],
            'customer_email'        => $user->email,
            'success_url'           => $domain.'/success',
            'cancel_url'            => $domain.'/cancel',
        ]);
    
        return redirect()->away($checkoutSession->url);
    }

     

    Laravel Modules Book by David Carr

    Help support the blog so that I can continue creating new content!

    Subscribe to my newsletter

    Subscribe and get my books and product announcements.

    © 2009 - 2022 DC Blog. All code MIT license. All rights reserved.