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

@thevikalp/zoho-payments

v1.0.0-rc.1

Published

TypeScript SDK for the Zoho Payments API — supports IN, IN Sandbox, and US editions

Readme

zohopay

TypeScript SDK for the Zoho Payments API. Supports India (production + sandbox) and United States editions.

Unofficial SDK / use at your own risk: This package is community-maintained and is not an official Zoho or Zoho Payments SDK. It is provided "as is," without warranties or guarantees. You are solely responsible for validating API behavior, securing credentials, handling customer/payment data, meeting compliance obligations, and managing any data violations, losses, outages, or damages that may arise from using it. The authors and contributors are not responsible or liable in any way for your use of this package.

Features

  • Full OAuth 2.0 flow — authorization URL, code exchange, token refresh, revoke
  • Payment Links — create, update, cancel, list, get
  • Payment Sessions — create, get
  • Payments — create (US), get, list, verify
  • Customers — create, get, list (US), delete (US)
  • Refunds — create, get, list
  • Pluggable HTTP transport — inject retries, proxies, or logging
  • Strict TypeScript types, zero runtime dependencies

Requirements

  • Node.js ≥ 18 (uses native fetch)
  • TypeScript ≥ 5.5

Install

bun install        # or: npm install
bun run build      # or: npm run build

Quick start

import { ZohoPayments, Edition } from "zohopay";

const client = ZohoPayments.builder()
  .accountId("YOUR_ACCOUNT_ID")
  .edition(Edition.IN)          // Edition.IN | Edition.IN_SANDBOX | Edition.US
  .accessToken("1000.xxxx.yyyy")
  .requestTimeoutMs(45_000)     // optional, default 60 s
  .build();

OAuth flow

1 — Build the authorization URL

import { buildAuthorizationUrl, Edition, OAUTH_SCOPES } from "zohopay";

const authUrl = buildAuthorizationUrl({
  clientId:    "1000.YOUR_CLIENT_ID",
  accountId:   "YOUR_ACCOUNT_ID",
  redirectUri: "https://yourapp.example.com/oauth/callback",
  edition:     Edition.IN,
  accessType:  "offline",           // "offline" to get a refresh token
  scopes: [
    OAUTH_SCOPES.PAYMENTS_CREATE,
    OAUTH_SCOPES.PAYMENTS_READ,
    OAUTH_SCOPES.PAYMENTS_UPDATE,
    OAUTH_SCOPES.CUSTOMERS_CREATE,
    OAUTH_SCOPES.CUSTOMERS_READ,
    OAUTH_SCOPES.REFUNDS_CREATE,
    OAUTH_SCOPES.REFUNDS_READ,
  ],
  state: "csrf-token-here",         // recommended — validate on callback
});

// Redirect the user to authUrl

2 — Parse the callback and exchange the code

import { parseOAuthCallback, exchangeCodeForToken } from "zohopay";

const callback = parseOAuthCallback(req.url);
// Validate callback.state against your stored CSRF token here

const tokenSet = await exchangeCodeForToken({
  code:         callback.code!,
  clientId:     "1000.YOUR_CLIENT_ID",
  clientSecret: "YOUR_CLIENT_SECRET",
  redirectUri:  "https://yourapp.example.com/oauth/callback",
  edition:      Edition.IN,
});

// tokenSet.accessToken  — use immediately
// tokenSet.refreshToken — store securely for later refreshes
// tokenSet.expiresIn    — seconds until access token expires

3 — Refresh the access token

The SDK does not auto-refresh. Call this when the token expires, then push it into the client.

const fresh = await ZohoPayments.generateAccessToken({
  refreshToken: "1000.stored_refresh_token",
  clientId:     "1000.YOUR_CLIENT_ID",
  clientSecret: "YOUR_CLIENT_SECRET",
  redirectUri:  "https://yourapp.example.com/oauth/callback",
  edition:      Edition.IN,
});

client.updateOAuthToken(fresh);   // no rebuild needed
// fresh.isExpired() — check with 30 s buffer

4 — Revoke a refresh token

await ZohoPayments.revokeToken({
  token:   "1000.stored_refresh_token",
  edition: Edition.IN,
});

Payment Links

// Create
const link = await client.paymentLinks().create({
  amount:      500,
  currency:    "INR",
  description: "Order #1234",
  email:       "[email protected]",
  notifyCustomer: { email: true, sms: false },
  metaData:    [{ key: "order_id", value: "ORD-1234" }],
});
console.log(link.paymentLinkId, link.url);

