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

paynotify-node

v1.0.8

Published

Official Node.js SDK for PayNotify Webhook Engine

Readme

[!NOTE] Designed for enterprise reliability, this Node.js SDK seamlessly integrates your backend with the PayNotify Engine. It implements Dynamic Cent Masking (Penny Drop) for lock-free concurrency management, and strictly enforces HMAC-SHA256 Webhook Verification to prevent replay and mutation attacks.


⚡ Core Architecture Features

  • Atomic Penny-Drop Concurrency: Instantly resolves payment overlap (e.g., 50 users buying a ₹49 product simultaneously) by dynamically masking amounts natively via Supabase RPCs.
  • Zero-Drift Signature Validation: Uses stable string concatenation (orderId:amount:status:timestamp) instead of JSON signing to absolutely prevent parsing mutation attacks.
  • Replay Attack Boundary: Enforces a rigid 5-minute expiry window on all incoming webhooks.
  • Client-Side Idempotency: Requires idempotencyKey on all order creations, shielding against double-billing during network retries.

📦 Installation

# npm
npm install paynotify-node

# yarn
yarn add paynotify-node

# pnpm
pnpm add paynotify-node

🚀 Initialization

import { PayNotify } from 'paynotify-node';

const paynotify = new PayNotify({
  apiKey: process.env.PAYNOTIFY_API_KEY as string,
  // Optional: Defaults to https://paypager.vercel.app
  gatewayUrl: process.env.PAYNOTIFY_GATEWAY_URL 
});

[!CAUTION] Secret Management Your apiKey is a highly privileged credential. Never commit it to source control or expose it to client-side environments (Browser/Mobile Apps).


🛒 Creating a Payment Order

When a user initiates checkout, call createOrder to atomically lock a unique decimal amount.

import express from 'express';
const app = express();

app.post('/api/checkout', async (req, res) => {
  try {
    const { baseAmount, customerName, sessionId } = req.body;

    const orderData = await paynotify.createOrder({
      baseAmount: baseAmount,
      customerName: customerName || 'Guest',
      // REQUIRED: Use session ID, Cart UUID, or Database ID to ensure idempotency
      idempotencyKey: `checkout_${sessionId}` 
    });

    // orderData returns: { success: true, orderId: "...", amount: 49.04, status: "PENDING" }
    
    // 1. Store orderData.orderId and orderData.amount in your Database
    // 2. Return data to the frontend for the React SDK
    res.json(orderData);

  } catch (error: any) {
    res.status(503).json({ error: 'Gateway unavailable, please retry.' });
  }
});

🔐 Securing Webhooks (Express Middleware)

PayNotify achieves Bi-Directional JIT (Just-In-Time) verification. You will receive webhooks instantly.

The SDK includes Express middleware that automatically handles timing attacks, signature validation, and replay prevention.

app.post(
  '/api/webhook',
  express.json(),
  paynotify.verifyWebhook(), // Drops unauthenticated/replay requests automatically
  async (req, res) => {
    // req.paynotify is populated only if the signature is 100% valid
    const { orderId, amount, status, sender_name, sender_upi } = (req as any).paynotify;

    if (status === 'VERIFIED') {
      // ✅ Trust this data. Update your database, unlock features, dispatch emails.
      await db.orders.updateOne(
        { id: orderId, expectedAmount: amount, status: 'PENDING' },
        { $set: { status: 'PAID' } }
      );
      
      console.log(`Payment confirmed from ${sender_name} via ${sender_upi}`);
      return res.status(200).json({ success: true });
    }

    res.status(200).json({ message: 'Ignored' });
  }
);

📖 API Reference

PayNotify(config)

| Option | Type | Required | Description | |---|---|---|---| | apiKey | string | Yes | Your secret PayNotify environment API key. | | gatewayUrl | string | No | Target API environment (default: https://paypager.vercel.app). |

createOrder(params)

| Parameter | Type | Required | Description | |---|---|---|---| | baseAmount | number | Yes | Base price of the product (e.g., 49.00). | | idempotencyKey | string | Yes | Unique tracking key preventing double execution on network retry. | | customerName | string | No | Used for dashboard analytics and logging. |

verifyWebhook()

Returns standard Express Middleware (req, res, next). Validates X-PayNotify-Signature using crypto.timingSafeEqual.