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.
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 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 set up 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);
}