// Get
const link = await client.paymentLinks().get("link_id");

// Update
const updated = await client.paymentLinks().update("link_id", { amount: 600 });

// Cancel
const cancelled = await client.paymentLinks().cancel("link_id");

// List
const { items, pageContext } = await client.paymentLinks().list({ page: 1, perPage: 20 });

Payment Sessions

const session = await client.paymentSessions().create({
  amount:        250,
  currency:      "INR",
  description:   "Checkout session",
  expiresIn:     600,          // 300–900 seconds
  maxRetryCount: 3,            // 1–5
});
console.log(session.paymentsSessionId, session.accessKey);

const session = await client.paymentSessions().get("session_id");

Payments

// Verify / get a payment
const payment = await client.payments().verify("payment_id");
console.log(payment.status, payment.amount, payment.currency);

// List
const { items } = await client.payments().list({ status: "success", page: 1 });

// Create (US edition only)
const payment = await client.payments().create({
  customerId:      "cust_id",
  paymentMethodId: "pm_id",
  amount:          1000,
  currency:        "USD",
});

Customers

// Create
const customer = await client.customers().create({
  name:  "Jane Doe",
  email: "[email protected]",
  metaData: [{ key: "source", value: "web" }],
});

// Get
const customer = await client.customers().get("cust_id");

// List (US only)
const { items } = await client.customers().list({ email: "[email protected]" });

// Delete (US only)
await client.customers().delete("cust_id");

Refunds

// Create
const refund = await client.refunds().create("payment_id", {
  amount: 100,
  reason: "requested_by_customer",
  type:   "initiated_by_merchant",
});

// Get
const refund = await client.refunds().get("refund_id");

// List
const { items } = await client.refunds().list({ page: 1 });

Error handling

import {
  AuthenticationException,
  PermissionException,
  ResourceNotFoundException,
  InvalidRequestException,
  RateLimitException,
  ZohoPaymentsAPIException,
  ConnectionException,
} from "zohopay";

try {
  await client.payments().get("id");
} catch (err) {
  if (err instanceof AuthenticationException) {
    // 401 — refresh the token and retry
  } else if (err instanceof RateLimitException) {
    // 429 — back off and retry
  } else if (err instanceof ResourceNotFoundException) {
    // 404
  } else if (err instanceof InvalidRequestException) {
    console.error(err.codeString, err.apiErrorMessage);
  } else if (err instanceof ZohoPaymentsAPIException) {
    console.error(err.httpStatusCode, err.message);
  } else if (err instanceof ConnectionException) {
    // network / timeout
  }
}

Custom HTTP transport

Inject your own transport for retries, proxies, or instrumentation:

import { DefaultHttpTransport, ZohoPayments, Edition } from "zohopay";
import type { HttpTransport, ZohoRequest, ZohoResponse } from "zohopay";

class LoggingTransport implements HttpTransport {
  constructor(private readonly inner: HttpTransport) {}

  async execute(req: ZohoRequest): Promise<ZohoResponse> {
    console.log(`→ ${req.method} ${req.url}`);
    const res = await this.inner.execute(req);
    console.log(`← ${res.statusCode}`);
    return res;
  }
}

const client = ZohoPayments.builder()
  .accountId("YOUR_ACCOUNT_ID")
  .edition(Edition.IN)
  .accessToken("1000.xxxx.yyyy")
  .transport(new LoggingTransport(new DefaultHttpTransport()))
  .build();

Note: transport() and requestTimeoutMs() are mutually exclusive with connectTimeoutMs().

Editions

| Constant | Region | API base | |---|---|---| | Edition.IN | India production | payments.zoho.in | | Edition.IN_SANDBOX | India sandbox | paymentssandbox.zoho.in | | Edition.US | United States | payments.zoho.com |

Dev server

A local proxy server is included to test API calls without CORS issues:

bun run playground        # starts on http://127.0.0.1:3579

The server binds to 127.0.0.1 only and is not LAN-accessible.

Scripts

| Command | Description | |---|---| | bun run build | Compile to dist/ (CJS + ESM + types) | | bun run dev | Watch mode | | bun run typecheck | Type-check without emitting | | bun run test | Run tests with Vitest | | bun run playground | Start the dev proxy server |

License

Apache-2.0. See LICENSE.

This package is provided on an "AS IS" and "USE AT YOUR OWN RISK" basis, without warranties or liability. Users are responsible for their own integrations, data handling, compliance, and operational safeguards.