Jay GajjarSenior Software Engineer

Razorpay vs Stripe in 2026: which payment gateway for Indian businesses and for selling to India

Razorpay vs Stripe in 2026: Stripe's invite-only status in India, international payments, UPI, fees, payouts and webhook verification in Laravel and PHP.

By Jay Gajjar10 min read

Razorpay vs Stripe in 2026 is mostly decided by two facts: where your business is registered and where your customers pay from. If you are an Indian business, Razorpay is the practical default, because Stripe has been invite-only for new Indian accounts since 2024 and still is. If you are a business outside India selling to Indian customers or worldwide, Stripe is usually the better fit, and it now supports UPI for Indian customers from many countries. This guide compares the two on availability, international payments, UPI and subscriptions, fees, payouts and the integration work in Laravel and PHP, using only what the official Razorpay and Stripe pages say as of October 2026.

Quick answer: Razorpay vs Stripe by situation

Your situation Sensible default Why
Indian business, customers mostly in India Razorpay Open sign-up, UPI, netbanking, wallets and cards, INR settlement
Indian business selling services or software abroad Razorpay international payments Stripe India needs an invite; Razorpay offers cards, PayPal and bank transfers from abroad
Indian business that already has an active Stripe account Stripe for international, often Razorpay for INR Existing Stripe India accounts are still supported
Business in the US, UK, EU, Singapore and similar, selling to Indian customers Stripe with UPI enabled Stripe accounts in those countries can accept UPI in INR
Business outside India, global customers, India a small share Stripe Wider country coverage and one integration
Individual freelancer in India paid by foreign clients Razorpay with PayPal Razorpay requires PayPal for individuals; Stripe India exports are for registered businesses only

The rest of the article explains each row, then shows the integration code.

Is Stripe available in India in 2026?

Only by invite. Stripe's support page says businesses from India "are not able to sign up for a new Stripe account through our website" and must request an invite through sales, and that Stripe supports "a select number of businesses, with a focus on international expansion". Currently active Indian accounts continue to be supported, and platforms can only add new connected accounts in India by invite. Stripe says it will reach out when it opens access more broadly. You can read the current wording on Stripe's India invite-only page (opens in a new tab).

If you do have or get a Stripe India account and want to sell abroad, the Stripe India exports guide (opens in a new tab) adds conditions:

  • The account must be a registered Indian business (sole proprietorship, LLP or company), not an individual.
  • Physical goods need an Importer Exporter Code (IEC). For services it is optional, unless you accept international American Express or claim Foreign Trade Policy benefits.
  • You choose one RBI transaction purpose code for the account, such as P0802 for software consultancy.
  • Every international payment must carry the customer's name, billing address and a description of what you are exporting, or the payment can fail.
  • Payouts arrive in INR, with export payouts listed separately, and Stripe's banking partner emails a payment advice for export payouts.

So for most new Indian businesses, "Stripe vs Razorpay" is not a real choice yet. The question becomes how far Razorpay's international features take you.

Razorpay international payments: what you get

Razorpay lets Indian businesses accept payments from customers abroad, but you have to activate it. New users choose Outside India (International) during onboarding. Existing users go to Account & Settings > International payments in the Dashboard and activate each method. According to Razorpay's international payments docs (opens in a new tab):

  • You can charge in more than 160 foreign currencies through the payment gateway, Payment Pages, Payment Links, Payment Buttons and Invoices.
  • Registered businesses with a valid website can accept foreign and domestic cards, PayPal, International Bank Transfer and some local methods (Giropay, Sofort, Trustly, POLi).
  • International Bank Transfer, branded the MoneySaver Export Account, lets foreign buyers pay by local bank transfer or SWIFT, with final settlement in INR to your Indian bank account.
  • Individuals, such as freelancers, must integrate PayPal to accept international payments.
  • International payments fail if you pass a dummy customer email or phone number, a detail that catches out many integrations that use placeholder values.

