Take UPI payments straight into your bank account with no gateway fee. Pick your setup and follow the steps.
No server to run. The plugin does everything inside your site.
[paisaify_donate] on any page. Skip this step if you do not take donations.A small server (Node.js) watches your bank SMS and tells your site when a payment arrives. You set it up once and it can serve many sites.
You need Node.js 22.13 or newer (24 is best), a folder that is kept between restarts, and a https address. Pick any host below. The upload steps differ a little, and the settings are the same everywhere.
[Unit] Description=Paisaify After=network.target [Service] WorkingDirectory=/opt/paisaify ExecStart=/usr/bin/node server.js Restart=always Environment=PORT=4900 [Install] WantedBy=multi-user.target
Run systemctl enable --now paisaify. For https, install Caddy and use this Caddyfile (it gets the certificate by itself):
pay.yourshop.com {
reverse_proxy localhost:4900
}Set TRUST_PROXY=yes because Caddy sits in front.
Create a service from the zip or your repository. Start command node server.js, Node 22 or newer. Add the settings as variables. Attach a persistent volume (for example at /data) and set DB_PATH=/data/paisaify.sqlite, otherwise payments are lost on every deploy. Choose a plan that stays awake: a service that sleeps will miss your phone's messages.
Run node server.js and expose it with a Cloudflare Tunnel to get a https address. It works while the computer and internet stay on, so use a proper host before real customers.
Plain PHP-only shared hosting (no Node.js), and serverless or edge platforms such as Cloudflare Workers and Vercel functions (no long-running process or writable disk). On PHP hosting use the WordPress plugin if your site is WordPress.
PUBLIC_URLThe https address of your Paisaify server, for example https://pay.yourshop.com. No slash at the end.VPAYour own UPI ID where money should arrive, for example yourname@okhdfcbank.PAYEEThe name customers see in their UPI app.WEBHOOK_SECRETA long random password (40 or more characters). Your phone uses it. Make one with a password generator.ADMIN_TOKENAnother long random password. This is how you sign in to your dashboard at /admin. Keep it private.ALLOWED_ORIGINSThe websites allowed to use this server, for example https://yourshop.com. Separate several with commas.DB_PATHA folder that survives restarts, for example /home/YOURUSER/paisaify-data/paisaify.sqlite. Create the folder first.PRODUCTSWhat you sell: slug|price|Title|thank-you page. Example: report|499|My Report|https://yourshop.com/thanks. Several items separated by a semicolon.Everything else is optional. Donations, email, alerts and WhatsApp are set later from the dashboard, with no file editing.
Open your-address/admin, sign in with your ADMIN_TOKEN, and you will see Activate your copy. Paste the key that came with your purchase (it looks like PSFY-XXXX-XXXX-XXXX-XXXX) and press Activate. One key works on one installation. Without activation the dashboard stays locked, and after 7 days payments stop too.
Selling one thing from a static site (the price always comes from your server, so nobody can change it in the browser):
const r = await fetch('https://pay.yourshop.com/api/checkout', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ product: 'report', consent: true, fields: { name, email, phone } }),
});
const { ok, html, error } = await r.json(); // html is the pay box. Show it on your page.Donations (add your site to ALLOWED_ORIGINS and switch on donations in Settings):
<div data-paisaify-donate data-api="https://pay.yourshop.com/api"></div> <script src="https://pay.yourshop.com/assets/donate.js" defer></script>
A shop that has its own server can create payments with the API. See the API section below.
Use the next sections. Then make a ₹1 payment link from Transactions, New payment link, pay it, and watch it turn Paid.
Your phone is the eye of the system. It sees the "money received" text from your bank and tells the server. Use the phone that receives your bank SMS and keep it on with signal.
Download from this server's app page. Open your dashboard, find Paisaify app, press Show pairing code, then scan it in the app. Allow notification access and set battery to Unrestricted.
Install the free MacroDroid from Google Play. In your dashboard press Download rule file, send it to the phone, open it with MacroDroid and switch the rule on.
iPhone cannot run the app. Use the Shortcuts app: Automation, Message contains credited, Run Immediately, action Get Contents of URL with the link from your dashboard. The dashboard shows the exact steps.
Many phones stop apps they think you are not using. That would stop bank SMS reaching the server. The app has a Keep running screen that finds your brand and opens the right settings. The short version:
The menu names change a little between software versions. If the server sees no sign of a phone for 30 minutes during the day (7am to 11pm), it sends you an alert, and another when the phone is back. Background tips inspired by dontkillmyapp.com.
All optional. Each one is free to start, and each has step-by-step help with links inside Settings.
Free, no account. Install the ntfy app, then press Turn on phone alerts on the dashboard and scan the code.
Free. Make a bot with @BotFather, paste its token in Settings, and press Start on your bot.
Create a Resend account, verify your domain, paste the API key in Settings. Receipts then go out as PDFs.
Free one-tap sending is built in. For automatic messages connect your own WhatsApp Business account in Settings. Meta charges per message.
Alerts carry only the amount and a reference number, never a customer's name, phone or email.
Create a payment from your own server and get told when it is paid.
Add MERCHANT_API_KEY to the server settings, then:
curl -X POST https://pay.yourshop.com/api/v1/payments \
-H "Authorization: Bearer $MERCHANT_API_KEY" -H "Content-Type: application/json" \
-d '{"amount":"999","reference":"ORD-1042","callback_url":"https://yourshop.com/hooks/upi","return_url":"https://yourshop.com/thanks"}'Send the customer to the pay_url in the reply. The amount can be up to 99 paise above what you asked, which is how two orders of the same price stay apart. When paid, your callback_url receives a signed message. The full details are in the README inside the zip.
Some apps refuse payment links to a personal UPI ID. Scanning the QR code with the camera, or typing your UPI ID in the "Pay to UPI ID" box on the pay page, both work. A business UPI ID from your bank avoids this. Ask your bank how it settles and whether it sends a text for each payment.
Allow your browser to install unknown apps (Settings, Apps, your browser). On Samsung also switch off Auto Blocker while installing. Open the download page again after that.
Press Send a test alert on the dashboard. It lists any channel that failed. For Telegram, open your bot and press Start. For ntfy, check the topic in the app matches.
The sender address must be on a domain you verified in Resend. Use Send test email in Settings to see the exact error.
The token is the ADMIN_TOKEN in your host's settings. For a new phone, make a fresh pairing code, then remove the old phone from the Paisaify app card.
Paisaify for UPI, a Flying Star product.