Integrate Paytm Payment Gateway for Subscriptions and Recurring Billing in Laravel

Posted by

Limited Time Offer!

For Less Than the Cost of a Starbucks Coffee, Access All DevOpsSchool Videos on YouTube Unlimitedly.
Master DevOps, SRE, DevSecOps Skills!

Enroll Now
Featurepaytm/paytm-pgpaytm/paytmchecksumanandsiddharth/laravel-paytm-wallet
PurposeFull Paytm Payment Gateway API SDKOnly for checksum signing/verificationLaravel package for simple Wallet/PG payments (old)
Recurring Payment Supportโœ… YesโŒ NoโŒ No
Subscription Creation/Managementโœ… YesโŒ NoโŒ No
UPI Autopayโœ… YesโŒ NoโŒ No
Card Tokenization (required for Recurring)โœ… YesโŒ NoโŒ No
Wallet Paymentsโœ… YesโŒ Noโœ… Yes
Laravel IntegrationโŒ Raw PHP SDK, you write controller manuallyโŒ Only PHP helper libraryโœ… Pre-built Laravel support (but for old APIs only)
Maintenanceโœ… Official, regularly updatedโœ… Official, regularly updatedโŒ Unofficial, rarely updated
Dependency on Paytm Docsโœ… High, because raw API handlingโœ… Used for checksum calculation in all typesโœ… Minimal, because handled internally (but outdated logic)
Security (Signature Handling)Manual handling with checksum libNeeded for secure callsInternal checksum handling (but old method)
Good ForFull latest Subscription, UPI, Recurring, Wallet, Card paymentsOnly checksum signing/verifyingOnly simple one-time wallet payments
Bad ForIf you donโ€™t want to manage API manuallyIf you think itโ€™s a full SDK (it’s not)Recurring/Subscription, UPI autopay

๐Ÿ”ฅ Conclusion (Real World):

NeedWhat to use
Full Professional Paytm Gateway integration (Subscription, Recurring, UPI Autopay)paytm/paytm-pg + paytm/paytmchecksum
Only simple Wallet payment (no recurring, no subscription)anandsiddharth/laravel-paytm-wallet

โœ… Full Tutorial: Paytm Subscription & Recurring Payments (Laravel)


Step 1: Install Paytm Official Packages

composer require paytm/paytm-pg
composer require paytm/paytmchecksum

โœ… This will install the latest versions.


Step 2: Set Paytm Credentials in .env

PAYTM_ENVIRONMENT=PROD
PAYTM_MERCHANT_ID=YOUR_MERCHANT_ID
PAYTM_MERCHANT_KEY=YOUR_MERCHANT_KEY
PAYTM_WEBSITE=YOUR_WEBSITE_NAME
PAYTM_CALLBACK_URL=https://yourdomain.com/paytm/subscription/callback

โœ… (Get all these from your Paytm Dashboard)


Step 3: Create Subscription Request API (Laravel Controller)

Create SubscriptionController.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Paytm\pg\MerchantProperty;
use Paytm\pg\RefundApi;
use Paytm\pg\SubscriptionApi;
use Paytm\pg\TransactionApi;
use Paytm\pg\utility\Config;
use Paytm\pg\utility\PaytmHelper;
use PaytmChecksum;

class SubscriptionController extends Controller
{
    public function createSubscription(Request $request)
    {
        // Step 1: Set Paytm environment properties
        MerchantProperty::setMerchantId(env('PAYTM_MERCHANT_ID'));
        MerchantProperty::setMerchantKey(env('PAYTM_MERCHANT_KEY'));
        MerchantProperty::setMerchantWebsite(env('PAYTM_WEBSITE'));
        MerchantProperty::setIndustryTypeId('Retail');
        MerchantProperty::setChannelId('WEB');

        // Step 2: Prepare subscription body
        $body = [
            "requestType"   => "NATIVE_SUBSCRIPTION",
            "mid"           => env('PAYTM_MERCHANT_ID'),
            "websiteName"   => env('PAYTM_WEBSITE'),
            "subscriptionRequest" => [
                "subscriptionAmountType" => "FIX",
                "subscriptionAmount" => "100.00",
                "subscriptionFrequency" => "MONTHLY",
                "subscriptionFrequencyUnit" => "MONTH",
                "subscriptionStartDate" => now()->addMinutes(5)->format('Y-m-d'), // Start after 5 mins
                "subscriptionGraceDays" => 3,
                "subscriptionExpiryDate" => now()->addYear(1)->format('Y-m-d'),
                "paymentInstrument" => [
                    "paymentMode" => "CARD",
                ],
                "payerInfo" => [
                    "name" => "John Doe",
                    "email" => "john@example.com",
                    "mobile" => "7777777777",
                ],
            ]
        ];

        // Step 3: Generate Checksum
        $checksum = PaytmChecksum::generateSignature(json_encode($body), env('PAYTM_MERCHANT_KEY'));

        // Step 4: Prepare final request
        $header = [
            "signature" => $checksum
        ];

        $paytmParams = [
            "head" => $header,
            "body" => $body
        ];

        // Step 5: Send the Subscription Request
        $url = "https://securegw.paytm.in/subscription/create";

        $response = $this->callNewApi($url, $paytmParams);

        return response()->json(json_decode($response, true));
    }

    private function callNewApi($url, $params)
    {
        $data_string = json_encode($params);

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($ch, CURLOPT_HTTPHEADER, [ 
            'Content-Type: application/json',
            'Content-Length: ' . strlen($data_string)
        ]);

        $response = curl_exec($ch);

        return $response;
    }
}

Step 4: Setup Route in web.php

use App\Http\Controllers\SubscriptionController;

Route::post('/paytm/subscription', [SubscriptionController::class, 'createSubscription']);

Step 5: Handle Callback/Webhook after Subscription

Create another function:

public function subscriptionCallback(Request $request)
{
    // Paytm will POST data here
    $payload = $request->all();

    // Validate signature
    $isValidChecksum = PaytmChecksum::verifySignature(
        json_encode($payload['body']), 
        env('PAYTM_MERCHANT_KEY'), 
        $payload['head']['signature']
    );

    if ($isValidChecksum) {
        // Update your database subscription status
        return response('Callback handled successfully.', 200);
    } else {
        return response('Invalid checksum', 400);
    }
}

Your Flow Will Be:

  1. Frontend โ†’ Call /paytm/subscription โ†’ Start Subscription
  2. Paytm โ†’ Redirect/Callback โ†’ /paytm/subscription/callback
  3. Laravel backend โ†’ Capture and validate โ†’ Update Subscription table.

Tip:

Paytm also provides Webhook URLs (for subscription renewal, payment failures, etc.).
โœ… Make sure to listen to webhook events and handle renewals or failures properly in production!


โœ… Final Recommendation:

SituationWhat to Use
Professional Subscription + Recurring Payment Handlingpaytm/paytm-pg + paytm/paytmchecksum
Old Style Wallet Payment Onlyanandsiddharth/laravel-paytm-wallet

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x