Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.paybridgenp.com/llms.txt

Use this file to discover all available pages before exploring further.

Installation

npm install @paybridge-np/sdk

Initialization

import { PayBridge } from "@paybridge-np/sdk";

const paybridge = new PayBridge({
  apiKey: process.env.PAYBRIDGE_API_KEY!,  // sk_test_... or sk_live_...
  baseUrl: "https://api.paybridgenp.com",  // optional, this is the default
  timeout: 30_000,                         // optional, ms. default: 30000
  maxRetries: 2,                           // optional. default: 2
});

paybridge.checkout

checkout.create(params)

Creates a checkout session.
const session = await paybridge.checkout.create({
  amount: 10000,                              // required - paisa (NPR × 100)
  returnUrl: "https://yoursite.com/success", // required
  cancelUrl: "https://yoursite.com/cart",    // optional
  provider: "khalti",                        // optional - omit to let customer pick
  currency: "NPR",                           // optional, default: "NPR"
  metadata: { orderId: "ORD-001" },          // optional
});

console.log(session.checkout_url);  // redirect customer here
console.log(session.id);            // cs_...
console.log(session.expires_at);    // ISO timestamp
Parameters:
NameTypeRequiredDescription
amountnumberYesIn paisa. NPR 100.00 = 10000
returnUrlstringYesRedirect URL after payment
cancelUrlstringNoRedirect URL on cancellation
provider"esewa" | "khalti" | "fonepay"NoPre-select provider
currencystringNoDefault: "NPR"
metadataobjectNoPassed through to webhooks and payment records

checkout.expire(id)

Marks a session as expired so it can no longer accept payment. Use this when you mint a fresh session for a logical purchase that already had one outstanding (e.g. a customer requesting a new payment link), so the old URL stops being payable immediately rather than waiting for its 30-minute TTL. Mirrors Stripe’s POST /checkout/sessions/{id}/expire.
await paybridge.checkout.expire("cs_6f2jHn2…");
Idempotent: calling on an already-terminal session is a no-op that returns the current row state without error.

paybridge.payments

payments.list(params?)

const { data, meta } = await paybridge.payments.list({
  limit: 20,   // optional, default 20, max 100
  offset: 0,   // optional, default 0
});

console.log(meta.total);  // total count
data.forEach((payment) => {
  console.log(payment.id, payment.amount, payment.status);
});

payments.retrieve(id)

const payment = await paybridge.payments.retrieve("pay_6f2jHn2...");

console.log(payment.status);      // "success" | "failed"
console.log(payment.amount);      // paisa
console.log(payment.provider);    // "esewa" | "khalti" | "fonepay"
console.log(payment.providerRef); // provider's transaction reference
console.log(payment.metadata);    // whatever you passed at checkout

paybridge.webhooks

webhooks.create(params)

const endpoint = await paybridge.webhooks.create({
  url: "https://yoursite.com/webhooks/paybridge",
  events: ["payment.succeeded", "payment.failed"], // optional - omit for all events
});

console.log(endpoint.signing_secret); // save this! shown only once

webhooks.list()

const { data } = await paybridge.webhooks.list();
data.forEach((wh) => console.log(wh.id, wh.url, wh.enabled));

webhooks.delete(id)

await paybridge.webhooks.delete("wh_...");

PayBridge.webhooks.constructEvent(body, signature, secret) (static)

Verifies a webhook signature and parses the event. Use this in your webhook handler.
import { PayBridge } from "@paybridge-np/sdk";

// This is a static method - no instance needed
const event = await PayBridge.webhooks.constructEvent(
  rawBodyString,           // raw request body - do NOT parse as JSON first
  signatureHeader,         // value of X-PayBridge-Signature header
  process.env.PAYBRIDGE_WEBHOOK_SECRET!,
);

switch (event.type) {
  case "payment.succeeded":
    // event.data: { id, amount, currency, provider, provider_ref, session_id }
    await fulfillOrder(event.data.metadata?.orderId);
    break;

  case "payment.failed":
    await notifyOrderFailed(event.data.session_id);
    break;
}
Throws PayBridgeSignatureVerificationError if:
  • The signature header is missing or malformed
  • The HMAC doesn’t match
  • The timestamp is more than 5 minutes old (replay attack protection)

paybridge.billing

The billing namespace provides access to plans, customers, subscriptions, and invoices. Billing API access requires the Premium plan.

billing.plans

// Create a plan
const plan = await paybridge.billing.plans.create({
  name: "Pro Monthly",
  amount: 99900,         // paisa - NPR 999/month
  interval: "month",
  intervalCount: 1,
  trialDays: 14,         // optional
});

// List plans
const { data } = await paybridge.billing.plans.list();

// Get a plan
const plan = await paybridge.billing.plans.retrieve("plan_...");

// Update a plan
const updated = await paybridge.billing.plans.update("plan_...", { name: "Pro Monthly v2" });

billing.customers

// Create a customer
const customer = await paybridge.billing.customers.create({
  name: "Aarav Sharma",
  email: "aarav@example.com",
  externalCustomerId: "user_123",   // optional - your internal user ID
});

// List customers
const { data } = await paybridge.billing.customers.list();

// Get a customer
const customer = await paybridge.billing.customers.retrieve("cus_...");

