v3.0.0 is released! Automatic Transaction Splitting, Zod 4 & Precision Math.
What's New
Core APISingle QR

generateQR(params)

Generates a single standard UPI QR code as a base64 Data URL string. Validated at runtime using Zod 4.

Function Signature

typescript
function generateQR(params: QRParams): Promise<string>;

Parameters (QRParams)

An object containing the transaction configuration and optional metadata:

ParameterTypeRequiredDefaultDescription
UPI_IDstringRequiredValid Virtual Payment Address (e.g. store@upi). Validated via /^[\w.-]+@[\w.-]+$/.
AMOUNTnumberRequiredPositive finite number up to ₹1,00,000.
namestringOptionalPayee Name (encoded as pn in the UPI URL).
notestringOptionalTransaction Note / Memo (encoded as tn in the UPI URL).
currencystringOptional"INR"Currency code (defaults to "INR").

Return Value

Returns a Promise<string> that resolves to a base64-encoded Data URL of the generated PNG image:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAA...

Step-by-Step Implementation Guide

1

Validate or Sanitize User Input

Ensure the UPI ID and amount are present and within valid ranges before making the call, or rely on @omkarbhosale/upiqr's built-in Zod validation.

2

Invoke generateQR

Call the asynchronous function within a try/catch block. Pass your UPI ID, target amount, payee name, and note.

3

Render Base64 Image in DOM or React

Set the resolved string directly as the src attribute of an <img> element or Next.js <Image /> component.

4

Add Download & Sharing Utility (Optional)

Allow your customers to save the QR code to their phone gallery for easy scanning via payment apps:

javascript
function downloadQR(dataUrl, filename = "upi-payment-qr.png") {
  const link = document.createElement("a");
  link.href = dataUrl;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

Code Examples

Basic Node.js / TypeScript Example

index.ts
import { generateQR } from "@omkarbhosale/upiqr";

const createSingleQR = async () => {
  try {
    const qrDataUrl = await generateQR({
      UPI_ID: "omkar@okhdfcbank",
      AMOUNT: 750,
      name: "Omkar Bhosale",
      note: "Coffee and snacks bill",
      currency: "INR"
    });

    console.log(qrDataUrl);
    // Output: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
  } catch (error) {
    console.error("QR creation failed:", error.message);
  }
};

createSingleQR();

React / Next.js Component Example

components/SingleQRCheckout.tsx
import React, { useState, useEffect } from "react";
import { generateQR } from "@omkarbhosale/upiqr";

export default function SingleQRCheckout({ amount = 500 }) {
  const [qrUrl, setQrUrl] = useState(null);
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let mounted = true;

    async function loadQR() {
      try {
        setLoading(true);
        const dataUrl = await generateQR({
          UPI_ID: "store@upi",
          AMOUNT: amount,
          name: "Acme Store",
          note: "Order #5092"
        });
        if (mounted) setQrUrl(dataUrl);
      } catch (err) {
        if (mounted) setError(err.message);
      } finally {
        if (mounted) setLoading(false);
      }
    }

    loadQR();
    return () => { mounted = false; };
  }, [amount]);

  if (loading) return <div>Generating UPI QR Code...</div>;
  if (error) return <div className="text-red-500">{error}</div>;

  return (
    <div className="p-4 border rounded-xl max-w-xs text-center">
      <h3 className="font-bold mb-2">Scan & Pay ₹{amount}</h3>
      {qrUrl && <img src={qrUrl} alt="UPI QR Code" className="mx-auto w-48 h-48" />}
      <p className="text-xs text-slate-500 mt-2">Scan with GPay, PhonePe, or Paytm</p>
    </div>
  );
}

Error Handling

If parameters do not pass schema validation, generateQR throws a descriptive Error. Always wrap in try/catch:

Amount Limit Notice
The maximum amount for a single QR code is ₹1,00,000. If your checkout requires amounts up to ₹10,00,000 or exceeds ₹2,000, consider using splitTransactionQR().