Razorpay also works the other way round. A non-Indian business can ask Razorpay to enable collecting from Indian customers by cards, UPI and netbanking, with settlement to an overseas bank account. It is an on-demand feature you request with a form, so check eligibility for your country before you plan around it.

UPI, Indian cards and subscriptions

Indian customers expect UPI. This is where the two products differ the most.

Razorpay supports UPI, cards, netbanking and wallets out of the box for Indian businesses. Its Subscriptions product charges cards, UPI AutoPay and e-mandates authorized with Aadhaar, netbanking or a debit card.

Stripe supports UPI in INR, for one-time and recurring payments, but the UPI docs (opens in a new tab) list the business locations that can accept it: the US, UK, Canada, Australia, Singapore, Switzerland, Norway, Liechtenstein and the EU countries. India is not on that list. UPI payments must be between 1 and 100,000 INR, and recurring UPI is capped at 15,000 INR. For a foreign SaaS company with Indian customers, this closes the biggest gap Stripe used to have.

Recurring payments on Indian cards follow RBI e-mandate rules, whichever gateway you use. Stripe's India recurring payments guide (opens in a new tab) states that these rules apply to Indian and non-Indian Stripe users alike whenever the customer pays with an Indian card or UPI off-session. The customer registers a mandate with extra authentication, gets a pre-debit notification at least 24 hours before each charge, and must authenticate again for recurring charges above 15,000 INR. Stripe delays these card charges by about 26 hours to allow for the notice. Build your billing emails, dunning and "subscription active until" logic around that delay, or customers will see confusing status changes.

Fees: what the official pricing pages say

Fees change, and both companies negotiate for larger volumes, so treat these as a snapshot from October 2026 and check the live pages before you decide.

Razorpay (standard plan) Stripe India (standard)
Domestic payments 2% platform fee on standard domestic methods, plus 18% GST on the fee 2% for Indian-issued Visa and Mastercard
UPI Zero MDR by RBI policy; Razorpay's 2% is described as a platform fee Not offered to India-based accounts
International cards See the international section of the pricing page 3% Visa and Mastercard, 3.5% Amex, 4.3% with USD or other currency presentment
Currency conversion Check the pricing page for your plan Additional 2% if conversion is required
Setup or annual fee None listed None listed

Sources: Razorpay pricing (opens in a new tab) and Stripe India pricing (opens in a new tab). Razorpay's page also lists separate rates for some methods (credit card on UPI shows 2.15%) and runs promotions for new businesses, so read the conditions.

In a Razorpay vs Stripe comparison, the fee line rarely decides things alone. Compare the effective cost on your real payment mix (how much UPI, domestic cards, international cards), plus the FX conversion, plus GST on fees, plus the cost of failed payments. A gateway that is 0.5% cheaper but fails a chunk of UPI payments costs you more.

Payouts and settlement timing

  • Razorpay: the standard domestic settlement cycle is T+2 working days from capture. Bank holidays do not count, and a settlement that falls on a holiday moves to the next working day. International settlements follow "applicable law(s)", and your Dashboard shows your actual cycle. Instant Settlements is an on-demand feature you request from support. Details are in the Razorpay settlements docs (opens in a new tab).
  • Stripe India: payouts are always automatic and daily in INR, with settlement of 2 business days for domestic charges and 5 business days for international charges, per Stripe's payouts documentation.

For a business that pays suppliers weekly, either cycle works. For thin cash flow, ask about instant or faster settlement before you launch, not after.

Integration effort in Laravel and PHP

Both gateways have maintained PHP SDKs: razorpay/razorpay (2.9.3 as of October 2026) and stripe/stripe-php (22.x). The bigger difference is the tooling around them.

