Razorpay is India's leading payment gateway, supporting UPI, cards, net banking, wallets, and more. Connecting InstantDM to Razorpay lets you send payment links directly in Instagram DMs - perfect for Indian businesses selling products, services, or courses through Instagram.
Why Use Razorpay with InstantDM?
- UPI support - accept payments via Google Pay, PhonePe, Paytm, and other UPI apps
- Indian payment methods - cards, net banking, wallets, EMI, and more
- Payment links - no website needed; Razorpay hosts the checkout
- INR native - pricing and settlement in Indian Rupees
- Low fees - 2% per transaction for standard plans
Common Use Cases
- Send a payment link after someone inquires about pricing via DM
- Collect course fees or consultation deposits through Instagram
- Sell digital products (PDFs, templates, courses) via DM
- Accept bookings with advance payment
- Offer Instagram-exclusive pricing
What You'll Need
| Requirement | Details |
|---|---|
| InstantDM account | Trendsetter, Trendsetter Pro, or any Multi plan |
| Razorpay account | Activated with KYC completed |
| InstantDM API key | Found at Settings → API in your InstantDM dashboard |
| Razorpay API keys | Found at Settings → API Keys in Razorpay Dashboard |
Method 1: Static Payment Links (Simplest)
Step 1: Create a Payment Link in Razorpay
- Go to dashboard.razorpay.com.
- Navigate to Payment Links → Create Payment Link.
- Set the amount, description, and customer details.
- Click Create.
- Copy the link (e.g.,
https://rzp.io/i/abc123).
Step 2: Use in InstantDM
Add the link as a button in your DM flow or send via API:
{
"action": "send_message",
"type": "buttons",
"recipient_id": "INSTAGRAM_USER_ID",
"message": "Here's your payment link 👇",
"buttons": [
{ "title": "Pay ₹999", "url": "https://rzp.io/i/abc123" }
]
}
Method 2: Dynamic Payment Links (Per Customer)
Generate unique payment links with pre-filled customer info.
Step 1: Get Your Razorpay API Keys
- In Razorpay Dashboard, go to Settings → API Keys.
- Generate a key pair.
- Copy the Key ID and Key Secret.
Step 2: Build a Webhook Receiver
const express = require('express');
const app = express();
app.use(express.json());
const RZP_KEY_ID = process.env.RAZORPAY_KEY_ID;
const RZP_KEY_SECRET = process.env.RAZORPAY_KEY_SECRET;
const INSTANTDM_API_KEY = process.env.INSTANTDM_API_KEY;
async function createPaymentLink(amount, description, customerName, customerEmail, customerPhone, metadata = {}) {
const response = await fetch('https://api.razorpay.com/v1/payment_links', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + Buffer.from(`${RZP_KEY_ID}:${RZP_KEY_SECRET}`).toString('base64'),
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: amount * 100, // Razorpay uses paise (1 INR = 100 paise)
currency: 'INR',
description: description,
customer: {
name: customerName || '',
email: customerEmail || '',
contact: customerPhone || '',
},
notify: {
sms: !!customerPhone,
email: !!customerEmail,
},
reminder_enable: true,
notes: metadata,
expire_by: Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60, // 7 days
}),
});
return response.json();
}
app.post('/instantdm-webhook', async (req, res) => {
const { event, data } = req.body;
if (event !== 'flow_completed') {
return res.status(200).json({ status: 'skipped' });
}
const interest = data.response_variables?.interest;
if (!interest) return res.status(200).json({ status: 'skipped' });
// Map interests to products
const products = {
'basic': { name: 'Basic Course', amount: 999 },
'premium': { name: 'Premium Course', amount: 2999 },
'consultation': { name: '1-on-1 Consultation', amount: 4999 },
};
const product = products[interest.toLowerCase()];
if (!product) return res.status(200).json({ status: 'skipped' });
try {
const paymentLink = await createPaymentLink(
product.amount,
product.name,
data.response_variables?.full_name,
data.response_variables?.email,
data.response_variables?.phone,
{
instagram_username: data.username,
flow_name: data.flow_name,
}
);
// Send via InstantDM
await fetch('https://api.instantdm.com/api-webhook', {
method: 'POST',
headers: {
'Authorization': `Bearer ${INSTANTDM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
action: 'send_message',
type: 'buttons',
recipient_id: data.instagram_user_id,
message: `Here's your payment link for ${product.name} (₹${product.amount}):`,
buttons: [
{ title: `Pay ₹${product.amount}`, url: paymentLink.short_url },
],
}),
});
res.status(200).json({ status: 'sent', paymentUrl: paymentLink.short_url });
} catch (error) {
res.status(500).json({ status: 'error', message: error.message });
}
});
app.listen(3000);
Handling Payment Confirmation
Set Up a Razorpay Webhook
- In Razorpay Dashboard, go to Settings → Webhooks.
- Click Add New Webhook.
- Set the URL to your server.
- Select event:
payment_link.paid. - Set a webhook secret for verification.
Handle the Webhook
const crypto = require('crypto');
app.post('/razorpay-webhook', express.raw({ type: 'application/json' }), async (req, res) => {
// Verify webhook signature
const signature = req.headers['x-razorpay-signature'];
const expectedSignature = crypto
.createHmac('sha256', process.env.RAZORPAY_WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (signature !== expectedSignature) {
return res.status(400).json({ error: 'Invalid signature' });
}
const event = JSON.parse(req.body);
if (event.event === 'payment_link.paid') {
const paymentLink = event.payload.payment_link.entity;
const instagramUserId = paymentLink.notes?.instagram_user_id;
if (instagramUserId) {
await fetch('https://api.instantdm.com/api-webhook', {
method: 'POST',
headers: {
'Authorization': `Bearer ${INSTANTDM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
action: 'send_message',
type: 'text',
recipient_id: instagramUserId,
message: `✅ Payment received! Thank you for your purchase. We'll send you access details shortly. 🙏`,
}),
});
}
}
res.status(200).json({ received: true });
});
Via Make.com
- Set up the webhook per the Make.com guide.
- Add an HTTP → Make a request module to call Razorpay's API.
- Create the payment link.
- Add another HTTP module to send the link via InstantDM API.
Troubleshooting
| Issue | Solution |
|---|---|
| API returning 401 | Verify Key ID and Key Secret. Ensure you're using Basic Auth (not Bearer). |
| Payment link not opening | Check the short_url from the response. Ensure the link hasn't expired. |
| Amount incorrect | Razorpay uses paise (multiply INR by 100). ₹999 = 99900 paise. |
| Customer not receiving notifications | Check that notify.sms and notify.email are set to true, and customer contact info is provided. |
| Webhook not firing | Verify the webhook URL is publicly accessible. Check the webhook secret matches. |
| KYC not completed | Razorpay requires KYC verification before you can accept live payments. Complete it in the Dashboard. |
Frequently Asked Questions
How much does Razorpay charge?
Standard pricing is 2% per transaction for domestic payments. International payments have higher fees. No setup fees or monthly charges.
Can I accept international payments?
Yes. Enable international payments in Razorpay Dashboard → Settings. International cards and PayPal are supported. Fees are higher for international transactions.
Can I use Razorpay for subscriptions?
Yes. Razorpay supports recurring payments via Subscriptions API. Create a subscription plan and send the subscription link via DM instead of a one-time payment link.
How does Razorpay compare to Stripe for Indian businesses?
Razorpay is better for Indian businesses - it supports UPI, Indian wallets, net banking, and EMI natively. Settlement is in INR with no currency conversion. Stripe works in India too but Razorpay has deeper local payment method support.
What's Next
- Set up Stripe for international payment processing.
- Connect to Shopify for full e-commerce integration.
- Read the WooCommerce guide for WordPress stores.
- Build a Custom AI Agent to handle pricing inquiries.
- Explore the full API docs at instantdm.com/instagram-api-docs.