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

pay-helper

v1.0.10

Published

A lightweight utility for parsing payment payloads, generating deep links, and verifying settlements.

Readme

pay-helper

A lightweight, standards-compliant library for generating dynamic EMVCo QR payment payloads, mobile banking deep links, and verifying transaction settlements across platforms.

npm version npm downloads license bundle size platforms


📖 Overview

pay-helper provides clean, reliable utilities for modern digital payment integration in Cambodia. Designed for simplicity and resilience, it operates completely standalone with zero external dependencies for its core generation and verification routines.

💡 Flexible Architecture (Standard Checkout Link or Official Bakong Open API):
pay-helper supports both operational models:

  1. Zero-Friction Link Mode: Works directly using a single standard ABA PayWay checkout link (https://link.payway.com.kh/...) without requiring private bank API keys or developer credentials.
  2. Official Bakong Mode: Supports official NBC Bakong Open API Bearer Tokens (createBakongChecker) and multi-provider failover (createDualFailoverChecker) for enterprise setups.
    Because ABA PayWay checkout links are connected to NBC Bakong on the national payment switch, generated dynamic KHQR payloads function across ABA Mobile, NBC Bakong, and supported Cambodian banking apps.

💡 Real-Time Telegram Inbound Alert Listener via MTProto:
Standard Telegram bots created with @BotFather cannot read messages sent by other bots in groups due to Telegram's platform policy.
pay-helper provides a passive, inbound-only Telegram MTProto User Client (TelegramMtprotoListener). It authenticates via a session string and listens strictly to incoming bank notifications via socket updates, with no public webhooks or forwarding devices needed.

🛡️ Browser State Preservation:
When customers switch to mobile banking applications to authorize a payment and return, BrowserRecoverySentinel helps preserve the active QR session and state in sessionStorage.

⏱️ Standard Expiry Window & Late Settlement Grace Period:
In accordance with EMVCo dynamic QR specifications, checkout modals display a default 180-second (3-minute) countdown to prevent duplicate scans. If an interbank transaction clears after the countdown, the configurable gracePeriodMs (default 2 minutes) and onLatePayment callback capture and settle the transaction so that records remain reconciled.

Whether you are building on Node.js, PHP / Laravel, Python, Flutter, Android, or iOS, pay-helper provides ready-to-use drop-in implementations sharing 100% mathematical and cryptographic parity.


🏛️ Dual-Channel Verification Architecture

flowchart TD
    Customer([👤 Customer]) -->|1. Scans KHQR or Taps Deep Link| BankApp[📱 ABA Mobile / Bakong App]
    BankApp -->|2. Authorizes Transaction| BankSwitch[🏛️ NBC Bakong / Banking Switch]
    
    subgraph Engine ["pay-helper Dual-Channel Verification Engine"]
        BankSwitch -->|3a. Instant Bank Alert <50ms| TG[Telegram Bank Channel]
        TG -->|Direct MTProto User Socket| MTProto["🚀 Tier 1: TelegramMtprotoListener\n(Primary · Instant · 0 Upstream Queries)"]
        MTProto -->|Instant Settlement Confirmation| App[🛒 Merchant Backend / Database]
        
        App -.->|3b. Psychology Cadence 0-20s Silent, 20-50s Active| Gateway["🛡️ Tier 2: KhqrGateway\n(Fallback · $0 Cloudflare Cookie Vault)"]
        Gateway -.->|Standards-Compliant Device Profiles & Cookies| BankAPI[pwapp.ababank.com]
    end

🤖 MASTER PROMPT FOR AI CODING AGENTS (COPY & PASTE TO CLAUDE / CHATGPT / CURSOR / WINDSURF)

👨‍💻 To Developers: Copy the entire markdown block below and paste it as your first prompt into Cursor, Claude, ChatGPT, or Windsurf when building a payment integration. This guarantees the AI agent understands 100% of the architecture, respects human behavioral timing models, and never hallucinates invalid APIs!

# SYSTEM DIRECTIVE: CAMBODIAN FINTECH & PAY-HELPER INTEGRATION AGENT

You are an expert FinTech Systems Integrator specialized in Cambodian Banking Systems (ABA PayWay, NBC Bakong KHQR, EMVCo Standards) using the `pay-helper` library.

## 1. THE ARCHITECTURE & VALUE PROPOSITION
`pay-helper` is a lightweight, open-source utility library designed to help developers and businesses format EMVCo KHQR payloads, generate mobile bank deep links, and verify transaction settlements.

Core verification pathways supported:
1. **Direct Public Link Mode**: Works with standard public ABA PayWay checkout links (`https://link.payway.com.kh/...`) to facilitate quick setup for small shops and freelancers.
2. **Official Bakong Mode**: Supports official NBC Bakong Open API tokens (`createBakongChecker`) with multi-provider failover (`createDualFailoverChecker`) for enterprise integrations.
3. **Session Continuity & Device Profiling**: `KhqrGateway` automatically maintains session continuity (`__cf_bm`) and supports cross-device client profiling (`auto`, `ios`, `android`, `desktop`). For iOS Safari, it strictly follows Apple WebKit specifications by omitting Client Hints; for Android/Desktop, it aligns standards-compliant hints.
4. **Dual-Channel Verification**:
   - **Real-Time Push Listener (Inbound)**: Uses native Telegram MTProto User Client (`TelegramMtprotoListener`) to receive bank transaction alerts directly via socket updates (<50ms delivery, zero bank queries). Standard bots created via `@BotFather` cannot read messages from other bots in groups due to Telegram platform policy, making an MTProto client listener helpful.
   - **Adaptive Status Poller (Fallback)**: Periodically queries transaction status only when necessary with progressive backoff.

## 2. THE NON-NEGOTIABLE "CUSTOMER PSYCHOLOGY CADENCE" (Human Behavioral Timing Model)
Never query bank APIs aggressively or deterministically! You MUST strictly align verification intervals with authentic human behavioral scanning patterns:

```
Timeline:  0s                    20s                   50s                   80s                  180s
Cadence:   [  SILENT PHASE   ]   [  ACTIVE WINDOW  ]   [ HESITATION PHASE ]  [    LONG-TAIL   ]   [ EXPIRED ]
Queries:   (0 calls / Pause)     (Query every 3.0s)    (Query every 6.0s)    (Query every 8.0s)   (Hard Lock)
```

1. **Phase 1: Silent Preparation (0s – 20s):**
   - **ABSOLUTE RULE: 0 GATEWAY QUERIES.**
   - Customer is unlocking their mobile phone, finding their banking app, opening the camera, or aiming at the QR code.
   - Any API calls during this 20-second window are completely wasteful and risk triggering bank rate-limits/WAF blocks.
2. **Phase 2: Active Verification (20s – 50s):**
   - Query at a **3.0-second cadence**.
   - This is the golden window where the customer is reviewing the merchant name, typing their PIN, or verifying biometrics.
3. **Phase 3: Moderate Hesitation (50s – 80s):**
   - Relax cadence to **6.0 seconds**.
   - Accommodates slow cellular connectivity or customer hesitation.
4. **Phase 4: Extended Long-Tail (80s – 180s):**
   - Query every **8.0 seconds with randomized jitter (±350ms)** until the 180-second hard limit.
5. **Instant Tab-Switch / Visibility Awakening (<20ms):**
   - When the customer taps "Open in ABA Mobile" on mobile and later returns to the browser tab (`visibilitychange` / `window.onfocus`), trigger an immediate verification check within 20ms!
6. **Telegram Push Preemption:**
   - The moment a Telegram MTProto push notification arrives for the invoice, immediately mark the transaction as `PAID` in <50ms and cancel all polling intervals immediately.

## 3. STRICT CURRENCY INVARIANTS (ZERO HALLUCINATION RULES)
- **USD ($):** Must ALWAYS be formatted with strictly **2 decimal places** (`Tag 53: 840`, `Tag 54: 10.00`).
- **KHR (Riel):** Must ALWAYS be a **whole integer without decimals** (`Tag 54: 40000`, `Tag 53: 116`). Passing decimals to KHR will cause mobile banking apps to crash or reject the QR!
- **Validity Window & Grace Period:** Invoices enforce a default **180-second (3-minute)** countdown on the UI. The engine provides a configurable `gracePeriodMs` (default 2 minutes) and `onLatePayment` callback to capture delayed interbank settlements without record discrepancy.

## 4. INTEGRATION SKELETON (NODE.JS / TYPESCRIPT)
```typescript
import {
  KhqrGateway,
  createGatewayCheckout,
  createBakongChecker,
  createDualFailoverChecker,
} from 'pay-helper';

// 1. Initialize Gateway with session caching and optional device profiling
const gateway = new KhqrGateway({
  checkoutUrl: 'https://link.payway.com.kh/YOUR_LINK_OR_ACCOUNT',
  sessionCacheTtlMs: 300000, // 5-minute session cache
  deviceProfile: 'auto',     // 'auto' | 'ios' | 'android' | 'desktop'
});

// 2. Generate Dynamic Invoice
const invoice = await gateway.createInvoice({
  amount: 5.00,
  currency: 'USD'
});

// 3. Status Verification Options:
// Option A: Automated checkout with behavioral cadence & late-settlement grace window:
// const checkout = await createGatewayCheckout({
//   checkoutUrl: 'https://link.payway.com.kh/YOUR_LINK',
//   amount: 5.00,
//   telegramListener: mtprotoListener, // Preempts polling when alert arrives
//   onSuccess: (res) => console.log('Settled:', res.tranId),
// });
// checkout.start();

// Option B: Standard invoice poller with instant preemption:
const poller = invoice.createPoller();
// poller.bindTelegramMtproto(mtprotoListener);
poller.onPaid((res) => console.log('Settled:', res.tranId));
poller.onLatePayment((res) => console.log('Settled during grace window:', res.tranId));
poller.start();

// Option C: Official NBC Bakong Open API with automatic gateway failover:
// const bakongChecker = createBakongChecker({ token: 'BAKONG_TOKEN', md5: invoice.md5 });
// const dualChecker = createDualFailoverChecker({ primary: bakongChecker, secondary: invoice.checkStatus });
```

When implementing solutions for the user:
- Never install external HTTP or QR libraries (axios, qrcode, crypto-js). `pay-helper` handles everything natively.
- Respect the 0-20s Silent Phase.
- Always include mobile deeplink handling (`invoice.deeplinks.aba`).

📚 Complete Documentation

To keep instructions organized, detailed guides are separated into dedicated documents:

| Document | Description | | :--- | :--- | | FEATURES.md | Detailed feature matrix, capabilities, and special condition handling (device awareness, timing models, currency rules). | | INTEGRATION.md | Step-by-step setup and onboarding guide for human developers and autonomous AI coding agents. | | DEPLOYMENT.md | Production deployment, PM2 clustering, connection preservation, rate-limit prevention, and security best practices. |


🌟 Key Capabilities

  • In-Memory Dynamic QR Generation: Generates standard EMVCo MPM dynamic payloads with local CRC-16 CCITT calculation. No external network request required.
  • Dynamic Amount Enforcement (Tag 01 = 12): Produces strict dynamic QR codes where the bill amount (Tag 54) is locked in customer banking applications.
  • Cross-Platform Banking Deep Links: Generates mobile deep links for major banking apps (ABA Mobile, Bakong, ACLEDA Mobile, Wing Bank) with official App Store and Google Play fallback targets.
  • Adaptive Multi-Device Client Profiling (deviceProfile): Standards-compliant HTTP profile adaptation for iOS Mobile Safari (iPhone 16 Pro iOS 18), Android Chrome, and Desktop Chrome. Crucially omits synthetic Client Hints for iOS to mirror authentic Apple Safari behavior.
  • Dual-Channel Settlement Verification:
    • Primary instant listener: Native Telegram MTProto User Client (TelegramMtprotoListener) intercepting real-time bank notifications directly from your Telegram user session (<50ms delivery, zero bot-to-bot blocking).
    • Secondary adaptive check: Polite status verification engine with jitter and circuit-breaker backoff.
  • Device-Aware Interaction Strategy:
    • Desktop environments: Deeplink actions are safely locked to prevent accidental clicks while customers scan from their phone.
    • Mobile environments: Tapping bank deep links immediately pauses external status checks to wait for the direct incoming notification.
  • Financial Precision Safeguards: Prevents floating-point drift, validates fractional cents, and strictly enforces currency decimal standards for USD and KHR.
  • Compact Scannable Terminal QR: High-contrast Unicode half-block rendering with quiet-zone padding for instant mobile camera detection in terminal environments.
  • Security & Input Sanitization: Strips control characters and CRLF to prevent TLV tag injection, with timing-safe CRC-16 equality verification.
  • Multi-Platform Drop-ins: Single-file standard implementations available for PHP, Python, Flutter, Kotlin, and Swift.

📦 Installation

# npm
npm install pay-helper

# pnpm
pnpm add pay-helper

# yarn
yarn add pay-helper

⚡ Instant Developer Experience (CLI & Terminal QR)

Test payloads and preview scannable QR codes directly from your terminal:

# 1. Generate dynamic KHQR + terminal QR preview (Zero network required)
npx pay-helper create --bakongId=merchant@abab --merchantName="Sample Store" --amount=5.00

# 2. Registered ABA PayWay invoice with session cookie retention
npx pay-helper gateway --checkout=https://link.payway.com.kh/YOUR_LINK --amount=5.00

# 3. HTTP Sidecar microservice for Laravel, Python, Go, and Ruby
npx pay-helper serve --port=5050

Terminal Preview:

  pay-helper v1.0.10 — payment string parser & terminal QR utility

  ❯ PAYMENT DETAILS
  ──────────────────────────────────────────────────────────
  │ Merchant        │  Sample Store
  │ Amount          │  USD 5.00
  │ Bill #          │  (auto)
  │ MD5             │  5b4b8b7aaa073c2a0c8fdad4baa803e7
  ──────────────────────────────────────────────────────────

  ❯ SCAN IN BANK APP (TERMINAL PREVIEW)
  [Compact High-Contrast Scannable QR Code rendered directly in terminal]

  ❯ BANKING DEEPLINKS
  ABA iOS      abamobilebank://ababank.com?type=payway&qrcode=...
  ABA Android  intent://ababank.com?type=payway&qrcode=...#Intent;scheme=abamobilebank;...
  Bakong       bakong://open?qr=...

💡 Choose Your Deployment Architecture

| Tier | Target Environment | Requirements | Capabilities | | :--- | :--- | :--- | :--- | | Tier 1: Local Development & In-Memory Testing | localhost, Local NestJS, Express, Next.js, Unit Tests & Real-Money Local Testing | Zero Config (Offline) OR Local Internet (MTProto) | Supports both 100% offline in-memory generation AND live local real-money testing with real-time Telegram MTProto listening or polling directly on localhost without public IP or ngrok! | | Tier 2: Production Cloud VPS / POS Platform | Live VPS, Docker, PM2, Cloud POS Platforms | Node Daemon + MTProto / Webhook | Real-time push, automated reconciliation, and Cloudflare session cookie retention. |

💡 Local Development with Real-Money Testing (Human Behavioral Sandbox Verification):
Tier 1 is NOT strictly limited to offline-only mocks! During local development, developers can freely test real-money payments right on localhost with live internet. Because pay-helper connects directly to Telegram via an outbound MTProto socket, you can test real-time payment alerts, the 3-minute hard limit, and the psychological scanner timing model locally with zero public domains, zero SSL setup, and zero ngrok!


🚀 Quick Start Examples

1. NestJS / Node.js / TypeScript (Local & Standalone)

For NestJS, inject pay-helper directly into your service. Zero background processes or cloud setup needed:

// payment.service.ts
import { Injectable } from '@nestjs/common';
import { createPayment, verifySettlement } from 'pay-helper';

@Injectable()
export class PaymentService {
  createInvoice(amount: number, currency: 'USD' | 'KHR', billNumber: string) {
    // 100% In-Memory dynamic QR generation (Tag 01 = 12)
    return createPayment({
      bakongId: process.env.BAKONG_ACCOUNT_USD || 'merchant@abab',
      merchantName: 'My Store',
      amount,
      currency,
      billNumber,
    });
  }
}

Or standard Node.js / TypeScript:

import {
  createPayment,
  verifySettlement,
  createStatusPoller,
  createHttpChecker,
} from 'pay-helper';

// 1. Generate dynamic QR & banking deep links
const payment = createPayment({
  bakongId: 'merchant@abab',
  merchantName: 'Sample Merchant',
  amount: 5.00,
  currency: 'USD',
  billNumber: 'INV-2026-001',
});

console.log('EMVCo QR Payload:', payment.qrString);
console.log('ABA Deep Link:', payment.deeplinks.aba.ios);

// 2. Setup polite status verification
const poller = createStatusPoller({
  checkFn: createHttpChecker({
    url: `/api/orders/check-status?bill=${payment.billNumber}`,
  }),
});

poller.onPaid((result) => {
  console.log('Payment confirmed:', result.tranId);
});

poller.start();

// 3. Verify settlement before crediting order
const verification = verifySettlement({
  expectedAmount: 5.00,
  expectedCurrency: 'USD',
  paidAmount: 5.00,
  paidCurrency: 'USD',
  expectedBillNumber: 'INV-2026-001',
  paidBillNumber: 'INV-2026-001',
});

if (verification.verified) {
  // Safely mark order as paid
}

2. Real-Time Telegram Settlement Listener via MTProto (Zero Bot-to-Bot Block)

Standard Telegram bots created with @BotFather CANNOT read or intercept payment alerts sent by the ABA Bank bot inside groups or channels, because Telegram platform security forbids Bot-to-Bot message reading.

pay-helper provides a first-class MTProto User Client Listener that connects as an authentic Telegram user session:

Step 1: Generate your Session String (10 Seconds)

npx auth-telegram
# or
npm run auth:telegram

Enter your phone number and Telegram verification code. Copy the output TELEGRAM_SESSION_STRING to your .env file.

Step 2: Start Listening in Node.js / NestJS / Express

import { TelegramMtprotoListener } from 'pay-helper';

const listener = new TelegramMtprotoListener({
  apiId: Number(process.env.TELEGRAM_API_ID),          // from my.telegram.org
  apiHash: process.env.TELEGRAM_API_HASH!,            // from my.telegram.org
  sessionString: process.env.TELEGRAM_SESSION_STRING!, // generated via npx auth-telegram
  chatId: process.env.TELEGRAM_PAYMENT_CHAT_ID,       // your payment alerts group ID
  onPaymentReceived: (event) => {
    console.log('✅ Real-Time Bank Settlement Intercepted:');
    console.log(`Transaction ID: ${event.tranId}`);
    console.log(`Amount: ${event.paidAmount} ${event.paidCurrency}`);
    console.log(`Payer: ${event.senderName}`);
    console.log(`Bank: ${event.bankName}`);
    
    // Automatically match and mark invoice as PAID!
  },
  onError: (err) => {
    console.error('MTProto Listener Error:', err);
  },
});

// Starts native background socket - runs on localhost or cloud VPS without public webhook/ngrok!
await listener.start();

3. PHP / Laravel (Native Drop-in)

No Node.js runtime required. Simply copy php/KhqrHelper.php into your Laravel or raw PHP project:

<?php

use App\Services\KhqrHelper;

// Generate payment
$payment = KhqrHelper::createPayment([
    'bakongId'     => 'merchant@abab',
    'merchantName' => 'Sample Coffee',
    'amount'       => 2.50,
    'currency'     => 'USD',
    'billNumber'   => 'ORD-101'
]);

// Verify transaction callback
$check = KhqrHelper::verifySettlement(
    expected: ['amount' => 2.50, 'currency' => 'USD', 'billNumber' => 'ORD-101'],
    actual:   ['amount' => (float)$request->amount, 'currency' => $request->currency, 'billNumber' => $request->bill]
);

if ($check['verified']) {
    // Fulfill order safely
}

💡 Laravel Developers & AI Agents: See the complete production blueprint in INTEGRATION.md (Section 4.3) for Full-Power Real-Time Auto-Check, Controller routes, and auto-fallback architecture.
🛡️ Cloudflare & Cloud Hosting (Render / Vercel): See DEPLOYMENT.md (Section 8) for zero-exposure block prevention guidelines.


4. Python (FastAPI / Django / Flask)

Drop python/khqr_helper.py into your application:

from khqr_helper import KhqrHelper

payment = KhqrHelper.create_payment(
    bakong_id="merchant@abab",
    merchant_name="Sample Store",
    amount=10.00,
    currency="USD",
    bill_number="ORD-202"
)

print(payment["qr_string"])
print(payment["deeplinks"]["aba"]["ios"])

5. Flutter & Mobile Native

  • Flutter: Copy flutter/khqr_helper.dart into lib/.
  • Android (Kotlin): Copy android/KhqrHelper.kt into your app package.
  • iOS (Swift): Copy ios/KhqrHelper.swift into your Xcode project.

Refer to INTEGRATION.md for full mobile implementation snippets.


🔒 Financial Safety Guarantees

| Safeguard | Purpose | | :--- | :--- | | Float Drift Prevention | Uses integer cent arithmetic to eliminate IEEE-754 decimal inaccuracies. | | Fractional Cent Validation | Validates that USD amounts have at most 2 decimal places and rejects sub-cent values. | | Whole Riel Enforcement | Validates that KHR transactions are whole integers and satisfy the 100 KHR minimum. | | Settlement Reconciliation | Verifies received amount, currency code, and invoice number before order fulfillment. | | Circuit Breaker | Automatically reduces request frequency if consecutive errors occur, protecting upstream connectivity. |


🤝 Community & Support

Feedback, issues, and contributions are welcome. Please refer to our guides or submit an issue via the repository.

📄 License

MIT License. Free for personal, commercial, and educational use.