stripe recurring payments php – how to manage recurring payment using Stripe Subscriptions?

stripe Subscriptions payment lets you accept payment for your member subscription service. step by step Integrate Recurring Payment using Stripe Checkout with Billing.

Integrate Recurring Payment using Stripe Checkout with Billing

stripe Subscriptions Payment Gateway Integration in PHP Example with demo & php code for online payment. stripe recurring payments php Before getting started to integrate Stripe Subscription payment API in PHP, take a look at the files structure for stripe recurring payments.

how to manage recurring payment using Stripe Subscriptions
how to manage recurring payment using Stripe Subscriptions

stripe recurring payments php
stripe-recurring-payments-php/
├── init.php
├── success.php
├── index.php
├── cancel.php
├── Service/
├── Service/StripeService.php
├── ajax-endpoint/
├── webhook-ep/
├── webhook-ep/capture-response.php

About Stripe recurring payment example

stripe recurring payments php
stripe recurring payments php

Generate Stripe Test API Keys

in stripe subscription api, first of all need the test API keys data. Step 1: Login to your Stripe account and then Go to “Developers » API” keys page. Simple here Go to API keys & get a Publishable key and Secret key.

stripe recurring payments php
stripe recurring payments php

Install Stripe PHP Library

First of all you can free Install the PHP library via Composer.

composer require stripe/stripe-php

Download Stripe PHP Library

Onther Way to Download the Stripe PHP library from Github code available: stripe recurring payments php

Step 1 : Create products and pricing plans

lib/Config.php

<?php
namespace Pakainfo;

class Config
{
    const STRIPE_PUBLISHIABLE_KEY = "set your Main Stripe publishiable key";

    const STRIPE_SECRET_KEY = "set your Main Stripe secret key";

    const SUBSCRIPTION_PLAN_ID = "Set Here Plan ID"; // plan_JD4nlShdfrYeBC

    const PRODUCT_NAME = 'Free Donload Payment Gatway Source code'; // Plane Name Like silver, Golden

    const PRODUCT_TYPE = 'service';
}
?>

step 2 : Create checkout session

first of all Create Stripe Subscription Form.
index.php

<?php
use Pakainfo\Config;

require_once __DIR__ . "/lib/Config.php";
?>
<html>
<head>
<title>Checkout - www.pakainfo.com</title>
<link href="./assets/css/style.css" type="text/css" rel="stylesheet" />
<script src="https://js.stripe.com/v3/"></script>
<script src="./assets/js/stripe.js"></script>
</head>
<body>
    <div class="product-plan-tile">
    <h2><?php echo Config::PRODUCT_NAME; ?></h2>
    <p>Best reference suitable for beginners to experts.</p>
    <div class="plan-pricing">$20 / month</div>
    <input type="button" id="subscribe" value="Subscribe Now" />
    </div>
    <div id="error-message"></div>
<script>
var stripe = Stripe('<?php echo Config::STRIPE_PUBLISHIABLE_KEY; ?>');

document.getElementById("subscribe").addEventListener("click", function(evt) {
    createCheckoutSession('<?php echo Config::SUBSCRIPTION_PLAN_ID; ?>').then(function(data) {

      stripe.redirectToCheckout({
          sessionId: data.id
      }).then(handleResult);
    });
  });
</script>
</body>
</html>

assets/js/stripe.js

var createCheckoutSession = function(planId) {
	var plan = {
		    plan_id: planId
		};

		var data = new FormData();
		data.append( "plan", JSON.stringify( plan ) );
  return fetch("ajax-endpoint/create-checkout-session.php", {
    method: "POST",
    body: data
  }).then(function(result) {
	  console.log(result);
    return result.json();
  });
};

// Handle any errors returned from Checkout
var handleResult = function(result) {
  if (result.error) {
    var displayError = document.getElementById("error-message");
    displayError.textContent = result.error.message;
  }
};

step 3: Create Checkout Session

ajax-endpoint/create-checkout-session.php

<?php
namespace Pakainfo;

use Pakainfo\StripeService;

require_once __DIR__ . '/../Service/StripeService.php';
$stripeService = new StripeService();

$plan = json_decode($_POST["plan"]);
$planId = $plan->plan_id;

$session  = $stripeService->createCheckoutSession($planId);

echo json_encode($session);
?>

Service/StripeService.php

<?php
namespace Pakainfo;

use Pakainfo\Config;
require_once __DIR__ . '/../lib/Config.php';

class StripeService
{
    function __construct()
    {
        require_once __DIR__ . "/../vendor/autoload.php";
        \Stripe\Stripe::setApiKey(Config::STRIPE_SECRET_KEY);
    }

    public function createProduct()
    {
        $product = \Stripe\Product::create([
            'name' => Config::PRODUCT_NAME,
            'type' => Config::PRODUCT_TYPE,
        ]);
        return $product;
    }

