npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vouch.finance/sdk

v0.2.2

Published

TypeScript SDK for the Vouch Purpose-Bound Voucher platform — UPI QR redemption, payments, open-network merchant support

Readme

@vouch.finance/sdk

TypeScript SDK for the Vouch Purpose-Bound Voucher platform. Supports UPI QR voucher redemption, payment intents, voucher balance checks, and verification.

Two entry points:

  • @vouch.finance/sdk — core client, UPI parsing, framework-agnostic scanner
  • @vouch.finance/sdk/react — React QR scanner component

Install

npm install @vouch.finance/sdk

If using the QR scanner, also install the optional peer dependencies:

# React apps using <QRScanner />
npm install react react-dom html5-qrcode

# Non-React apps using UPIScanner
npm install html5-qrcode

CDN (no bundler):

<script src="https://cdn.jsdelivr.net/npm/@vouch.finance/sdk/dist/index.global.js"></script>
<script>
  const vouch = new Vouch.Vouch({
    apiKey: "your-key",
    baseUrl: "https://api.your-domain.com/api/v1",
  });
</script>

Configuration

Always set baseUrl explicitly in production. The SDK only falls back to a local dev default when omitted.

| Source | Used by | Example | | --- | --- | --- | | VouchConfig.baseUrl | All runtimes | https://sandbox.lk.vouch.finance/api/v1 | | VOUCH_BASE_URL env | Node.js / tests | http://localhost:9393/api/v1 | | DEFAULT_DEV_BASE_URL | Dev fallback only | http://localhost:9393/api/v1 |

import { Vouch, DEFAULT_DEV_BASE_URL } from "@vouch.finance/sdk";

const vouch = new Vouch({
  apiKey: process.env.VOUCH_API_KEY!,
  baseUrl: process.env.VOUCH_BASE_URL ?? DEFAULT_DEV_BASE_URL,
  showVoucherOnlyWithBalance: true, // optional: gate UI on spendable balance
});

Browser apps (Vite / React)

Avoid CORS and hardcoded hosts by proxying /api to your backend and using a relative SDK base URL:

# .env.local
VITE_BACKEND_URL=http://localhost:9393
VITE_VOUCH_BASE_URL=/api/v1
VITE_VOUCH_API_KEY=sk_test_...

See examples/partner-test-ui/ for a full working setup.

E2E tests

cd sdk
VOUCH_API_KEY=sk_test_... \
VOUCH_BASE_URL=http://localhost:9393/api/v1 \
VOUCH_PROGRAM_ID=cmpo31oud0000vzmopcrfb9kx \
VOUCH_BENEFICIARY_PHONE=9953531809 \
npm run test:e2e

Quick Start

import { Vouch } from "@vouch.finance/sdk";

const vouch = new Vouch({
  apiKey: "sk_test_...",
  baseUrl: "https://api.your-domain.com/api/v1",
});

Voucher balance gate (partner apps)

Before showing voucher UI, check whether the beneficiary has spendable balance:

const balance = await vouch.vouchers.getBalance({
  beneficiaryPhone: "9953531809",
  programId: "cmpo31oud0000vzmopcrfb9kx",
});

// balance.hasVoucher, balance.hasBalance, balance.remainingBalanceMinor, balance.tokenId

const showUi = await vouch.vouchers.shouldShowUI({
  beneficiaryPhone: "9953531809",
  programId: "cmpo31oud0000vzmopcrfb9kx",
});
// true only when showVoucherOnlyWithBalance is set and hasBalance is true

UPI Voucher Payment Flow

The primary integration for partners building beneficiary-facing apps. The partner identifies the beneficiary by phone number, scans a merchant UPI QR, and completes payment using the voucher.

Step 1 — Scan merchant UPI QR

import { parseUPIScheme } from "@vouch.finance/sdk";

const upi = parseUPIScheme("upi://pay?pa=pharmacy@upi&pn=City+Pharmacy&am=250.00");
if (!upi) throw new Error("Not a valid UPI QR");

// upi = {
//   type: "upi",
//   upiId: "pharmacy@upi",
//   merchantName: "City Pharmacy",
//   amount: "250.00",
//   mcc: "5912",
//   raw: "upi://pay?..."
// }

Or use the scanner components (see QR Scanner section below).

Step 2 — Create intent and get quote

const intent = await vouch.payments.initiateUPI({
  upiData: upi,
  beneficiaryPhone: "+919876543210",
  programId: "cmpo31oud0000vzmopcrfb9kx",
});

Step 3 — Show payment review

Display the quote to the beneficiary. Proceed only if status === "QUOTED" and eligibleAmount > 0.

Step 4 — Authorize payment

const auth = await vouch.payments.authorize({ intentId: intent.intentId });

Step 5 — Poll for settlement

