Skip to content
  • No data uploaded
  • Instant results

Bootstrap 5 Razorpay Checkout Form for React

A production-ready minimal razorpay checkout form: a two-column checkout with an order summary (subtotal, GST, total in INR), contact fields, a UPI / card / netbanking selector and a pay button that opens Razorpay Checkout. Pick your brand color, toggle dark mode and corner radius — the live preview and the React code update instantly in your browser.

Live component editor

Library
Framework
Style
Theme
Corner radius
Live preview
import 'bootstrap/dist/css/bootstrap.min.css';
import './theme.css';
import { useState } from 'react';

// Razorpay Standard Checkout — https://razorpay.com/docs/payments/payment-gateway/web-integration/standard/
const RAZORPAY_KEY_ID = 'rzp_test_YOUR_KEY_ID'; // public key only — the secret stays on your server

function loadRazorpay() {
  if (window.Razorpay) return Promise.resolve();
  return new Promise((resolve, reject) => {
    const s = document.createElement('script');
    s.src = 'https://checkout.razorpay.com/v1/checkout.js';
    s.onload = resolve;
    s.onerror = () => reject(new Error('Razorpay SDK failed to load'));
    document.head.appendChild(s);
  });
}

async function payWithRazorpay() {
  await loadRazorpay();
  // 1) Server creates the order (amount in paise) — never trust a client-side amount.
  const order = await fetch('/api/razorpay/order', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ plan: 'pro-annual' })
  }).then((r) => r.json());
  // 2) Open Checkout for that order.
  const rzp = new window.Razorpay({
    key: RAZORPAY_KEY_ID,
    order_id: order.id,
    amount: order.amount,
    currency: order.currency,
    name: 'Acme Inc.',
    description: 'Pro plan — annual',
    prefill: {
      email: document.getElementById('rp-email')?.value,
      contact: document.getElementById('rp-phone')?.value
    },
    theme: { color: '#4f46e5' },
    // 3) Server verifies razorpay_signature before fulfilling.
    handler: (res) =>
      fetch('/api/razorpay/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(res) })
  });
  rzp.on('payment.failed', (res) => console.error(res.error));
  rzp.open();
}

export default function RazorpayCheckout() {
  const [method, setMethod] = useState("upi");

  return (
    <div className="w-100 mw-4xl row row-cols-1 row-cols-md-2 g-4">
      <div className="col">
        <div className="h-100 p-4 bg-body border shadow-sm rounded-3">
          <h2 className="fs-5 fw-semibold text-body-emphasis">Order summary</h2>
          <div className="mt-3 d-flex align-items-start justify-content-between gap-3">
            <div>
              <p className="fw-medium text-body-emphasis">Pro plan · annual</p>
              <p className="small text-body-secondary">Billed once, renews yearly</p>
            </div>
            <p className="fw-medium text-body-emphasis">₹8,474</p>
          </div>
          <div className="mt-4 pt-3 d-flex flex-column gap-2 small border-top">
            <div className="d-flex justify-content-between text-body-secondary"><span>Subtotal</span><span>₹8,474</span></div>
            <div className="d-flex justify-content-between text-body-secondary"><span>GST (18%)</span><span>₹1,525</span></div>
            <div className="d-flex justify-content-between fw-semibold text-body-emphasis"><span>Total</span><span>₹9,999</span></div>
          </div>
          <p className="mt-4 small text-body-secondary">Secured by Razorpay · PCI DSS compliant</p>
        </div>
      </div>
      <div className="col">
        <form className="h-100 p-4 d-flex flex-column gap-3 bg-body border shadow-sm rounded-3">
          <h2 className="fs-5 fw-semibold text-body-emphasis">Payment details</h2>
          <div>
            <label htmlFor="rp-email" className="form-label small fw-medium">Email</label>
            <input id="rp-email" type="email" autoComplete="email" placeholder="you@company.com" className="form-control rounded-2" required />
          </div>
          <div>
            <label htmlFor="rp-phone" className="form-label small fw-medium">Mobile number</label>
            <input id="rp-phone" type="tel" inputmode="tel" autoComplete="tel" placeholder="+91 98765 43210" className="form-control rounded-2" required />
          </div>
          <div>
            <p className="form-label small fw-medium">Payment method</p>
            <div className="d-flex flex-wrap gap-2" role="group" aria-label="Payment method">
              <button type="button" className="btn btn-outline-secondary choice fw-semibold rounded-2" onClick={() => setMethod('upi')} aria-pressed={method === 'upi'}>UPI</button>
              <button type="button" className="btn btn-outline-secondary choice fw-semibold rounded-2" onClick={() => setMethod('card')} aria-pressed={method === 'card'}>Card</button>
              <button type="button" className="btn btn-outline-secondary choice fw-semibold rounded-2" onClick={() => setMethod('netbanking')} aria-pressed={method === 'netbanking'}>Netbanking</button>
            </div>
            <p className="mt-2 small text-body-secondary" hidden={method !== 'upi'}>Pay with any UPI app — GPay, PhonePe, Paytm or BHIM.</p>
            <p className="mt-2 small text-body-secondary" hidden={method !== 'card'}>Visa, Mastercard, RuPay and Amex credit or debit cards.</p>
            <p className="mt-2 small text-body-secondary" hidden={method !== 'netbanking'}>All major Indian banks supported.</p>
          </div>
          <button type="button" className="btn btn-brand fw-semibold rounded-2 w-100" onClick={(e) => payWithRazorpay(e)}>Pay ₹9,999</button>
        </form>
      </div>
    </div>
  );
}
All components →

Free Bootstrap 5 Razorpay Checkout Form for React by pGento

Install Bootstrap 5 for React

Create a React project with Vite and install Bootstrap:

npm create vite@latest my-app -- --template react
cd my-app
npm install
npm install bootstrap

Save the generated theme.css next to the component; the component file already imports bootstrap/dist/css/bootstrap.min.css and ./theme.css. No Bootstrap JavaScript is required — interactivity uses useState.

Use the razorpay checkout form in React

// App.jsx
import RazorpayCheckout from './RazorpayCheckout';

export default function App() {
  return <RazorpayCheckout />;
}

Connecting the form to Razorpay

  1. Create an order on your server with the Orders API using your key_secret and return { id, amount, currency } from /api/razorpay/order.
  2. Replace rzp_test_YOUR_KEY_ID with your public key_id (test keys first).
  3. In /api/razorpay/verify, compute HMAC_SHA256(order_id + "|" + payment_id, key_secret) and compare it with razorpay_signature before marking the order paid. Also handle the payment.captured webhook as the source of truth.

The preview never contacts Razorpay — clicking “Pay” there only shows where checkout would open.

Accessibility & customization

Payment methods are toggle buttons with aria-pressed, totals are real text (not images), the phone field uses inputmode="tel" and autocomplete tokens, and the pay button states the exact amount.

Every color, radius and dark-mode choice is baked into plain Bootstrap classes plus a tiny CSS-variable theme file, so the copied code has no runtime dependency on this site.

Compatibility

ItemDetails
CSS frameworkBootstrap 5.3+ (CSS only)
LibraryReact 18+ (function component)
Interactive statemethod
Dark modeYes — toggle in the editor
StyleMinimal

Frequently asked questions

How do I install this Bootstrap razorpay checkout form in React?
Create a React project, install Bootstrap 5 as shown in the installation section, then paste the generated code. Also save the generated theme.css file.
Can I change the color of the razorpay checkout form?
Yes. Use the brand color picker or type any hex code — the preview and code update instantly, and the color is written directly into the classes you copy.
Does the razorpay checkout form support dark mode?
Yes. Toggle “Dark mode” in the editor to generate a dark palette version of the same component.
Is the razorpay checkout form accessible?
Payment methods are toggle buttons with aria-pressed, totals are real text (not images), the phone field uses inputmode="tel" and autocomplete tokens, and the pay button states the exact amount.
Is this component free for commercial use?
Yes. The generated code is yours to use in personal and commercial projects without attribution.
Bootstrap 5 Razorpay Checkout Form for React

Embed this tool on your site

Paste this code into any web page. It stays free, fast and ad-free inside your site.

Print or save as PDF

Prints just this tool and its result. Choose “Save as PDF” as the printer to get a file. Branding is stored only in this browser.