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

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs