This guide details how to connect your CRM microservice, backend, and Razorpay to create a seamless payment workflow. There are three main areas you will need to configure:
Once all three parts are configured and working together, your integration is ready.
| Field | Description & Setup Link |
|---|---|
| Active Environment | Choose Test or Production — see details |
| Auth ID | Razorpay Key ID — generate keys |
| Client Secret | Razorpay Key Secret — generate keys |
| Callback URL | Backend endpoint — see callback setup |
| Webhook Secret | Value from Razorpay — configure webhook |
| Plans | Registered Plan IDs — create plans |
In Dashboard → Settings → API Keys → Generate Key. Copy and store:
Key ID: use as Auth ID in CRM.Key Secret: use as Client Secret in CRM (shown once).If you don’t have a Razorpay account, create one and complete verification before proceeding.
you will see this URL when opening configuration modal in CRM.
Go to Dashboard → Settings → Webhooks → Add new webhook.
Razorpay → CRM: CRM validates signatures and forwards the validated payload to your backend callback URL.
Create recurring billing plans in Dashboard → Subscriptions → Plans → Create Plan. Required fields:
Copy the generated planId and register it in CRM or include it in create-order payloads.
Offers apply discounts or cashback for a single payment method. Create separate offers for each method:
offerId_upiofferId_cardNote: Only one offerId can be used per transaction. Apply based on the user’s payment method.
The CRM provides an endpoint to create Razorpay orders or subscriptions and return checkout data.
CRM_API_HOST="https://cs.fabbuilder.com"
CRM_TENANT_ID="your_tenant_id"
CRM_RAZORPAY_SUBURL="cs-app/razorpay"
const response = await axios.post(
`${CRM_API_HOST}/${CRM_RAZORPAY_SUBURL}/api/tenant/${CRM_TENANT_ID}/razorpay/customer/create-order`, payload
);
const order = response.data.data;
if (!order || !order.id) {
console.error('response error', response.data);
throw new Error('Razorpay order not created. Please try again.');
}
One-time Payment Payload:
{
"type": "one_time",
"leadId": "",
"email": "customer@example.com",
"contact": "9999999999",
"amount": 50000,
"offerId": ""
}
Subscription Payload:
{
"type": "recurring",
"leadId": "",
"email": "customer@example.com",
"contact": "9999999999",
"planId": "plan_XXXX",
"offerId": ""
}
CRM Expected Response:
{
"success": true,
"data": {
"id": "order_XXXX" // or "sub_XXXX" for subscriptions
}
}
Expose a POST endpoint in your backend to receive Razorpay webhook events:
<backend_url>/api/webhooks/razorpay
Example controller for handling Razorpay webhook events:
export default async function handleRazorpayWebhook(req, res) {
try {
const { event, payload } = req.body;
switch (event) {
case 'subscription.activated':
await processSubscriptionActivated(payload);
break;
case 'subscription.charged':
await processSubscriptionCharged(payload);
break;
case 'subscription.halted':
await processSubscriptionHalted(payload);
break;
case 'subscription.cancelled':
await processSubscriptionCancelled(payload);
break;
case 'payment.captured':
await processPaymentCaptured(payload);
break;
case 'payment.failed':
await processPaymentFailed(payload);
break;
default:
console.warn('Unhandled event type:', event);
}
return res.status(200).json({ status: 'ok' });
} catch (err) {
console.error('Webhook handler error', err);
return res.status(500).json({ error: 'processing_failed' });
}
}
200 OK).Once Razorpay, CRM, and Backend are properly configured:
Your integration is complete, secure, and ready for production.