Skip to main content

Overview

Razorpay is India’s leading payment gateway, offering:
  • Credit and debit card payments
  • Net banking
  • UPI (Unified Payments Interface)
  • Wallets (Paytm, PhonePe, etc.)
  • EMI options
  • International cards
  • INR currency support

Prerequisites

  • A Razorpay account (Sign up here)
  • KYC verification completed
  • Business bank account linked
  • GST number (for Indian businesses)

Setup Instructions

1

Create Razorpay Account

  1. Visit Razorpay Signup
  2. Enter business details
  3. Verify email and mobile number
  4. Complete KYC verification
  5. Link your business bank account
2

Get API Keys

  1. Log in to Razorpay Dashboard
  2. Go to SettingsAPI Keys
  3. Click Generate Test Keys or Generate Live Keys
Test Mode Keys:
Key ID: rzp_test_xxxxxxxxxxxxx
Key Secret: xxxxxxxxxxxxxxxxxxxxx
Live Mode Keys:
Key ID: rzp_live_xxxxxxxxxxxxx
Key Secret: xxxxxxxxxxxxxxxxxxxxx
Keep your Key Secret secure. Never expose it in client-side code or commit to version control.
3

Configure Environment Variables

Add Razorpay credentials to your .env file:For Test Mode:
RAZORPAY="YES"
RAZORPAY_KEY="rzp_test_vYLUhaqny75Hyj"
RAZORPAY_SECRET="qGdRYD6MnnPqZw0e2qoPvI52"
For Live Mode:
RAZORPAY="YES"
RAZORPAY_KEY="rzp_live_your_actual_key"
RAZORPAY_SECRET="your_actual_secret"
Always start with test keys during development.
4

Configure in Dashboard

  1. Log in to TelemanAI admin panel
  2. Navigate to SettingsPayment GatewaysRazorpay
  3. Enter your Razorpay credentials:
    • Key ID (RAZORPAY_KEY)
    • Key Secret (RAZORPAY_SECRET)
  4. Click Save Configuration

Testing the Integration

1

Use Test Cards

Razorpay provides test cards for different scenarios:Successful Payment:
Card Number: 4111 1111 1111 1111
CVV: Any 3 digits (e.g., 123)
Expiry: Any future date (e.g., 12/25)
Name: Any name
Payment Failed:
Card Number: 4000 0000 0000 0002
3D Secure Authentication:
Card Number: 5104 0600 0000 0008
OTP: 1234 (any 4 digits work in test mode)
Full test card list
2

Test UPI Payment

For UPI testing:
UPI ID: success@razorpay
(Use any UPI ID in test mode)
3

Make a Test Purchase

  1. Go to TelemanAI pricing page
  2. Select a subscription plan
  3. Click Subscribe Now
  4. Choose Razorpay payment method
  5. Select payment method (Card/UPI/Net Banking)
  6. Enter test card details
  7. Complete payment
  8. Verify subscription is activated

Payment Flow

Implementation Details

Razorpay Gateway Service

See RazorpayGateway.php for implementation:
namespace App\Services\Payment;

use Razorpay\Api\Api;

class RazorpayGateway implements PaymentGatewayInterface
{
    private function getApiInstance()
    {
        return new Api(env('RAZORPAY_KEY'), env('RAZORPAY_SECRET'));
    }
    
    public function pay(array $paymentData)
    {
        $api = $this->getApiInstance();
        
        // Create order
        $order = $api->order->create([
            'receipt'   => uniqid(),
            'amount'    => $paymentData['amount'] * 100, // Convert to paisa
            'currency'  => $paymentData['currency'] ?? 'INR',
            'payment_capture' => 1, // Auto-capture
        ]);
        
        return [
            'success'    => true,
            'order_id'   => $order['id'],
            'amount'     => $paymentData['amount'],
            'currency'   => $paymentData['currency'] ?? 'INR',
            'key_id'     => env('RAZORPAY_KEY'),
            'callback_url' => route('payment.callback', ['gateway' => 'razorpay']),
        ];
    }
}
See RazorpayGateway.php (lines 8-51)

Payment Verification