    public function createPlan()
    {
        $plan = \Stripe\Plan::create([
            'amount' => 250,
            'currency' => 'usd',
            'interval' => 'month',
            'product' => ['name' => Config::PRODUCT_NAME],
        ]);
        return $plan;
    }

    public function createCheckoutSession($planId)
    {
        $session = \Stripe\Checkout\Session::create([
            'payment_method_types' => ['card'],
            'subscription_data' => [
                'items' => [[
                    'plan' => $planId,
                ]],
            ],
            'success_url' => 'https://localhost/stripe-checkout/success.php?session_id={CHECKOUT_SESSION_ID}',
            'cancel_url' => 'https://localhost/stripe-checkout/cancel.php',
        ]);
        return $session;
    }

    public function getStripeResponse()
    {
        $body = @file_get_contents('php://input');
        $event_json = json_decode($body);
        return $event_json;
    }
}
?>

step 4 : Subscription life cycle and events

webhook-ep/capture-finalresults.php

<?php
namespace Pakainfo;

use Pakainfo\StripePayment;
use Pakainfo\StriService;

require_once __DIR__ . "/../lib/StripePayment.php";
require_once __DIR__ . "/../Service/StripeService.php";

$stripeService = new StripeService();

$finalresults = $stripeService->getStripeResponse();

$stripePayment = new StripePayment();

if(!empty($finalresults))
{
    switch($finalresults->type) {
        case "invoice.payment_succeeded":
            $userDefineDt["id"] = $finalresults->data->object->id;
            $userDefineDt["invoice_status"] = $finalresults->data->object->status;
            $stripePayment->updateInvoiceStatus($userDefineDt);
            break;

        case "invoice.payment_failed":
            $userDefineDt["id"] = $finalresults->data->object->id;
            $userDefineDt["invoice_status"] = $finalresults->data->object->status;
            $stripePayment->updateInvoiceStatus($userDefineDt);
            break;

        case "customer.created":
            $userDefineDt = array();
            $userDefineDt["customer_id"] = $finalresults->data->object->id;
            $userDefineDt["customer_email"] = $finalresults->data->object->email;
            $stripePayment->insertCustomer($userDefineDt);
            break;

        case "customer.subscription.created":
            $userDefineDt = array();
            $userDefineDt["id"] = $finalresults->data->object->id;
            $userDefineDt["customer_id"] = $finalresults->data->object->customer;
            $userDefineDt["subscription_plan"] = $finalresults->data->object->plan->id;
            $userDefineDt["subscription_interval"] = $finalresults->data->object->plan->interval_count . " " .$finalresults->data->object->plan->interval;
            $userDefineDt["subscription_status"] = $finalresults->data->object->status;
            $userDefineDt["current_period_start"] = date("Y-m-d H:i:s", $finalresults->data->object->current_period_start);
            $userDefineDt["current_period_end"] = date("Y-m-d H:i:s", $finalresults->data->object->current_period_end);
            $userDefineDt["subscription_created_date"] = date("Y-m-d H:i:s", $finalresults->data->object->created);
            $stripePayment->insertSubscription($userDefineDt);
            break;

        case "customer.subscription.updated":
            $userDefineDt = array();
            $userDefineDt["id"] = $finalresults->data->object->id;
            $userDefineDt["subscription_status"] = $finalresults->data->object->status;
            $stripePayment->updateSubscription($userDefineDt);
            break;

        case "invoice.created":
            $userDefineDt = array();
            $userDefineDt["id"] = $finalresults->data->object->id;
            $userDefineDt["subscription_id"] = $finalresults->data->object->subscription;
            $userDefineDt["invoice_number"] = $finalresults->data->object->number;
            $userDefineDt["customer_id"] = $finalresults->data->object->customer;
            $userDefineDt["billing_email"] = $finalresults->data->object->customer_email;
            $userDefineDt["currency"] = $finalresults->data->object->currency;
            $userDefineDt["invoice_status"] = $finalresults->data->object->status;
            $userDefineDt["invoice_created_date"] = date("Y-m-d H:i:s", $finalresults->data->object->created);

            $i = 0;
            foreach($finalresults->data->object->lines->data as $data)
            {
                $userDefineDt["invoice_items"][$i]["amount"] = $data->amount;
                $userDefineDt["invoice_items"][$i]["currency"] = $data->currency;
                $userDefineDt["invoice_items"][$i]["quantity"] = $data->quantity;
                $userDefineDt["invoice_items"][$i]["description"] = $data->description;
                $i++;
            }

            $stripePayment->insertInvoice($userDefineDt);
            break;

        case "invoice.finalized":
            $userDefineDt["id"] = $finalresults->data->object->id;
            $userDefineDt["invoice_finalized_date"] = date("Y-m-d H:i:s", $finalresults->data->object->finalized_at);
            $userDefineDt["invoice_status"] = $finalresults->data->object->status;
            $stripePayment->updateInvoice($userDefineDt);
            break;
    }
}
?>

