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);
}

 

Fathom Analytics $10 discount on your first invoice using this link

David Carr - Laravel Developer

Hi, I’m David Carr

A Senior Developer at Vivedia
I love to use the TALL stack (Tailwind CSS, Alpine.js, Laravel, and Laravel Livewire)

I enjoy writing tutorials and working on Open Source packages.

I also write books. I'm writing a new book Laravel Testing Cookbook, This book focuses on testing coving both PestPHP and PHPUnit.

Sponsor me on GitHub

Subscribe to my newsletter

Subscribe and get my books and product announcements.

Laravel Testing Cookbook

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

Fathom Analytics $10 discount on your first invoice using this link

Subscribe to my newsletter

Subscribe and get my books and product announcements.

© 2006 - 2023 DC Blog. All code MIT license. All rights reserved.