public function handleCallback()
{
    $api = $this->getApiInstance();
    
    // Get callback data
    $paymentId = request()->input('razorpay_payment_id');
    $orderId = request()->input('razorpay_order_id');
    $signature = request()->input('razorpay_signature');
    
    // Verify signature
    $generatedSignature = hash_hmac(
        'sha256',
        $orderId . "|" . $paymentId,
        env('RAZORPAY_SECRET')
    );
    
    if ($generatedSignature !== $signature) {
        return ['success' => false, 'message' => 'Signature verification failed.'];
    }
    
    // Fetch payment details
    $payment = $api->payment->fetch($paymentId);
    
    if ($payment['status'] === 'captured') {
        return [
            'success'       => true,
            'message'       => 'Payment successful.',
            'transactionId' => $paymentId,
            'amount'        => $payment['amount'] / 100,
        ];
    }
    
    return ['success' => false, 'message' => 'Payment verification failed.'];
}
See RazorpayGateway.php (lines 58-95)

Razorpay Controller

Key routes (see routes/razorpay.php):
RouteMethodDescription
/razorpay/paymentPOSTCreate Razorpay order
/razorpay/callbackPOSTPayment verification callback
/razorpay/webhookPOSTWebhook endpoint
Controller implementation: RazorpayController.php

Supported Payment Methods

Razorpay supports multiple payment methods:

Cards

  • Credit cards (Visa, Mastercard, Amex, RuPay)
  • Debit cards
  • International cards
  • EMI options

UPI

  • Google Pay
  • PhonePe
  • Paytm
  • BHIM
  • All UPI apps

Net Banking

  • All major Indian banks
  • 58+ bank options

Wallets

  • Paytm
  • PhonePe
  • Mobikwik
  • Freecharge
  • Ola Money

Buy Now Pay Later

  • LazyPay
  • PayLater
  • Simpl
Enable specific payment methods in Razorpay Dashboard under SettingsPayment Methods.

Webhook Configuration

Set up webhooks for real-time payment notifications:
1

Create Webhook

  1. In Razorpay Dashboard, go to SettingsWebhooks
  2. Click + Add New Webhook
  3. Enter webhook URL:
    https://your-domain.com/api/razorpay/webhook
    
  4. Enter a webhook secret (store this securely)
2

Select Events

Subscribe to these events:
  • payment.captured
  • payment.failed
  • order.paid
  • refund.created
  • refund.processed
3

Save Webhook Secret

Add the webhook secret to .env:
RAZORPAY_WEBHOOK_SECRET="your_webhook_secret"

Currency Support

Razorpay primarily supports INR (Indian Rupee):
# Default currency
RAZORPAY_CURRENCY="INR"
For international transactions:
  • USD, EUR, GBP supported
  • Requires international payments activation
  • Contact Razorpay support to enable

Amount Conversion

Razorpay uses paisa (1 INR = 100 paisa):
// Convert rupees to paisa
$amountInPaisa = $amountInRupees * 100;

// Example: ₹49.99 = 4999 paisa
$order = $api->order->create([
    'amount' => 4999, // ₹49.99
    'currency' => 'INR',
]);

// Convert paisa back to rupees
$amountInRupees = $payment['amount'] / 100;

Payment Modes

Test Mode

RAZORPAY_KEY="rzp_test_..."
RAZORPAY_SECRET="test_secret"
Characteristics:
  • No real money processed
  • All payment methods available
  • Test cards work
  • Separate dashboard section
  • No settlements

Live Mode

RAZORPAY_KEY="rzp_live_..."
RAZORPAY_SECRET="live_secret"
Requirements:
  • KYC completed
  • Bank account verified
  • Activation approved by Razorpay
  • HTTPS enabled
  • Proper error handling
Test and live keys are completely separate. Never mix them.

Security Features

Signature Verification

Always verify Razorpay signatures:
$signature = hash_hmac(
    'sha256',
    $orderId . '|' . $paymentId,
    env('RAZORPAY_SECRET')
);

if ($signature !== $razorpay_signature) {
    throw new Exception('Invalid signature');
}

Webhook Signature Verification

$webhookSecret = env('RAZORPAY_WEBHOOK_SECRET');
$webhookSignature = request()->header('X-Razorpay-Signature');
$webhookBody = request()->getContent();

$expectedSignature = hash_hmac('sha256', $webhookBody, $webhookSecret);

if ($webhookSignature !== $expectedSignature) {
    throw new Exception('Invalid webhook signature');
}

Error Handling

Common Razorpay errors:
Error CodeDescriptionSolution
BAD_REQUEST_ERRORInvalid parametersCheck request data
GATEWAY_ERRORPayment gateway issueRetry or contact bank
SERVER_ERRORRazorpay server errorRetry after some time
AUTHENTICATION_ERRORInvalid API keysVerify credentials
INVALID_AMOUNTAmount validation failedCheck amount format

