upi-qr-code-generator 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +186 -0
- package/dist/index.cjs +133 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +49 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +94 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 techpool
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# UPI QR Code Generator
|
|
2
|
+
|
|
3
|
+
Generate UPI payment URIs and QR codes with a pre-filled INR amount. The
|
|
4
|
+
library works in Node.js and browser applications using a bundler, and ships
|
|
5
|
+
with ESM, CommonJS, and TypeScript declarations.
|
|
6
|
+
|
|
7
|
+
> This package generates payment requests. It does not initiate, verify, or
|
|
8
|
+
> reconcile payments and never handles a payer's UPI PIN.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- Creates standards-shaped `upi://pay` URIs
|
|
13
|
+
- Includes and validates a fixed payment amount
|
|
14
|
+
- Generates PNG data URLs or SVG strings
|
|
15
|
+
- Escapes payee names, notes, and references safely
|
|
16
|
+
- Supports merchant transaction references and merchant category codes
|
|
17
|
+
- Provides TypeScript types and works from JavaScript
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
Once published to npm:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npm install upi-qr-code-generator
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
To install the current GitHub version:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
npm install github:techpool/upi-qr-code-generator
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Node.js 20 or newer is supported.
|
|
34
|
+
|
|
35
|
+
## Quick start
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
import {
|
|
39
|
+
createUpiPaymentUri,
|
|
40
|
+
generateUpiQrDataUrl,
|
|
41
|
+
} from "upi-qr-code-generator";
|
|
42
|
+
|
|
43
|
+
const payment = {
|
|
44
|
+
payeeVpa: "merchant@bank",
|
|
45
|
+
payeeName: "Example Store",
|
|
46
|
+
amount: "149.00",
|
|
47
|
+
transactionRef: "ORDER-123",
|
|
48
|
+
transactionNote: "Order 123",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const uri = createUpiPaymentUri(payment);
|
|
52
|
+
console.log(uri);
|
|
53
|
+
|
|
54
|
+
const qrDataUrl = await generateUpiQrDataUrl(payment);
|
|
55
|
+
|
|
56
|
+
// Browser example
|
|
57
|
+
document.querySelector("img").src = qrDataUrl;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The generated URI looks like this:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
upi://pay?pa=merchant%40bank&pn=Example%20Store&am=149.00&cu=INR&tr=ORDER-123&tn=Order%20123
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Generate SVG
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
import { generateUpiQrSvg } from "upi-qr-code-generator";
|
|
70
|
+
|
|
71
|
+
const svg = await generateUpiQrSvg({
|
|
72
|
+
payeeVpa: "merchant@bank",
|
|
73
|
+
payeeName: "Example Store",
|
|
74
|
+
amount: "499.50",
|
|
75
|
+
transactionRef: "ORDER-456",
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
In Node.js, save the returned SVG with `node:fs/promises`. A complete example
|
|
80
|
+
is available in [`examples/generate-svg.mjs`](examples/generate-svg.mjs).
|
|
81
|
+
|
|
82
|
+
## CommonJS
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
const { generateUpiQrDataUrl } = require("upi-qr-code-generator");
|
|
86
|
+
|
|
87
|
+
const qrDataUrl = await generateUpiQrDataUrl({
|
|
88
|
+
payeeVpa: "merchant@bank",
|
|
89
|
+
payeeName: "Example Store",
|
|
90
|
+
amount: "99.00",
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## API
|
|
95
|
+
|
|
96
|
+
### `createUpiPaymentUri(payment)`
|
|
97
|
+
|
|
98
|
+
Returns the encoded `upi://pay` URI.
|
|
99
|
+
|
|
100
|
+
### `generateUpiQrDataUrl(payment, qrOptions?)`
|
|
101
|
+
|
|
102
|
+
Returns a promise containing a PNG `data:image/png;base64,...` URL.
|
|
103
|
+
|
|
104
|
+
### `generateUpiQrSvg(payment, qrOptions?)`
|
|
105
|
+
|
|
106
|
+
Returns a promise containing an SVG string.
|
|
107
|
+
|
|
108
|
+
### `normalizeUpiAmount(amount)`
|
|
109
|
+
|
|
110
|
+
Validates a positive amount with at most two decimal places and returns an
|
|
111
|
+
exact two-decimal string. It does not silently round.
|
|
112
|
+
|
|
113
|
+
### Payment options
|
|
114
|
+
|
|
115
|
+
| Option | Type | Required | UPI field | Description |
|
|
116
|
+
| --- | --- | --- | --- | --- |
|
|
117
|
+
| `payeeVpa` | `string` | Yes | `pa` | Payee UPI virtual payment address |
|
|
118
|
+
| `payeeName` | `string` | Yes | `pn` | Name shown in the payer's app |
|
|
119
|
+
| `amount` | `string \| number` | Yes | `am` | Positive INR amount, maximum two decimal places |
|
|
120
|
+
| `transactionRef` | `string` | No | `tr` | Unique merchant reference, maximum 35 characters |
|
|
121
|
+
| `transactionNote` | `string` | No | `tn` | Payment note |
|
|
122
|
+
| `merchantCode` | `string` | No | `mc` | Merchant category code supplied by an acquirer |
|
|
123
|
+
|
|
124
|
+
Use decimal strings such as `"149.00"` for money. JavaScript numbers are
|
|
125
|
+
accepted for convenience, but values with more than two decimal places are
|
|
126
|
+
rejected rather than rounded.
|
|
127
|
+
|
|
128
|
+
For dynamic merchant QR codes, supply a unique `transactionRef` for each
|
|
129
|
+
payment. Your acquiring bank or PSP may require additional fields or impose
|
|
130
|
+
stricter rules.
|
|
131
|
+
|
|
132
|
+
### QR options
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
{
|
|
136
|
+
errorCorrectionLevel?: "low" | "medium" | "quartile" | "high" | "L" | "M" | "Q" | "H";
|
|
137
|
+
width?: number;
|
|
138
|
+
margin?: number;
|
|
139
|
+
scale?: number;
|
|
140
|
+
color?: {
|
|
141
|
+
dark?: string;
|
|
142
|
+
light?: string;
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Defaults are a width of 512 pixels, margin of 2 modules, and error correction
|
|
148
|
+
level `M`.
|
|
149
|
+
|
|
150
|
+
## Payment confirmation
|
|
151
|
+
|
|
152
|
+
A successful QR scan is not proof of payment. To confirm payments, use the
|
|
153
|
+
status, reconciliation, or webhook APIs provided by your bank, PSP, or payment
|
|
154
|
+
gateway. Match their confirmed transaction to your unique `transactionRef`.
|
|
155
|
+
|
|
156
|
+
Always show the expected payee and amount in your checkout UI. The payer should
|
|
157
|
+
verify those details in their UPI app before authorizing the transaction.
|
|
158
|
+
|
|
159
|
+
## UPI compatibility
|
|
160
|
+
|
|
161
|
+
UPI app behavior can vary. Test production QR codes with the UPI apps your
|
|
162
|
+
customers use and follow the requirements supplied by your acquiring bank or
|
|
163
|
+
PSP. NPCI's merchant QR interoperability circular identifies `pa` and `pn` as
|
|
164
|
+
critical fields and requires `am` and `tr` for dynamic merchant QRs.
|
|
165
|
+
|
|
166
|
+
- [NPCI UPI overview](https://www.npci.org.in/product/upi)
|
|
167
|
+
- [NPCI merchant QR interoperability circular](https://www.npci.org.in/PDF/npci/upi/circular/2017/Circular18_BankCompliances_to_enbaleUPIMerchantecosystem_0.pdf)
|
|
168
|
+
|
|
169
|
+
## Development
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
npm install
|
|
173
|
+
npm test
|
|
174
|
+
npm run typecheck
|
|
175
|
+
npm run build
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Run the complete verification suite with:
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
npm run check
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
[MIT](LICENSE)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
UPI_PAYMENT_SCHEME: () => UPI_PAYMENT_SCHEME,
|
|
34
|
+
createUpiPaymentUri: () => createUpiPaymentUri,
|
|
35
|
+
generateUpiQrDataUrl: () => generateUpiQrDataUrl,
|
|
36
|
+
generateUpiQrSvg: () => generateUpiQrSvg,
|
|
37
|
+
normalizeUpiAmount: () => normalizeUpiAmount
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(index_exports);
|
|
40
|
+
var import_qrcode = __toESM(require("qrcode"), 1);
|
|
41
|
+
var UPI_PAYMENT_SCHEME = "upi://pay";
|
|
42
|
+
var DEFAULT_QR_OPTIONS = {
|
|
43
|
+
errorCorrectionLevel: "M",
|
|
44
|
+
width: 512,
|
|
45
|
+
margin: 2
|
|
46
|
+
};
|
|
47
|
+
function requiredText(value, field) {
|
|
48
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
49
|
+
throw new TypeError(`${field} is required`);
|
|
50
|
+
}
|
|
51
|
+
return value.trim();
|
|
52
|
+
}
|
|
53
|
+
function optionalText(value, field, maxLength) {
|
|
54
|
+
if (value === void 0) {
|
|
55
|
+
return void 0;
|
|
56
|
+
}
|
|
57
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
58
|
+
throw new TypeError(`${field} must be a non-empty string when provided`);
|
|
59
|
+
}
|
|
60
|
+
const normalized = value.trim();
|
|
61
|
+
if (maxLength !== void 0 && normalized.length > maxLength) {
|
|
62
|
+
throw new RangeError(`${field} must be at most ${maxLength} characters`);
|
|
63
|
+
}
|
|
64
|
+
return normalized;
|
|
65
|
+
}
|
|
66
|
+
function normalizeUpiAmount(value) {
|
|
67
|
+
if (typeof value !== "string" && typeof value !== "number") {
|
|
68
|
+
throw new TypeError("amount must be a string or number");
|
|
69
|
+
}
|
|
70
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
71
|
+
throw new TypeError("amount must be finite");
|
|
72
|
+
}
|
|
73
|
+
const candidate = String(value).trim();
|
|
74
|
+
const match = /^(0|[1-9]\d*)(?:\.(\d{1,2}))?$/.exec(candidate);
|
|
75
|
+
if (!match) {
|
|
76
|
+
throw new TypeError(
|
|
77
|
+
"amount must be a positive decimal with no more than two decimal places"
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
const whole = match[1];
|
|
81
|
+
const fraction = (match[2] ?? "").padEnd(2, "0");
|
|
82
|
+
if (BigInt(whole) === 0n && fraction === "00") {
|
|
83
|
+
throw new RangeError("amount must be greater than zero");
|
|
84
|
+
}
|
|
85
|
+
return `${whole}.${fraction}`;
|
|
86
|
+
}
|
|
87
|
+
function createUpiPaymentUri(options) {
|
|
88
|
+
if (options === null || typeof options !== "object") {
|
|
89
|
+
throw new TypeError("payment options are required");
|
|
90
|
+
}
|
|
91
|
+
const payeeVpa = requiredText(options.payeeVpa, "payeeVpa");
|
|
92
|
+
if (!/^[^\s@]+@[^\s@]+$/.test(payeeVpa)) {
|
|
93
|
+
throw new TypeError("payeeVpa must be a valid UPI virtual payment address");
|
|
94
|
+
}
|
|
95
|
+
const fields = [
|
|
96
|
+
["pa", payeeVpa],
|
|
97
|
+
["pn", requiredText(options.payeeName, "payeeName")],
|
|
98
|
+
["am", normalizeUpiAmount(options.amount)],
|
|
99
|
+
["cu", "INR"],
|
|
100
|
+
["tr", optionalText(options.transactionRef, "transactionRef", 35)],
|
|
101
|
+
["tn", optionalText(options.transactionNote, "transactionNote")],
|
|
102
|
+
["mc", optionalText(options.merchantCode, "merchantCode")]
|
|
103
|
+
];
|
|
104
|
+
const query = fields.filter((field) => field[1] !== void 0).map(
|
|
105
|
+
([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
|
|
106
|
+
).join("&");
|
|
107
|
+
return `${UPI_PAYMENT_SCHEME}?${query}`;
|
|
108
|
+
}
|
|
109
|
+
function generateUpiQrDataUrl(payment, qrOptions = {}) {
|
|
110
|
+
const options = {
|
|
111
|
+
...DEFAULT_QR_OPTIONS,
|
|
112
|
+
...qrOptions,
|
|
113
|
+
type: "image/png"
|
|
114
|
+
};
|
|
115
|
+
return import_qrcode.default.toDataURL(createUpiPaymentUri(payment), options);
|
|
116
|
+
}
|
|
117
|
+
function generateUpiQrSvg(payment, qrOptions = {}) {
|
|
118
|
+
const options = {
|
|
119
|
+
...DEFAULT_QR_OPTIONS,
|
|
120
|
+
...qrOptions,
|
|
121
|
+
type: "svg"
|
|
122
|
+
};
|
|
123
|
+
return import_qrcode.default.toString(createUpiPaymentUri(payment), options);
|
|
124
|
+
}
|
|
125
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
126
|
+
0 && (module.exports = {
|
|
127
|
+
UPI_PAYMENT_SCHEME,
|
|
128
|
+
createUpiPaymentUri,
|
|
129
|
+
generateUpiQrDataUrl,
|
|
130
|
+
generateUpiQrSvg,
|
|
131
|
+
normalizeUpiAmount
|
|
132
|
+
});
|
|
133
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import QRCode from \"qrcode\";\nimport type {\n QRCodeErrorCorrectionLevel,\n QRCodeToDataURLOptions,\n QRCodeToStringOptions,\n} from \"qrcode\";\n\n/** Details encoded in a UPI payment QR code. */\nexport interface UpiPaymentOptions {\n /** Payee virtual payment address, for example `merchant@bank`. */\n payeeVpa: string;\n /** Name displayed by the payer's UPI app. */\n payeeName: string;\n /** Positive INR amount with no more than two decimal places. Prefer a string. */\n amount: string | number;\n /** Merchant transaction reference. Dynamic merchant QRs should include this. */\n transactionRef?: string;\n /** Note displayed with the payment. */\n transactionNote?: string;\n /** Merchant category code, when supplied by the acquiring bank or PSP. */\n merchantCode?: string;\n}\n\n/** Rendering controls shared by the PNG data URL and SVG generators. */\nexport interface UpiQrOptions {\n /** Error-correction level. Defaults to `M`. */\n errorCorrectionLevel?: QRCodeErrorCorrectionLevel;\n /** Width in pixels. Defaults to 512. */\n width?: number;\n /** Quiet-zone width in QR modules. Defaults to 2. */\n margin?: number;\n /** Pixels per module when width is not supplied. */\n scale?: number;\n /** Dark and light colors as hexadecimal RGBA strings. */\n color?: {\n dark?: string;\n light?: string;\n };\n}\n\nexport const UPI_PAYMENT_SCHEME = \"upi://pay\" as const;\n\nconst DEFAULT_QR_OPTIONS = {\n errorCorrectionLevel: \"M\",\n width: 512,\n margin: 2,\n} as const;\n\nfunction requiredText(value: string, field: string): string {\n if (typeof value !== \"string\" || value.trim() === \"\") {\n throw new TypeError(`${field} is required`);\n }\n\n return value.trim();\n}\n\nfunction optionalText(\n value: string | undefined,\n field: string,\n maxLength?: number,\n): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value !== \"string\" || value.trim() === \"\") {\n throw new TypeError(`${field} must be a non-empty string when provided`);\n }\n\n const normalized = value.trim();\n if (maxLength !== undefined && normalized.length > maxLength) {\n throw new RangeError(`${field} must be at most ${maxLength} characters`);\n }\n\n return normalized;\n}\n\n/**\n * Normalize an INR amount without silently rounding it.\n *\n * Decimal strings are recommended so callers do not introduce floating-point\n * rounding before the value reaches this function.\n */\nexport function normalizeUpiAmount(value: string | number): string {\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n throw new TypeError(\"amount must be a string or number\");\n }\n\n if (typeof value === \"number\" && !Number.isFinite(value)) {\n throw new TypeError(\"amount must be finite\");\n }\n\n const candidate = String(value).trim();\n const match = /^(0|[1-9]\\d*)(?:\\.(\\d{1,2}))?$/.exec(candidate);\n\n if (!match) {\n throw new TypeError(\n \"amount must be a positive decimal with no more than two decimal places\",\n );\n }\n\n const whole = match[1];\n const fraction = (match[2] ?? \"\").padEnd(2, \"0\");\n\n if (BigInt(whole) === 0n && fraction === \"00\") {\n throw new RangeError(\"amount must be greater than zero\");\n }\n\n return `${whole}.${fraction}`;\n}\n\n/** Create the `upi://pay` URI that is encoded into the QR code. */\nexport function createUpiPaymentUri(options: UpiPaymentOptions): string {\n if (options === null || typeof options !== \"object\") {\n throw new TypeError(\"payment options are required\");\n }\n\n const payeeVpa = requiredText(options.payeeVpa, \"payeeVpa\");\n if (!/^[^\\s@]+@[^\\s@]+$/.test(payeeVpa)) {\n throw new TypeError(\"payeeVpa must be a valid UPI virtual payment address\");\n }\n\n const fields: Array<[string, string | undefined]> = [\n [\"pa\", payeeVpa],\n [\"pn\", requiredText(options.payeeName, \"payeeName\")],\n [\"am\", normalizeUpiAmount(options.amount)],\n [\"cu\", \"INR\"],\n [\"tr\", optionalText(options.transactionRef, \"transactionRef\", 35)],\n [\"tn\", optionalText(options.transactionNote, \"transactionNote\")],\n [\"mc\", optionalText(options.merchantCode, \"merchantCode\")],\n ];\n\n const query = fields\n .filter((field): field is [string, string] => field[1] !== undefined)\n .map(\n ([key, value]) =>\n `${encodeURIComponent(key)}=${encodeURIComponent(value)}`,\n )\n .join(\"&\");\n\n return `${UPI_PAYMENT_SCHEME}?${query}`;\n}\n\n/** Generate a PNG QR code as a data URL. Works in Node.js and browser bundlers. */\nexport function generateUpiQrDataUrl(\n payment: UpiPaymentOptions,\n qrOptions: UpiQrOptions = {},\n): Promise<string> {\n const options: QRCodeToDataURLOptions = {\n ...DEFAULT_QR_OPTIONS,\n ...qrOptions,\n type: \"image/png\",\n };\n\n return QRCode.toDataURL(createUpiPaymentUri(payment), options);\n}\n\n/** Generate a QR code as an SVG string. */\nexport function generateUpiQrSvg(\n payment: UpiPaymentOptions,\n qrOptions: UpiQrOptions = {},\n): Promise<string> {\n const options: QRCodeToStringOptions = {\n ...DEFAULT_QR_OPTIONS,\n ...qrOptions,\n type: \"svg\",\n };\n\n return QRCode.toString(createUpiPaymentUri(payment), options);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAmB;AAwCZ,IAAM,qBAAqB;AAElC,IAAM,qBAAqB;AAAA,EACzB,sBAAsB;AAAA,EACtB,OAAO;AAAA,EACP,QAAQ;AACV;AAEA,SAAS,aAAa,OAAe,OAAuB;AAC1D,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,UAAM,IAAI,UAAU,GAAG,KAAK,cAAc;AAAA,EAC5C;AAEA,SAAO,MAAM,KAAK;AACpB;AAEA,SAAS,aACP,OACA,OACA,WACoB;AACpB,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,UAAM,IAAI,UAAU,GAAG,KAAK,2CAA2C;AAAA,EACzE;AAEA,QAAM,aAAa,MAAM,KAAK;AAC9B,MAAI,cAAc,UAAa,WAAW,SAAS,WAAW;AAC5D,UAAM,IAAI,WAAW,GAAG,KAAK,oBAAoB,SAAS,aAAa;AAAA,EACzE;AAEA,SAAO;AACT;AAQO,SAAS,mBAAmB,OAAgC;AACjE,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,UAAM,IAAI,UAAU,mCAAmC;AAAA,EACzD;AAEA,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,UAAM,IAAI,UAAU,uBAAuB;AAAA,EAC7C;AAEA,QAAM,YAAY,OAAO,KAAK,EAAE,KAAK;AACrC,QAAM,QAAQ,iCAAiC,KAAK,SAAS;AAE7D,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,CAAC;AACrB,QAAM,YAAY,MAAM,CAAC,KAAK,IAAI,OAAO,GAAG,GAAG;AAE/C,MAAI,OAAO,KAAK,MAAM,MAAM,aAAa,MAAM;AAC7C,UAAM,IAAI,WAAW,kCAAkC;AAAA,EACzD;AAEA,SAAO,GAAG,KAAK,IAAI,QAAQ;AAC7B;AAGO,SAAS,oBAAoB,SAAoC;AACtE,MAAI,YAAY,QAAQ,OAAO,YAAY,UAAU;AACnD,UAAM,IAAI,UAAU,8BAA8B;AAAA,EACpD;AAEA,QAAM,WAAW,aAAa,QAAQ,UAAU,UAAU;AAC1D,MAAI,CAAC,oBAAoB,KAAK,QAAQ,GAAG;AACvC,UAAM,IAAI,UAAU,sDAAsD;AAAA,EAC5E;AAEA,QAAM,SAA8C;AAAA,IAClD,CAAC,MAAM,QAAQ;AAAA,IACf,CAAC,MAAM,aAAa,QAAQ,WAAW,WAAW,CAAC;AAAA,IACnD,CAAC,MAAM,mBAAmB,QAAQ,MAAM,CAAC;AAAA,IACzC,CAAC,MAAM,KAAK;AAAA,IACZ,CAAC,MAAM,aAAa,QAAQ,gBAAgB,kBAAkB,EAAE,CAAC;AAAA,IACjE,CAAC,MAAM,aAAa,QAAQ,iBAAiB,iBAAiB,CAAC;AAAA,IAC/D,CAAC,MAAM,aAAa,QAAQ,cAAc,cAAc,CAAC;AAAA,EAC3D;AAEA,QAAM,QAAQ,OACX,OAAO,CAAC,UAAqC,MAAM,CAAC,MAAM,MAAS,EACnE;AAAA,IACC,CAAC,CAAC,KAAK,KAAK,MACV,GAAG,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,KAAK,CAAC;AAAA,EAC3D,EACC,KAAK,GAAG;AAEX,SAAO,GAAG,kBAAkB,IAAI,KAAK;AACvC;AAGO,SAAS,qBACd,SACA,YAA0B,CAAC,GACV;AACjB,QAAM,UAAkC;AAAA,IACtC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,MAAM;AAAA,EACR;AAEA,SAAO,cAAAA,QAAO,UAAU,oBAAoB,OAAO,GAAG,OAAO;AAC/D;AAGO,SAAS,iBACd,SACA,YAA0B,CAAC,GACV;AACjB,QAAM,UAAiC;AAAA,IACrC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,MAAM;AAAA,EACR;AAEA,SAAO,cAAAA,QAAO,SAAS,oBAAoB,OAAO,GAAG,OAAO;AAC9D;","names":["QRCode"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { QRCodeErrorCorrectionLevel } from 'qrcode';
|
|
2
|
+
|
|
3
|
+
/** Details encoded in a UPI payment QR code. */
|
|
4
|
+
interface UpiPaymentOptions {
|
|
5
|
+
/** Payee virtual payment address, for example `merchant@bank`. */
|
|
6
|
+
payeeVpa: string;
|
|
7
|
+
/** Name displayed by the payer's UPI app. */
|
|
8
|
+
payeeName: string;
|
|
9
|
+
/** Positive INR amount with no more than two decimal places. Prefer a string. */
|
|
10
|
+
amount: string | number;
|
|
11
|
+
/** Merchant transaction reference. Dynamic merchant QRs should include this. */
|
|
12
|
+
transactionRef?: string;
|
|
13
|
+
/** Note displayed with the payment. */
|
|
14
|
+
transactionNote?: string;
|
|
15
|
+
/** Merchant category code, when supplied by the acquiring bank or PSP. */
|
|
16
|
+
merchantCode?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Rendering controls shared by the PNG data URL and SVG generators. */
|
|
19
|
+
interface UpiQrOptions {
|
|
20
|
+
/** Error-correction level. Defaults to `M`. */
|
|
21
|
+
errorCorrectionLevel?: QRCodeErrorCorrectionLevel;
|
|
22
|
+
/** Width in pixels. Defaults to 512. */
|
|
23
|
+
width?: number;
|
|
24
|
+
/** Quiet-zone width in QR modules. Defaults to 2. */
|
|
25
|
+
margin?: number;
|
|
26
|
+
/** Pixels per module when width is not supplied. */
|
|
27
|
+
scale?: number;
|
|
28
|
+
/** Dark and light colors as hexadecimal RGBA strings. */
|
|
29
|
+
color?: {
|
|
30
|
+
dark?: string;
|
|
31
|
+
light?: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
declare const UPI_PAYMENT_SCHEME: "upi://pay";
|
|
35
|
+
/**
|
|
36
|
+
* Normalize an INR amount without silently rounding it.
|
|
37
|
+
*
|
|
38
|
+
* Decimal strings are recommended so callers do not introduce floating-point
|
|
39
|
+
* rounding before the value reaches this function.
|
|
40
|
+
*/
|
|
41
|
+
declare function normalizeUpiAmount(value: string | number): string;
|
|
42
|
+
/** Create the `upi://pay` URI that is encoded into the QR code. */
|
|
43
|
+
declare function createUpiPaymentUri(options: UpiPaymentOptions): string;
|
|
44
|
+
/** Generate a PNG QR code as a data URL. Works in Node.js and browser bundlers. */
|
|
45
|
+
declare function generateUpiQrDataUrl(payment: UpiPaymentOptions, qrOptions?: UpiQrOptions): Promise<string>;
|
|
46
|
+
/** Generate a QR code as an SVG string. */
|
|
47
|
+
declare function generateUpiQrSvg(payment: UpiPaymentOptions, qrOptions?: UpiQrOptions): Promise<string>;
|
|
48
|
+
|
|
49
|
+
export { UPI_PAYMENT_SCHEME, type UpiPaymentOptions, type UpiQrOptions, createUpiPaymentUri, generateUpiQrDataUrl, generateUpiQrSvg, normalizeUpiAmount };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { QRCodeErrorCorrectionLevel } from 'qrcode';
|
|
2
|
+
|
|
3
|
+
/** Details encoded in a UPI payment QR code. */
|
|
4
|
+
interface UpiPaymentOptions {
|
|
5
|
+
/** Payee virtual payment address, for example `merchant@bank`. */
|
|
6
|
+
payeeVpa: string;
|
|
7
|
+
/** Name displayed by the payer's UPI app. */
|
|
8
|
+
payeeName: string;
|
|
9
|
+
/** Positive INR amount with no more than two decimal places. Prefer a string. */
|
|
10
|
+
amount: string | number;
|
|
11
|
+
/** Merchant transaction reference. Dynamic merchant QRs should include this. */
|
|
12
|
+
transactionRef?: string;
|
|
13
|
+
/** Note displayed with the payment. */
|
|
14
|
+
transactionNote?: string;
|
|
15
|
+
/** Merchant category code, when supplied by the acquiring bank or PSP. */
|
|
16
|
+
merchantCode?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Rendering controls shared by the PNG data URL and SVG generators. */
|
|
19
|
+
interface UpiQrOptions {
|
|
20
|
+
/** Error-correction level. Defaults to `M`. */
|
|
21
|
+
errorCorrectionLevel?: QRCodeErrorCorrectionLevel;
|
|
22
|
+
/** Width in pixels. Defaults to 512. */
|
|
23
|
+
width?: number;
|
|
24
|
+
/** Quiet-zone width in QR modules. Defaults to 2. */
|
|
25
|
+
margin?: number;
|
|
26
|
+
/** Pixels per module when width is not supplied. */
|
|
27
|
+
scale?: number;
|
|
28
|
+
/** Dark and light colors as hexadecimal RGBA strings. */
|
|
29
|
+
color?: {
|
|
30
|
+
dark?: string;
|
|
31
|
+
light?: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
declare const UPI_PAYMENT_SCHEME: "upi://pay";
|
|
35
|
+
/**
|
|
36
|
+
* Normalize an INR amount without silently rounding it.
|
|
37
|
+
*
|
|
38
|
+
* Decimal strings are recommended so callers do not introduce floating-point
|
|
39
|
+
* rounding before the value reaches this function.
|
|
40
|
+
*/
|
|
41
|
+
declare function normalizeUpiAmount(value: string | number): string;
|
|
42
|
+
/** Create the `upi://pay` URI that is encoded into the QR code. */
|
|
43
|
+
declare function createUpiPaymentUri(options: UpiPaymentOptions): string;
|
|
44
|
+
/** Generate a PNG QR code as a data URL. Works in Node.js and browser bundlers. */
|
|
45
|
+
declare function generateUpiQrDataUrl(payment: UpiPaymentOptions, qrOptions?: UpiQrOptions): Promise<string>;
|
|
46
|
+
/** Generate a QR code as an SVG string. */
|
|
47
|
+
declare function generateUpiQrSvg(payment: UpiPaymentOptions, qrOptions?: UpiQrOptions): Promise<string>;
|
|
48
|
+
|
|
49
|
+
export { UPI_PAYMENT_SCHEME, type UpiPaymentOptions, type UpiQrOptions, createUpiPaymentUri, generateUpiQrDataUrl, generateUpiQrSvg, normalizeUpiAmount };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import QRCode from "qrcode";
|
|
3
|
+
var UPI_PAYMENT_SCHEME = "upi://pay";
|
|
4
|
+
var DEFAULT_QR_OPTIONS = {
|
|
5
|
+
errorCorrectionLevel: "M",
|
|
6
|
+
width: 512,
|
|
7
|
+
margin: 2
|
|
8
|
+
};
|
|
9
|
+
function requiredText(value, field) {
|
|
10
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
11
|
+
throw new TypeError(`${field} is required`);
|
|
12
|
+
}
|
|
13
|
+
return value.trim();
|
|
14
|
+
}
|
|
15
|
+
function optionalText(value, field, maxLength) {
|
|
16
|
+
if (value === void 0) {
|
|
17
|
+
return void 0;
|
|
18
|
+
}
|
|
19
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
20
|
+
throw new TypeError(`${field} must be a non-empty string when provided`);
|
|
21
|
+
}
|
|
22
|
+
const normalized = value.trim();
|
|
23
|
+
if (maxLength !== void 0 && normalized.length > maxLength) {
|
|
24
|
+
throw new RangeError(`${field} must be at most ${maxLength} characters`);
|
|
25
|
+
}
|
|
26
|
+
return normalized;
|
|
27
|
+
}
|
|
28
|
+
function normalizeUpiAmount(value) {
|
|
29
|
+
if (typeof value !== "string" && typeof value !== "number") {
|
|
30
|
+
throw new TypeError("amount must be a string or number");
|
|
31
|
+
}
|
|
32
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
33
|
+
throw new TypeError("amount must be finite");
|
|
34
|
+
}
|
|
35
|
+
const candidate = String(value).trim();
|
|
36
|
+
const match = /^(0|[1-9]\d*)(?:\.(\d{1,2}))?$/.exec(candidate);
|
|
37
|
+
if (!match) {
|
|
38
|
+
throw new TypeError(
|
|
39
|
+
"amount must be a positive decimal with no more than two decimal places"
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
const whole = match[1];
|
|
43
|
+
const fraction = (match[2] ?? "").padEnd(2, "0");
|
|
44
|
+
if (BigInt(whole) === 0n && fraction === "00") {
|
|
45
|
+
throw new RangeError("amount must be greater than zero");
|
|
46
|
+
}
|
|
47
|
+
return `${whole}.${fraction}`;
|
|
48
|
+
}
|
|
49
|
+
function createUpiPaymentUri(options) {
|
|
50
|
+
if (options === null || typeof options !== "object") {
|
|
51
|
+
throw new TypeError("payment options are required");
|
|
52
|
+
}
|
|
53
|
+
const payeeVpa = requiredText(options.payeeVpa, "payeeVpa");
|
|
54
|
+
if (!/^[^\s@]+@[^\s@]+$/.test(payeeVpa)) {
|
|
55
|
+
throw new TypeError("payeeVpa must be a valid UPI virtual payment address");
|
|
56
|
+
}
|
|
57
|
+
const fields = [
|
|
58
|
+
["pa", payeeVpa],
|
|
59
|
+
["pn", requiredText(options.payeeName, "payeeName")],
|
|
60
|
+
["am", normalizeUpiAmount(options.amount)],
|
|
61
|
+
["cu", "INR"],
|
|
62
|
+
["tr", optionalText(options.transactionRef, "transactionRef", 35)],
|
|
63
|
+
["tn", optionalText(options.transactionNote, "transactionNote")],
|
|
64
|
+
["mc", optionalText(options.merchantCode, "merchantCode")]
|
|
65
|
+
];
|
|
66
|
+
const query = fields.filter((field) => field[1] !== void 0).map(
|
|
67
|
+
([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
|
|
68
|
+
).join("&");
|
|
69
|
+
return `${UPI_PAYMENT_SCHEME}?${query}`;
|
|
70
|
+
}
|
|
71
|
+
function generateUpiQrDataUrl(payment, qrOptions = {}) {
|
|
72
|
+
const options = {
|
|
73
|
+
...DEFAULT_QR_OPTIONS,
|
|
74
|
+
...qrOptions,
|
|
75
|
+
type: "image/png"
|
|
76
|
+
};
|
|
77
|
+
return QRCode.toDataURL(createUpiPaymentUri(payment), options);
|
|
78
|
+
}
|
|
79
|
+
function generateUpiQrSvg(payment, qrOptions = {}) {
|
|
80
|
+
const options = {
|
|
81
|
+
...DEFAULT_QR_OPTIONS,
|
|
82
|
+
...qrOptions,
|
|
83
|
+
type: "svg"
|
|
84
|
+
};
|
|
85
|
+
return QRCode.toString(createUpiPaymentUri(payment), options);
|
|
86
|
+
}
|
|
87
|
+
export {
|
|
88
|
+
UPI_PAYMENT_SCHEME,
|
|
89
|
+
createUpiPaymentUri,
|
|
90
|
+
generateUpiQrDataUrl,
|
|
91
|
+
generateUpiQrSvg,
|
|
92
|
+
normalizeUpiAmount
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import QRCode from \"qrcode\";\nimport type {\n QRCodeErrorCorrectionLevel,\n QRCodeToDataURLOptions,\n QRCodeToStringOptions,\n} from \"qrcode\";\n\n/** Details encoded in a UPI payment QR code. */\nexport interface UpiPaymentOptions {\n /** Payee virtual payment address, for example `merchant@bank`. */\n payeeVpa: string;\n /** Name displayed by the payer's UPI app. */\n payeeName: string;\n /** Positive INR amount with no more than two decimal places. Prefer a string. */\n amount: string | number;\n /** Merchant transaction reference. Dynamic merchant QRs should include this. */\n transactionRef?: string;\n /** Note displayed with the payment. */\n transactionNote?: string;\n /** Merchant category code, when supplied by the acquiring bank or PSP. */\n merchantCode?: string;\n}\n\n/** Rendering controls shared by the PNG data URL and SVG generators. */\nexport interface UpiQrOptions {\n /** Error-correction level. Defaults to `M`. */\n errorCorrectionLevel?: QRCodeErrorCorrectionLevel;\n /** Width in pixels. Defaults to 512. */\n width?: number;\n /** Quiet-zone width in QR modules. Defaults to 2. */\n margin?: number;\n /** Pixels per module when width is not supplied. */\n scale?: number;\n /** Dark and light colors as hexadecimal RGBA strings. */\n color?: {\n dark?: string;\n light?: string;\n };\n}\n\nexport const UPI_PAYMENT_SCHEME = \"upi://pay\" as const;\n\nconst DEFAULT_QR_OPTIONS = {\n errorCorrectionLevel: \"M\",\n width: 512,\n margin: 2,\n} as const;\n\nfunction requiredText(value: string, field: string): string {\n if (typeof value !== \"string\" || value.trim() === \"\") {\n throw new TypeError(`${field} is required`);\n }\n\n return value.trim();\n}\n\nfunction optionalText(\n value: string | undefined,\n field: string,\n maxLength?: number,\n): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value !== \"string\" || value.trim() === \"\") {\n throw new TypeError(`${field} must be a non-empty string when provided`);\n }\n\n const normalized = value.trim();\n if (maxLength !== undefined && normalized.length > maxLength) {\n throw new RangeError(`${field} must be at most ${maxLength} characters`);\n }\n\n return normalized;\n}\n\n/**\n * Normalize an INR amount without silently rounding it.\n *\n * Decimal strings are recommended so callers do not introduce floating-point\n * rounding before the value reaches this function.\n */\nexport function normalizeUpiAmount(value: string | number): string {\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n throw new TypeError(\"amount must be a string or number\");\n }\n\n if (typeof value === \"number\" && !Number.isFinite(value)) {\n throw new TypeError(\"amount must be finite\");\n }\n\n const candidate = String(value).trim();\n const match = /^(0|[1-9]\\d*)(?:\\.(\\d{1,2}))?$/.exec(candidate);\n\n if (!match) {\n throw new TypeError(\n \"amount must be a positive decimal with no more than two decimal places\",\n );\n }\n\n const whole = match[1];\n const fraction = (match[2] ?? \"\").padEnd(2, \"0\");\n\n if (BigInt(whole) === 0n && fraction === \"00\") {\n throw new RangeError(\"amount must be greater than zero\");\n }\n\n return `${whole}.${fraction}`;\n}\n\n/** Create the `upi://pay` URI that is encoded into the QR code. */\nexport function createUpiPaymentUri(options: UpiPaymentOptions): string {\n if (options === null || typeof options !== \"object\") {\n throw new TypeError(\"payment options are required\");\n }\n\n const payeeVpa = requiredText(options.payeeVpa, \"payeeVpa\");\n if (!/^[^\\s@]+@[^\\s@]+$/.test(payeeVpa)) {\n throw new TypeError(\"payeeVpa must be a valid UPI virtual payment address\");\n }\n\n const fields: Array<[string, string | undefined]> = [\n [\"pa\", payeeVpa],\n [\"pn\", requiredText(options.payeeName, \"payeeName\")],\n [\"am\", normalizeUpiAmount(options.amount)],\n [\"cu\", \"INR\"],\n [\"tr\", optionalText(options.transactionRef, \"transactionRef\", 35)],\n [\"tn\", optionalText(options.transactionNote, \"transactionNote\")],\n [\"mc\", optionalText(options.merchantCode, \"merchantCode\")],\n ];\n\n const query = fields\n .filter((field): field is [string, string] => field[1] !== undefined)\n .map(\n ([key, value]) =>\n `${encodeURIComponent(key)}=${encodeURIComponent(value)}`,\n )\n .join(\"&\");\n\n return `${UPI_PAYMENT_SCHEME}?${query}`;\n}\n\n/** Generate a PNG QR code as a data URL. Works in Node.js and browser bundlers. */\nexport function generateUpiQrDataUrl(\n payment: UpiPaymentOptions,\n qrOptions: UpiQrOptions = {},\n): Promise<string> {\n const options: QRCodeToDataURLOptions = {\n ...DEFAULT_QR_OPTIONS,\n ...qrOptions,\n type: \"image/png\",\n };\n\n return QRCode.toDataURL(createUpiPaymentUri(payment), options);\n}\n\n/** Generate a QR code as an SVG string. */\nexport function generateUpiQrSvg(\n payment: UpiPaymentOptions,\n qrOptions: UpiQrOptions = {},\n): Promise<string> {\n const options: QRCodeToStringOptions = {\n ...DEFAULT_QR_OPTIONS,\n ...qrOptions,\n type: \"svg\",\n };\n\n return QRCode.toString(createUpiPaymentUri(payment), options);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "upi-qr-code-generator",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Generate UPI payment URIs and QR codes with a pre-filled amount in Node.js and browsers.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"upi",
|
|
7
|
+
"qr-code",
|
|
8
|
+
"payments",
|
|
9
|
+
"india",
|
|
10
|
+
"javascript",
|
|
11
|
+
"typescript"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "techpool",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
17
|
+
"module": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"require": "./dist/index.cjs"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"sideEffects": false,
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/techpool/upi-qr-code-generator.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/techpool/upi-qr-code-generator/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/techpool/upi-qr-code-generator#readme",
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsup",
|
|
45
|
+
"check": "npm run typecheck && npm test && npm run build",
|
|
46
|
+
"prepare": "npm run build",
|
|
47
|
+
"test": "vitest run",
|
|
48
|
+
"test:watch": "vitest",
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"prepublishOnly": "npm run check"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"qrcode": "^1.5.4"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^24.0.0",
|
|
57
|
+
"@types/qrcode": "^1.5.6",
|
|
58
|
+
"tsup": "^8.5.1",
|
|
59
|
+
"typescript": "^5.9.3",
|
|
60
|
+
"vitest": "^5.0.0"
|
|
61
|
+
},
|
|
62
|
+
"overrides": {
|
|
63
|
+
"esbuild": "^0.28.2"
|
|
64
|
+
}
|
|
65
|
+
}
|