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

 

Read articles directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Copyright © 2006 - 2024 DC Blog - All rights reserved.