Stripe has Laravel Cashier (laravel/cashier, currently supporting Laravel 10 to 13), which handles customers, subscriptions, invoices, trials and webhooks for you. For one-time payments, Stripe Checkout gives you a hosted payment page and you mostly handle webhooks. If your product is subscription software, Cashier saves real time, which is a fair point in Stripe's favor when you can get an account.

Razorpay has no first-party Laravel billing package, so a Laravel Razorpay integration means writing the flow yourself. It is not hard, but every step matters:

  1. Create an order on the server, with the amount in the smallest currency unit (paise for INR).
  2. Open Razorpay Checkout in the browser with that order ID.
  3. Receive razorpay_payment_id, razorpay_order_id and razorpay_signature from the Checkout handler and verify the signature on the server.
  4. Treat the webhook as the final word, and mark the order paid only once.

Creating the order and verifying the payment in a Laravel controller:

use Razorpay\Api\Api;
use Razorpay\Api\Errors\SignatureVerificationError;

// 1. Create the Razorpay order when the customer clicks Pay
$api = new Api(config('services.razorpay.key'), config('services.razorpay.secret'));

$rzpOrder = $api->order->create([
    'receipt'  => 'order_' . $order->id,
    'amount'   => $order->total_paise,   // integer, e.g. 49900 for Rs 499.00
    'currency' => 'INR',
    'notes'    => ['order_id' => (string) $order->id],
]);

$order->update(['razorpay_order_id' => $rzpOrder['id']]);

// 3. Verify what the browser posts back after payment
try {
    $api->utility->verifyPaymentSignature([
        'razorpay_order_id'   => $order->razorpay_order_id,   // from your database, not the request
        'razorpay_payment_id' => $request->input('razorpay_payment_id'),
        'razorpay_signature'  => $request->input('razorpay_signature'),
    ]);
} catch (SignatureVerificationError $e) {
    abort(400, 'Payment could not be verified.');
}

Note that the order ID comes from your database, not the request. That ties the signature to the order you created, so a valid payment for a cheaper order cannot be replayed against an expensive one. Razorpay's PHP integration guide (opens in a new tab) covers the Checkout options.

Webhooks and signature verification

The browser callback can fail: the customer closes the tab, the network drops, the redirect never happens. Webhooks are how both gateways tell your server what really happened, and an unverified webhook endpoint is an open door for anyone to mark orders as paid. Signed, idempotent webhook handlers are a routine part of my API development and integration work, and the pattern is the same for both gateways.

A Razorpay webhook handler in Laravel, verifying the X-Razorpay-Signature header with HMAC SHA256 over the raw body:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

public function razorpay(Request $request)
{
    $payload   = $request->getContent(); // raw body, never re-encoded JSON
    $signature = (string) $request->header('X-Razorpay-Signature');
    $expected  = hash_hmac('sha256', $payload, config('services.razorpay.webhook_secret'));

    if (! hash_equals($expected, $signature)) {
        abort(400);
    }

    $isNew = DB::table('webhook_events')->insertOrIgnore([
        'provider'   => 'razorpay',
        'event_id'   => (string) $request->header('x-razorpay-event-id'),
        'payload'    => $payload,
        'created_at' => now(),
    ]);

    if ($isNew) {
        ProcessRazorpayEvent::dispatch(json_decode($payload, true));
    }

    return response()->noContent();
}

The webhook_events table has a unique index on provider and event_id, so insertOrIgnore() returns 0 for a duplicate delivery. Razorpay's webhook validation docs (opens in a new tab) say the same event can arrive more than once and that x-razorpay-event-id is unique per event. The SDK's $api->utility->verifyWebhookSignature($payload, $signature, $secret) does the same check if you prefer it.

A Laravel Stripe webhook handler uses the SDK, which checks the Stripe-Signature header and rejects events older than five minutes by default:

use Stripe\Exception\SignatureVerificationException;
use Stripe\Exception\UnexpectedValueException;
use Stripe\Webhook;

