v3.0.0 is released! Automatic Transaction Splitting, Zod 4 & Precision Math.
What's New
Framework GuideVanilla JS

Vanilla JavaScript Guide

Generate and display UPI QR codes with core JavaScript. Works with bundlers (Vite, Webpack, Rollup) or directly in the browser via ESM CDNs.

Browser ES Modules (CDN)

You can load @omkarbhosale/upiqr directly into an HTML file without any build step using modern ESM CDNs such as esm.sh:

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>UPI QR Vanilla JS Demo</title>
</head>
<body>
  <div style="max-width: 320px; margin: 40px auto; text-align: center; font-family: sans-serif;">
    <h2>UPI QR Payment</h2>
    <img id="qr-image" src="" alt="Scan to pay" style="width: 220px; height: 220px; border: 1px solid #ddd; border-radius: 12px; margin: 16px 0;" />
    <p id="status">Generating QR code...</p>
    <button id="copy-upi" style="padding: 8px 16px; border-radius: 6px; cursor: pointer;">Copy UPI ID</button>
  </div>

  <script type="module">
    import { generateQR } from "https://esm.sh/@omkarbhosale/upiqr@3.0.0";

    const UPI_ID = "store@okhdfcbank";
    const AMOUNT = 750;

    async function init() {
      try {
        const qrUrl = await generateQR({
          UPI_ID,
          AMOUNT,
          name: "Omkar Store",
          note: "Order #9821"
        });

        document.getElementById("qr-image").src = qrUrl;
        document.getElementById("status").textContent = `Pay ₹${AMOUNT} via any UPI app`;
      } catch (err) {
        document.getElementById("status").textContent = "Error: " + err.message;
      }
    }

    document.getElementById("copy-upi").addEventListener("click", () => {
      navigator.clipboard.writeText(UPI_ID);
      alert("UPI ID copied!");
    });

    init();
  </script>
</body>
</html>

Vanilla Split QR Grid

Dynamically render multiple split cards in Vanilla JS:

split-renderer.js
import { splitTransactionQR } from "@omkarbhosale/upiqr";

async function renderSplits(containerId, amount) {
  const container = document.getElementById(containerId);
  container.innerHTML = "Calculating splits...";

  try {
    const splits = await splitTransactionQR({
      UPI_ID: "store@upi",
      AMOUNT: amount,
      name: "Omkar Store",
      note: "Checkout"
    });

    container.innerHTML = "";

    splits.forEach((item, index) => {
      const card = document.createElement("div");
      card.className = "split-card";
      card.innerHTML = `
        <h4>Part ${index + 1} of ${splits.length}</h4>
        <img src="${item.image}" alt="QR code" width="180" height="180" />
        <p><strong>₹${item.amount}</strong></p>
      `;
      container.appendChild(card);
    });
  } catch (error) {
    container.innerHTML = `<p style="color: red;">${error.message}</p>`;
  }
}

// Render ₹5,000 splits:
renderSplits("splits-grid", 5000);