const status = await vouch.payments.getIntent(intent.intentId);
// status.status — "AUTHORIZED" | "SETTLED" | "FAILED"

Open-Network UPI (Unregistered Merchants)

Payments work to any UPI merchant — registered or not. Unregistered merchants return merchantResolution: "open_network" and settle via fiat UPI (settlementRail: "fiat").

const intent = await vouch.payments.initiateUPI({
  upiData: upi,
  beneficiaryPhone: "+919876543210",
  programId: "cmpo31oud0000vzmopcrfb9kx",
});

if (intent.merchantResolution === "open_network") {
  console.log("Paying via UPI to:", intent.upiId);
}

QR Scanner

React

import { QRScanner } from "@vouch.finance/sdk/react";

<QRScanner
  onScan={(upi) => console.log(upi.upiId, upi.amount)}
  onError={(err) => console.error(err)}
  onClose={() => setOpen(false)}
  width={320}
  height={320}
/>

Vanilla JS (any framework)

import { UPIScanner } from "@vouch.finance/sdk";

const scanner = new UPIScanner({
  container: "#scanner",
  onScan: (upi) => console.log(upi.upiId),
  onError: (err) => console.error(err),
});

await scanner.start();

API Reference

Client

new Vouch({
  apiKey,
  baseUrl?,                      // required in production
  version?,                      // default "2026-04-06"
  showVoucherOnlyWithBalance?,   // default false
})

All requests include x-api-key and Vouch-Version headers.

Programs

| Method | Return | |--------|--------| | vouch.programs.list() | { programs: Program[] } | | vouch.programs.get(slug) | { program: Program } | | vouch.programs.create(params) | { data: { program }, meta } | | vouch.programs.stats(slug) | { data: { stats }, meta } | | vouch.programs.enrol(slug, { phone, fields? }) | { data, meta } |

Payments

| Method | Return | |--------|--------| | vouch.payments.initiateUPI({ upiData, programId, beneficiaryPhone?, beneficiaryId?, tokenId? }) | UPIIntentResponse | | vouch.payments.createIntent({ merchantId, items, programId? }) | { data: PaymentIntent, meta } | | vouch.payments.quote({ intentId, tokenId }) | { data, meta } | | vouch.payments.authorize({ intentId }) | AuthorizeResponse | | vouch.payments.getIntent(intentId) | IntentStatusResponse |

Vouchers & Merchants

| Method | Return | |--------|--------| | vouch.vouchers.verify(token, programId?) | { data: Voucher, meta } | | vouch.vouchers.getBalance({ beneficiaryPhone, programId }) | VoucherBalanceStatus | | vouch.vouchers.shouldShowUI({ beneficiaryPhone, programId }) | boolean | | vouch.merchants.list(programId?) | { data: Merchant[], meta, pagination } |

Constants

| Export | Description | |--------|-------------| | DEFAULT_DEV_BASE_URL | http://localhost:9393/api/v1 — local dev fallback | | DEFAULT_DEV_BACKEND_ORIGIN | http://localhost:9393 — for Vite proxy config | | resolveBaseUrl(explicit?) | Config → VOUCH_BASE_URL → dev default |

Types

| Type | Description | |------|-------------| | VouchConfig | apiKey, baseUrl?, version?, showVoucherOnlyWithBalance? | | VoucherBalanceStatus | Response from getBalancehasVoucher, hasBalance, remainingBalanceMinor, tokenId, currency, etc. | | UPIData | Parsed UPI QR (upiId, merchantName?, amount?, mcc?) | | UPIIntentResponse | Response from initiateUPI | | AuthorizeResponse | Response from authorize | | IntentStatusResponse | Response from getIntent | | VouchError | code, statusCode, requestId, message |

Error Handling

import { VouchError } from "@vouch.finance/sdk";

try {
  await vouch.payments.authorize({ intentId: "bad" });
} catch (err) {
  if (err instanceof VouchError) {
    console.log(err.code, err.statusCode, err.requestId, err.message);
  }
}

Examples

| App | Port | Description | | --- | --- | --- | | examples/partner-test-ui/ | 5182 | Dvara flow: balance gate + UPI scan (recommended) | | examples/react-app/ | 5180 | Minimal React + <QRScanner /> | | examples/vanilla/ | — | CDN HTML, no build step |

cd sdk && npm run build

# Partner test UI
cd examples/partner-test-ui
cp .env.local.example .env.local
npm install && npm run dev

# React example
cd examples/react-app
cp .env.local.example .env.local
npm install && npm run dev

Publishing

cd sdk
npm install
npm run build
NPM_TOKEN=... ./scripts/publish.sh

Build outputs: dist/index.js (CJS), dist/index.mjs (ESM), dist/index.global.js (IIFE/CDN), dist/react/ (React entry).