try {
    $event = Webhook::constructEvent(
        $request->getContent(),
        (string) $request->header('Stripe-Signature'),
        config('services.stripe.webhook_secret'),
    );
} catch (UnexpectedValueException | SignatureVerificationException $e) {
    abort(400);
}

// Store $event->id with a unique index, then queue the work, exactly as above.

If you use Cashier, it registers /stripe/webhook, verifies signatures with STRIPE_WEBHOOK_SECRET, and php artisan cashier:webhook creates the endpoint in Stripe for you.

Webhook routes must skip CSRF protection, because the gateway cannot send a token. In Laravel 13 the middleware was renamed, so the bootstrap/app.php call is:

->withMiddleware(function (Middleware $middleware) {
    $middleware->preventRequestForgery(except: [
        'webhooks/*',
        'stripe/*',
    ]);
})

On Laravel 11 and 12 the same call is validateCsrfTokens(except: [...]). The rules that apply to both gateways:

  • Verify the signature against the raw body before you parse anything.
  • Compare signatures with hash_equals(), never ==.
  • Store event IDs with a unique index and process each event once.
  • Return a 2xx quickly and do the work in a queued job. Slow handlers cause timeouts, retries and duplicates.
  • Mark orders paid from the webhook, not from the browser redirect.
  • Keep amounts as integers in the smallest unit end to end. Floats and rupees-versus-paise mix-ups cause real refunds.
  • Reconcile daily: compare paid orders in your database with captured payments in the gateway dashboard or API.

Queue workers have to keep running on the server for this to work, which is the part shared hosting often gets wrong. My guide to deploying Laravel on cPanel or a VPS covers workers and cron.

Using both: Razorpay for India, Stripe for the rest

Many businesses that have access to both run Razorpay for INR and Stripe for international customers, choosing the gateway by billing country at checkout. It works well, but budget for it properly:

  • Put both behind one PaymentGateway interface with a driver per gateway, and store gateway, gateway_order_id and gateway_payment_id on every payment.
  • Write a webhook handler and tests per gateway. Refunds, partial refunds and disputes behave differently.
  • Report in one currency, with the FX rate and fees stored per payment, or monthly numbers will never match.
  • Expect roughly double the testing, and plan for each gateway's account review before launch.

The same thinking applies inside existing systems. A Perfex CRM install, for example, can get a custom gateway through a module, as covered in my Perfex CRM module development guide.

Frequently asked questions

Is Stripe available in India in 2026?

Only by invite for new accounts. Indian businesses cannot sign up on Stripe's website and must request an invite through sales, while existing active Indian accounts continue to be supported. Stripe has not announced a date for opening sign-ups again.

Can Razorpay accept international payments?

Yes, once you activate international payments. Registered Indian businesses can accept foreign cards, PayPal, international bank transfers (local transfer or SWIFT) and some local European and Australian methods, in more than 160 currencies, with settlement in INR. Individuals must use PayPal.

Which is better for a SaaS selling subscriptions to Indian customers?

If you are an Indian business, Razorpay Subscriptions, because Stripe needs an invite. If you are a foreign business, Stripe with Cashier and UPI enabled is usually the cleaner build. Either way, plan for RBI e-mandate rules: mandate registration, pre-debit notices and re-authentication above 15,000 INR.

Can a freelancer in India use Stripe or Razorpay to get paid by foreign clients?

Through Razorpay, yes, but Razorpay requires individuals to use PayPal for international payments. Stripe India's export support is limited to registered businesses (sole proprietorships, LLPs and companies), and new accounts need an invite.

Do I still need webhooks if I verify the payment signature in the callback?

Yes. The callback depends on the customer's browser finishing the redirect, which does not always happen. The webhook is the reliable record of captured payments, refunds and disputes, so verify its signature and make it the source of truth for order status.

If you want either gateway, or both, wired into a Laravel, CodeIgniter or core PHP app with verified webhooks and reconciliation, my payment gateway integration service covers it end to end.