// Update a customer
const updated = await paybridge.billing.customers.update("cus_...", { email: "new@example.com" });

// Delete a customer
await paybridge.billing.customers.delete("cus_...");

billing.subscriptions

// Create a subscription
const subscription = await paybridge.billing.subscriptions.create({
  customerId: "cus_...",
  planId: "plan_...",
});

// List subscriptions
const { data } = await paybridge.billing.subscriptions.list();

// Get a subscription
const sub = await paybridge.billing.subscriptions.retrieve("sub_...");

// Lifecycle actions
await paybridge.billing.subscriptions.pause("sub_...");
await paybridge.billing.subscriptions.resume("sub_...");
await paybridge.billing.subscriptions.cancel("sub_...");

// Change plan
await paybridge.billing.subscriptions.changePlan("sub_...", { planId: "plan_..." });

billing.invoices

// List invoices (optionally filter by subscription or customer)
const { data } = await paybridge.billing.invoices.list({
  subscriptionId: "sub_...",   // optional
});

// Get an invoice
const invoice = await paybridge.billing.invoices.retrieve("inv_...");

console.log(invoice.status);     // "pending" | "paid" | "overdue" | "cancelled"
console.log(invoice.amount);     // paisa
console.log(invoice.due_date);   // ISO timestamp
console.log(invoice.payment_url); // hosted payment link sent to customer

Error handling

All SDK methods throw typed errors you can catch and inspect:
import { PayBridge, PayBridgeError, PayBridgeAuthenticationError } from "@paybridge-np/sdk";

try {
  await paybridge.checkout.create({ amount: 1000, returnUrl: "..." });
} catch (err) {
  if (err instanceof PayBridgeAuthenticationError) {
    // Invalid API key
    console.error("Check your PAYBRIDGE_API_KEY");
  } else if (err instanceof PayBridgeError) {
    console.error(err.message);     // human-readable message
    console.error(err.statusCode);  // HTTP status
    console.error(err.code);        // machine-readable code
  }
}

Error classes

ClassStatusWhen
PayBridgeAuthenticationError401Invalid or missing API key
PayBridgeInvalidRequestError400Bad request parameters
PayBridgeNotFoundError404Resource not found
PayBridgeRateLimitError429Too many requests
PayBridgeError5xxServer error
PayBridgeSignatureVerificationError-Webhook HMAC mismatch or replay

TypeScript types

All types are exported from @paybridge-np/sdk:
import type {
  CheckoutSession,
  Payment,
  PaymentStatus,
  Provider,
  WebhookEvent,
  WebhookEventType,
  WebhookEndpoint,
  CreateCheckoutParams,
  PaginatedResponse,
  BillingPlan,
  BillingCustomer,
  BillingSubscription,
  BillingInvoice,
  CreatePlanParams,
  CreateCustomerParams,
  CreateSubscriptionParams,
} from "@paybridge-np/sdk";

Framework examples

// app/api/checkout/route.ts
import { NextRequest } from "next/server";
import { PayBridge } from "@paybridge-np/sdk";

const paybridge = new PayBridge({
  apiKey: process.env.PAYBRIDGE_API_KEY!,
});

export async function POST(req: NextRequest) {
  const { orderId, amount } = await req.json();

  const session = await paybridge.checkout.create({
    amount,
    returnUrl: `${process.env.NEXT_PUBLIC_URL}/thank-you`,
    cancelUrl: `${process.env.NEXT_PUBLIC_URL}/cart`,
    metadata: { orderId },
  });

  return Response.json({ checkoutUrl: session.checkout_url });
}
// app/api/webhooks/paybridge/route.ts
import { NextRequest } from "next/server";
import { PayBridge } from "@paybridge-np/sdk";

export async function POST(req: NextRequest) {
  const body = await req.text();
  const sig = req.headers.get("x-paybridge-signature");

  let event;
  try {
    event = await PayBridge.webhooks.constructEvent(
      body, sig, process.env.PAYBRIDGE_WEBHOOK_SECRET!,
    );
  } catch {
    return Response.json({ error: "Invalid signature" }, { status: 400 });
  }

  if (event.type === "payment.succeeded") {
    await db.orders.update({ status: "paid" }, {
      where: { id: event.data.metadata?.orderId },
    });
  }

  return Response.json({ received: true });
}
import express from "express";
import { PayBridge } from "@paybridge-np/sdk";

const app = express();
const paybridge = new PayBridge({ apiKey: process.env.PAYBRIDGE_API_KEY! });

app.use(express.json());

app.post("/create-checkout", async (req, res) => {
  const session = await paybridge.checkout.create({
    amount: req.body.amount,
    returnUrl: "https://yoursite.com/success",
    metadata: { orderId: req.body.orderId },
  });
  res.json({ checkoutUrl: session.checkout_url });
});

// Webhook route - must use raw body
app.post(
  "/webhooks/paybridge",
  express.raw({ type: "application/json" }),
  async (req, res) => {
    const event = await PayBridge.webhooks.constructEvent(
      req.body.toString(),
      req.headers["x-paybridge-signature"] as string,
      process.env.PAYBRIDGE_WEBHOOK_SECRET!,
    );

    if (event.type === "payment.succeeded") {
      // handle success
    }

    res.json({ received: true });
  },
);