Share this:

Today we are going to learn Building a Subscription-Based Payment System with PHP 8.x. Subscription-based payment systems have become increasingly popular in recent years, allowing businesses to offer customers a range of subscription plans with recurring payments. In this detailed blog post, we will walk you through the process of building a subscription-based payment system using PHP 8.x and the Stripe API.

By the end of this tutorial, you will have a basic understanding of how to create and manage subscriptions, handle webhooks for recurring payments, and manage customer information.

Table of Contents

  1. Prerequisites
  2. Setting Up Stripe
  3. Integrating the Stripe API with PHP
  4. Creating a Subscription Plan
  5. Creating a Customer
  6. Subscribing a Customer to a Plan
  7. Handling Webhooks for Recurring Payments
  8. Managing Customer Information
  9. Canceling a Subscription
  10. Conclusion

Prerequisites

Before we begin, ensure that you have the following:

  • A working PHP 8.x environment (refer to our previous blog post on installing PHP 8.x on CentOS)
  • A Stripe account (sign up for free at https://stripe.com)
  • Composer (a dependency manager for PHP)

Setting Up Stripe

To start, you need to obtain your Stripe API keys. Log in to your Stripe account and navigate to the “Developers” section. Click on “API Keys” to access your Publishable and Secret keys. Keep these keys secure, as they will be used to authenticate your API calls.

Integrating the Stripe API with PHP

To interact with the Stripe API, we need to install the Stripe PHP library. Use Composer to install the library by running the following command:

composer require stripe/stripe-php

Next, create a new PHP file and include the Stripe library by adding the following line at the beginning of the file:

require_once 'vendor/autoload.php';

Now, set your Stripe API key by adding the following line:

\Stripe\Stripe::setApiKey('your_stripe_secret_key');

Creating a Subscription Plan

To create a subscription plan, we will use the Stripe API to create a “Product” and a “Price.” A Product represents the subscription service, while a Price represents the specific pricing plan for the product.

First, create a Product using the following code:

$product = \Stripe\Product::create([
    'name' => 'Your Subscription Service',
    'type' => 'service',
]);

Next, create a Price for the product:

$price = \Stripe\Price::create([
    'unit_amount' => 999, // Amount in cents
    'currency' => 'usd',
    'recurring' => [
        'interval' => 'month',
    ],
    'product' => $product->id,
]);

Creating a Customer

Before a user can subscribe to a plan, they need to be created as a Customer in Stripe. To create a Customer, use the following code:

$customer = \Stripe\Customer::create([
    'name' => 'John Doe',
    'email' => 'john.doe@example.com',
    'source' => 'tok_visa', // Replace with a real token from your frontend
]);

Subscribing a Customer to a Plan

Now that we have a Customer and a subscription plan, we can subscribe the Customer to the plan. To do this, create a Subscription:

$subscription = \Stripe\Subscription::create([
    'customer' => $customer->id,
    'items' => [
        [
            'price' => $price->id,
        ],
    ],
    'expand' => ['latest_invoice.payment_intent'],
]);

if ($subscription->status === 'active') {
     echo 'Subscription created successfully';
} else {
    echo 'Failed to create subscription';
}

This code creates a Subscription for the specified Customer and Price. It also retrieves the latest invoice and payment intent information. If the subscription status is ‘active’, the subscription has been successfully created. Otherwise, an error occurred, and the subscription was not created.

Handling Webhooks for Recurring Payments

Stripe uses webhooks to notify your application of events, such as successful payments or failed charges. To handle webhooks, you need to create an endpoint on your server that listens for incoming webhook events. First, create a new PHP file called `webhook.php` and add the following code:

require_once 'vendor/autoload.php';

\Stripe\Stripe::setApiKey('your_stripe_secret_key');

$input = @file_get_contents('php://input');
$event = null;

try {
    $event = \Stripe\Event::constructFrom(json_decode($input, true));
} catch (\UnexpectedValueException $e) {
    http_response_code(400);
    exit();
}

switch ($event->type) {
    case 'invoice.payment_succeeded':
        // Handle successful payment
        break;
    case 'invoice.payment_failed':
        // Handle failed payment
        break;
    // Add other event types as needed
}

http_response_code(200);

This code listens for incoming webhook events and processes them based on their type. For example, if the event type is invoice.payment_succeeded, you can update your database to mark the subscription as paid.

Don’t forget to configure your webhook endpoint in the Stripe Dashboard under “Developers” > “Webhooks.”

Managing Customer Information

To retrieve and update customer information, use the following methods provided by the Stripe API:

  • To retrieve a Customer:
$customer = \Stripe\Customer::retrieve('customer_id');
  • To update a Customer’s email address:
$customer = \Stripe\Customer::update('customer_id', [
    'email' => 'new.email@example.com',
]);

Canceling a Subscription

To cancel a subscription, use the following code:

$subscription = \Stripe\Subscription::retrieve('subscription_id');
$subscription->cancel();

This code retrieves the Subscription object and cancels it. Note that the cancellation takes effect at the end of the current billing period.

Conclusion

In this blog post, we have provided a detailed, step-by-step guide to building a subscription-based payment system using PHP 8.x and the Stripe API. We have covered essential aspects such as creating and managing subscriptions, handling webhooks for recurring payments, and managing customer information.

With this foundation, you can now build and customize your subscription-based payment system to meet your business needs. Remember to follow best practices for security and error handling when working with sensitive data and payment processing. Good luck!

Share this:

Categorized in: