A Step-by-Step Guide to Integrating Razorpay with Your Custom PHP Website
Prerequisites: What You Need Before Integrating Razorpay
Before you begin to integrate the Razorpay payment gateway in your PHP website, a solid foundation is essential for a smooth and secure process. Attempting to build on unstable ground will only lead to complications, delays, and potential security vulnerabilities. As expert consultants at WovLab, we always ensure our clients have a comprehensive checklist in place before writing a single line of integration code. First, your server environment must meet the minimum requirements. You'll need a web server running PHP version 7.1 or higher. Additionally, the cURL extension for PHP must be enabled, as the Razorpay PHP SDK relies on it to make HTTP requests to the Razorpay API servers. Without cURL, your server cannot communicate with Razorpay.
Next, you absolutely must have an active Razorpay account. If you don't have one, sign up on the Razorpay website. Once your account is created, you will need to generate a set of API keys. Navigate to the API Keys section in your Razorpay Dashboard settings. You will need both the Key ID and the Key Secret. The Key ID is a public key used to identify your account on the frontend, while the Key Secret is a confidential key used for server-side authentication and signature verification. Treat your Key Secret like a password; never expose it in client-side code or commit it to a public version control repository.
A common mistake we see is developers hardcoding their API keys directly into their PHP files. This is a significant security risk. We strongly recommend using environment variables (e.g., via a
.envfile and a library likevlucas/phpdotenv) to store your sensitive keys, keeping them separate from your codebase.
Finally, ensure you have Composer, the dependency manager for PHP, installed on your development machine and accessible from your project directory. We will use Composer to install the official Razorpay PHP SDK, which is the most reliable and secure method for interacting with the Razorpay API. It handles autoloading and simplifies the process of keeping your integration up-to-date with the latest features and security patches.
Step 1: Installing the Razorpay PHP SDK and Setting Up Your Keys
With the prerequisites handled, the next logical step is to install the official Razorpay PHP library. This SDK provides a robust, pre-built interface for all of Razorpay's API endpoints, saving you the considerable effort of building and maintaining your own cURL requests. The recommended and most efficient method for installation is via Composer. Open your terminal, navigate to your project's root directory, and execute the following command:
composer require razorpay/razorpay-php
This command instructs Composer to download the Razorpay SDK and its dependencies into a vendor directory and automatically generate an autoload.php file. This autoloader is crucial, as it will handle loading the necessary SDK classes into your scripts on demand. To use the SDK, you simply need to include this autoloader in your PHP files where you intend to interact with the Razorpay API:
require __DIR__ . '/vendor/autoload.php';
Once the SDK is included, you must instantiate the Razorpay API client. This requires the Key ID and Key Secret you obtained from your Razorpay dashboard. As mentioned, avoid hardcoding these credentials. A best practice is to store them in environment variables and access them using getenv() or a similar method. Here’s how you initialize the client:
use Razorpay\Api\Api;
// It's best to load these from a .env file
$keyId = 'YOUR_KEY_ID';
$keySecret = 'YOUR_KEY_SECRET';
$api = new Api($keyId, $keySecret);
The instantiation of the
Apiclass is your gateway to every function Razorpay offers. A successful instantiation means your server is ready to communicate securely with Razorpay's servers. If this step fails, it's almost always due to incorrect keys or a missingautoload.phpfile.
This single $api object is now your tool for creating orders, fetching payments, verifying signatures, and more. Keep this object handy, as we will use it in the subsequent steps of this guide to integrate the Razorpay payment gateway in your PHP website.
Step 2: Creating a Dynamic Order ID from Your PHP Backend
A critical, non-negotiable step in a secure payment flow is to create an Order ID on your server before the payment process begins. The Order ID is a unique identifier generated by Razorpay's servers that corresponds to a specific transaction amount, currency, and other details. Never trust an amount sent from the client-side; always define it on your backend to prevent price manipulation. This server-side order creation is a cornerstone of a secure Razorpay PHP integration.
Using the $api object we instantiated in the previous step, we can call the Orders API. You need to provide at least the amount, currency, and a unique receipt ID from your system. The amount must be in the smallest currency unit (e.g., paise for INR). For ₹500.00, you would specify 50000. Here is a practical PHP example:
// Let's assume this is for an order in our system with an ID of 'order_123'
$myOrderId = 'order_123';
$orderAmount = 500.00; // The amount in your currency's base unit (e.g., Rupees)
$orderCurrency = 'INR';
$orderData = [
'receipt' => $myOrderId,
'amount' => $orderAmount * 100, // Amount in the smallest currency unit
'currency' => $orderCurrency,
'notes' => [
'user_id' => 'your_user_id_12',
'custom_info' => 'This is some custom information.'
]
];
$razorpayOrder = $api->order->create($orderData);
$razorpayOrderId = $razorpayOrder['id'];
$displayAmount = $orderAmount;
$displayCurrency = $orderCurrency;
// We will pass this $razorpayOrderId to the frontend checkout form
The $razorpayOrder object returned by the API contains the newly created id, which we've stored in $razorpayOrderId. It also contains all the details you passed, now officially logged in Razorpay's system. The notes field is particularly useful for storing your application-specific data, like a user ID or product SKU, which can help with reconciliation later.
Think of the server-side Order creation as a contract. Your server tells Razorpay, "I am expecting a payment of exactly this amount for this receipt ID." Razorpay locks in this amount. Now, even if a malicious user tries to alter the amount on the frontend checkout form, the payment will be rejected because it won't match the server-defined Order ID's value.
You must now pass this $razorpayOrderId to your frontend. You can do this by embedding it directly into the HTML if your page is rendered by PHP, or by sending it via a JSON response if you're using an AJAX call to a PHP endpoint that performs this logic. This ID is the critical link between your backend's "contract" and the user's checkout experience.
Step 3: Implementing the Checkout Form on Your Frontend
With the server-side logic in place to generate a unique Order ID, we can now shift our focus to the client-side. This is where the user will interact with the Razorpay payment modal. Razorpay's Checkout is a JavaScript-based drop-in form that handles the entire payment process securely, including OTPs and 3D Secure authentication, without the user ever leaving your site. This ensures a seamless experience and helps build trust. To begin, you need to include the Razorpay Checkout script on your payment page, preferably just before the closing </body> tag.
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
Next, you create the payment initiation button. This can be a simple <button> element. However, the real magic happens in the JavaScript that configures and opens the checkout modal. You will use the Razorpay constructor, passing it an options object. This object is where you connect your frontend to the Order ID generated in the previous step.
Here’s a complete example of a payment button and the associated JavaScript, assuming you have passed the order details from PHP:
<button id="rzp-button1">Pay Now</button>
<script>
var options = {
"key": "<?php echo $keyId; ?>", // Your Key ID
"amount": "<?php echo $displayAmount * 100; ?>", // Amount is in currency subunits.
"currency": "<?php echo $displayCurrency; ?>",
"name": "WovLab Inc.", //your business name
"description": "Test Transaction",
"image": "https://wovlab.com/logo.png", //Your logo URL
"order_id": "<?php echo $razorpayOrderId; ?>", //This is a sample Order ID. Pass the `id` obtained in the response of Step 2
"handler": function (response){
// This function is called after a successful payment
// You can now redirect to a success page or verify the payment on the same page
window.location.href = 'verify.php?payment_id=' + response.razorpay_payment_id + '&order_id=' + response.razorpay_order_id + '&signature=' + response.razorpay_signature;
},
"prefill": {
"name": "Gaurav Kumar", //your customer's name
"email": "gaurav.kumar@example.com",
"contact": "9000090000"
},
"notes": {
"address": "WovLab Corporate Office"
},
"theme": {
"color": "#3399cc"
}
};
var rzp1 = new Razorpay(options);
document.getElementById('rzp-button1').onclick = function(e){
rzp1.open();
e.preventDefault();
}
</script>
The
handlerfunction is the most important part of the client-side code. It executes only after a payment is successfully captured by Razorpay. It receives a response containingrazorpay_payment_id,razorpay_order_id, andrazorpay_signature. Your job is to immediately send these three pieces of information back to your server for final verification. Never trust a successful callback alone as confirmation.
This implementation provides a complete, branded checkout experience. The user sees your company name, logo, and pre-filled information, making the process smooth. Upon clicking "Pay Now," the modal opens, handles the payment, and on success, triggers your handler function, which then passes the critical details to your backend verification script—the final and most important step.
Step 4: Verifying the Payment Signature to Finalize the Transaction
This is the final and most crucial step in the entire process to integrate a Razorpay payment gateway in a PHP website. It is the only guaranteed way to confirm the authenticity of a payment. After the client-side handler receives a successful payment response from Razorpay, it sends the razorpay_payment_id, razorpay_order_id, and razorpay_signature back to your server. Your server-side verification script must then perform a cryptographic check to confirm that the payment was genuine and not tampered with.
The process involves generating your own signature using the Order ID and the Payment ID combined with your secret key. You then compare this generated signature with the signature sent by Razorpay. If they match, the payment is authentic. Here is how you implement this check in your verify.php file using the Razorpay PHP SDK:
require('config.php'); // Your config file with keys
require('vendor/autoload.php');
use Razorpay\Api\Api;
use Razorpay\Api\Errors\SignatureVerificationError;
$success = true;
$error = "Payment Failed";
if (empty($_GET['payment_id']) === false)
{
$api = new Api($keyId, $keySecret);
try
{
// Please note that the attributes should be in this order.
// The attributes should be the same as passed in the checkout script.
$attributes = [
'razorpay_order_id' => $_GET['order_id'],
'razorpay_payment_id' => $_GET['payment_id'],
'razorpay_signature' => $_GET['signature']
];
$api->utility->verifyPaymentSignature($attributes);
}
catch(SignatureVerificationError $e)
{
$success = false;
$error = 'Razorpay Error : ' . $e->getMessage();
}
}
if ($success === true)
{
// Payment was successful. You can now update your database.
// For example, update your order status to 'paid'.
// echo "Payment Successful. Payment ID: {$_GET['payment_id']}";
// Redirect to a success page
header('Location: success.php');
}
else
{
// Payment failed.
// echo "Payment failed. Error: {$error}";
// Redirect to a failure page
header('Location: failure.php?error=' . urlencode($error));
}
The verifyPaymentSignature method within the SDK's utility class handles the complex signature generation and comparison for you. It takes an array containing the three key pieces of data and will throw a SignatureVerificationError if the signature is invalid. This try-catch block is the heart of your security logic. Only inside the try block, after the verification call has passed without an error, should you consider the transaction complete.
Crucially, signature verification MUST happen on the server. A client-side check is worthless as JavaScript can be easily manipulated. Failing to perform this server-side check is like leaving your cash register unlocked. It's the single biggest security mistake a developer can make when integrating a payment gateway.
Once the signature is verified, you can confidently update your database. Mark the order as 'paid', release the digital product, or start the shipping process. The transaction is now complete, secure, and authenticated.
Integration Complete: Need Help with a Custom Solution? Contact WovLab
You have now successfully walked through the essential steps to integrate the Razorpay payment gateway in your PHP website. From setting up your environment and installing the SDK, to creating server-side orders, implementing the frontend checkout, and performing the critical server-side signature verification, this guide covers the core of a secure and robust integration. Following these steps meticulously ensures that your payment processing is safe, reliable, and provides a seamless experience for your customers. This foundation is perfect for most standard e-commerce sites, subscription services, and invoicing platforms running on a custom PHP stack.
However, the world of digital business is rarely one-size-fits-all. Your specific needs might go beyond this standard implementation. Perhaps you need a complex subscription model with tiered pricing and automated recurring billing. Maybe you require a dynamic split payment system for a marketplace platform, where funds are automatically routed to multiple vendors. Or you could be looking to integrate payments deeply into a legacy ERP system, requiring custom logic for reconciliation and reporting.
A standard integration is just the beginning. The real value comes from tailoring the payment flow to your unique business logic, creating efficiency and unlocking new revenue models. This is where expert implementation becomes a competitive advantage.
At WovLab, we are more than just developers; we are architects of complex digital solutions. As a full-service digital agency from India, our expertise spans across AI Agents, custom development, SEO, cloud architecture, and, of course, intricate payment gateway integrations. We have helped businesses across the globe build highly custom, scalable, and secure payment systems tailored to their exact operational needs. If you've completed this guide but find yourself asking, "What's next?" or "How can I make this fit my business model?", then it's time to talk to an expert. Contact WovLab today, and let us help you build a payment solution that not only works but works brilliantly for you.
Ready to Get Started?
Let WovLab handle it for you — zero hassle, expert execution.
💬 Chat on WhatsApp