stripe recurring payments php
stripe recurring payments php

lib/StripePayment.php
<?php
namespace Pakainfo;

use Pakainfo\DataSource;

class StripePayment
{
    private $ds;

    function __construct()
    {
        require_once __DIR__ . "/../lib/DataSource.php";
        $this->ds = new DataSource();
    }
    public function insertCustomer($customer)
    {
        $insertQuery = "INSERT INTO tbl_customer(customer_id, email) VALUES (?, ?) ";

        $userArgDataVal = array(
            $customer["customer_id"],
            $customer["customer_email"],
        );

        $userArgTp = "ss";
        $this->ds->insert($insertQuery, $userArgTp, $userArgDataVal);
    }

    public function insertSubscription($charge_subs)
    {
        $insertQuery = "INSERT INTO tbl_subscription(subscription_id, customer_id, subscription_plan, subscription_interval, current_period_start, current_period_end, subscription_status, subscription_created_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ";

        $userArgDataVal = array(
            $charge_subs["id"],
            $charge_subs["customer_id"],
            $charge_subs["subscription_plan"],
            $charge_subs["subscription_interval"],
            $charge_subs["current_period_start"],
            $charge_subs["current_period_end"],
            $charge_subs["subscription_status"],
            $charge_subs["subscription_created_date"],
        );

        $userArgTp = "ssssssss";
        $this->ds->insert($insertQuery, $userArgTp, $userArgDataVal);
    }

    public function insertInvoice($invoice)
    {
        $insertQuery = "INSERT INTO tbl_invoice(invoice_number, subscription_id, invoice_id, customer_id, billing_email, currency, invoice_status, invoice_created_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ";

        $userArgDataVal = array(
            $invoice["invoice_number"],
            $invoice["subscription"],
            $invoice["id"],
            $invoice["customer_id"],
            $invoice["billing_email"],
            $invoice["currency"],
            $invoice["invoice_status"],
            $invoice["invoice_created_date"],
        );

        $userArgTp = "ssssssss";
        $inserId = $this->ds->insert($insertQuery, $userArgTp, $userArgDataVal);
        if(!empty($inserId))
        {
            $this->insertInvoiceItem($invoice["invoice_items"], $inserId);
        }
    }

    public function insertInvoiceItem($invoiceItem, $invoiceMasterId)
    {
        $insertQuery = "INSERT INTO tbl_invoice_items(invoice_master_id, description, quantity, amount, currency) VALUES (?, ?, ?, ?, ?) ";

        $userArgDataVal = array(
            $invoiceMasterId,
            $invoiceItem[0]["description"],
            $invoiceItem[0]["quantity"],
            $invoiceItem[0]["amount"],
            $invoiceItem[0]["currency"],
        );

        $userArgTp = "issss";
        $this->ds->insert($insertQuery, $userArgTp, $userArgDataVal);
    }

    public function updateInvoice($invoice)
    {
        $query = "UPDATE tbl_invoice SET invoice_finalized_date = ?, invoice_status = ? WHERE invoice_id = ?";

        $userArgDataVal = array(
            $invoice["invoice_finalized_date"],
            $invoice["invoice_status"],
            $invoice["id"]
        );

        $userArgTp = "sss";
        $this->ds->execute($query, $userArgTp, $userArgDataVal);
    }

    public function updateInvoiceStatus($invoice)
    {
        $query = "UPDATE tbl_invoice SET invoice_status = ? WHERE invoice_id = ?";

        $userArgDataVal = array(
            $invoice["invoice_status"],
            $invoice["id"]
        );

        $userArgTp = "ss";
        $this->ds->execute($query, $userArgTp, $userArgDataVal);
    }

    public function updateSubscription($charge_subs)
    {
        $query = "UPDATE tbl_subscription SET subscription_status = ? WHERE subscription_id = ?";

        $userArgDataVal = array(
            $charge_subs["subscription_status"],
            $charge_subs["id"]
        );

        $userArgTp = "ss";
        $this->ds->execute($query, $userArgTp, $userArgDataVal);
    }
}
?>

Also Read : Stripe API Subscriptions With Plan Coupon And Discounts Using PHP

Read Also:  Login and Registration Form in PHP using Mysqli

step : 5 Test Card Details for stripe recurring payments php

Expiration date : 10/2022
CVC number : 989 (Any random number)

  • 4242424242424242 – Visa
  • 4000056655665556 – Visa (debit)
  • 5555555555554444 – Mastercard
  • 5200828282828210 – Mastercard (debit)
  • 378282246310005 – American Express
  • 6011111111111117 – Discover