DEV Community

David Carr
David Carr

Posted on • Originally published at dcblog.dev on

Sell products with Stripe

Sell products with Stripe

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
Enter fullscreen mode Exit fullscreen mode

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=
Enter fullscreen mode Exit fullscreen mode

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'),
],
Enter fullscreen mode Exit fullscreen mode

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

}

Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)