Troubleshooting

Problem: Authentication failed errorSolution:
  • Verify Key ID and Secret are correct
  • Ensure no extra spaces in .env file
  • Check you’re using test keys in test mode
  • Confirm keys are active in Razorpay Dashboard
  • Clear config cache: php artisan config:clear
Problem: Signature mismatch errorSolution:
  • Ensure you’re using correct secret for signature
  • Verify order ID and payment ID are correct
  • Check the order of parameters in hash_hmac
  • Don’t modify orderId or paymentId
  • Use exact format: orderId|paymentId
Problem: Payment authorized but not capturedSolution:
  • Set payment_capture => 1 in order creation
  • Or manually capture the payment:
    $payment = $api->payment->fetch($paymentId);
    $payment->capture(['amount' => $amount]);
    
  • Check auto-capture is enabled in dashboard
Problem: Webhooks not hitting endpointSolution:
  • Verify webhook URL is publicly accessible
  • Ensure HTTPS is enabled
  • Check webhook secret matches
  • Test with Razorpay webhook simulator
  • Review webhook logs in Razorpay Dashboard
  • Verify firewall allows Razorpay IPs
Problem: Test payment failingSolution:
  • Use correct test card: 4111 1111 1111 1111
  • Ensure you’re in test mode (using test keys)
  • Try different test cards
  • Check CVV is any 3 digits
  • Use any future expiry date
Problem: Wrong amount chargedSolution:
  • Remember to convert to paisa (multiply by 100)
  • Check currency is INR
  • Verify amount calculation logic
  • Don’t mix rupees and paisa

Razorpay Dashboard

Key sections:
  • Transactions: View all payments
  • Orders: Track order status
  • Customers: Customer database
  • Settlements: Payout information
  • Reports: Download transaction reports
  • Disputes: Handle customer disputes
  • API Keys: Manage credentials
  • Webhooks: Monitor webhook delivery

Advanced Features

Recurring Payments

Create subscription plans:
// Create subscription plan
$plan = $api->plan->create([
    'period' => 'monthly',
    'interval' => 1,
    'item' => [
        'name' => 'Monthly Plan',
        'amount' => 99900, // ₹999
        'currency' => 'INR',
    ]
]);

// Create subscription
$subscription = $api->subscription->create([
    'plan_id' => $plan->id,
    'customer_notify' => 1,
    'total_count' => 12, // 12 months
]);
Generate payment links:
$link = $api->paymentLink->create([
    'amount' => 50000, // ₹500
    'currency' => 'INR',
    'description' => 'Subscription Payment',
    'customer' => [
        'name' => 'John Doe',
        'email' => '[email protected]',
        'contact' => '+919876543210',
    ],
]);

echo $link->short_url; // Share this link

Refunds

Process refunds:
// Full refund
$refund = $api->payment->fetch($paymentId)->refund();

// Partial refund
$refund = $api->payment->fetch($paymentId)->refund([
    'amount' => 25000, // ₹250
]);

Going Live Checklist

1

Complete KYC

  • Submit business documents
  • Verify bank account
  • Submit GST details (if applicable)
  • Wait for Razorpay approval
2

Get Live Keys

  • Generate live API keys
  • Update .env with live credentials
  • Store keys securely
3

Configure Webhooks

  • Create webhook for production URL
  • Update webhook secret
  • Test webhook delivery
4

Enable Payment Methods

  • Select payment methods in dashboard
  • Configure EMI options if needed
  • Set up international payments if required
5

Test Live Payment

  • Make a small real payment
  • Verify settlement in bank account
  • Test refund process
  • Check invoice generation

Transaction Fees

Razorpay pricing (India): Standard Pricing:
  • Domestic cards: 2% per transaction
  • UPI: 2% per transaction
  • Net Banking: 2% per transaction
  • Wallets: 2% per transaction
  • International cards: 3% + GST
Startup Friendly:
  • First ₹25 lakh: 2%
  • Beyond ₹25 lakh: Negotiable
Pricing may vary based on business volume. Contact Razorpay for custom pricing.

Next Steps

Stripe Integration

Add Stripe for international payments

PayPal Integration

Configure PayPal payment gateway

Payment Overview

View all payment gateways

Subscription Management

Manage subscriptions

Additional Resources

Build docs developers (and LLMs) love