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

@obare13/pesapal-v3

v1.0.0

Published

Pure TypeScript PesaPal library for frontend frameworks

Readme

Pesapal TypeScript Library

A pure, dependency-free TypeScript library for the PesaPal API v3 using the standard Web Fetch API. Designed to work flawlessly in frontend frameworks like Next.js, Nuxt.js, SvelteKit (server routes) or standard Node.js applications (v18+).

The library was created to ease the usage of PesaPal payments in modern TypeScript/JavaScript environments.

[!WARNING] Consumer Keys and Secrets should never be exposed to the browser. Only use this library inside secure server-side routes (like Next.js API Routes or Server Actions).

Showcase

The library comes with three beautiful, ready-to-use examples for popular frameworks. They all share the same premium UI and robust payment logic.

| Next.js Example | Nuxt.js Example | SvelteKit Example | | :---: | :---: | :---: | | Next.js Showcase | Nuxt.js Showcase | SvelteKit Showcase |

Resources

To help you get started quickly, here are some useful links:

Installation

npm install @obare13/pesapal-v3

(Since you are developing locally, you can use npm link or copy this package directly to your project)

Usage

1. Initialize the client

import { PesapalClient } from '@obare13/pesapal-v3';

const pesapal = new PesapalClient({
  consumerKey: process.env.PESAPAL_CONSUMER_KEY!,
  consumerSecret: process.env.PESAPAL_CONSUMER_SECRET!,
  environment: 'sandbox', // Use 'production' for live apps
});

2. Authenticate & Register IPN

// Authenticate
await pesapal.authenticate();

// Register your server's IPN URL for instant payment notifications
const ipn = await pesapal.registerIPN({
  url: "https://your-domain.com/api/pesapal-webhook", // Must be publicly accessible
  ipn_notification_type: "GET" 
});

const ipnId = ipn.ipn_id;
console.log('IPN Registration ID:', ipnId);

3. Create an Order (Checkout)

const orderResponse = await pesapal.submitOrder({
  id: "YOUR_UNIQUE_ORDER_ID_123",
  currency: "KES",
  amount: 100.0,
  description: "Test Purchase",
  callback_url: "https://your-domain.com/payment-success",
  notification_id: ipnId, // From previous step
  billing_address: {
    email_address: "[email protected]",
    phone_number: "0712345678",
    country_code: "KE",
    first_name: "John",
    last_name: "Doe"
  }
});

// Redirect user to the PesaPal checkout page
console.log('Redirect user to:', orderResponse.redirect_url);

4. Verify Transaction Status

When a transaction is completed, PesaPal redirects the user and/or calls your IPN URL with an OrderTrackingId parameter. Use it to check status:

await pesapal.authenticate(); // Ensure you're still authenticated
const status = await pesapal.getTransactionStatus('ORDER_TRACKING_ID_HERE');

if (status.payment_status_code === 'COMPLETED') {
  // Update your database!
  console.log('Payment Successful:', status);
}

Going to Production

To move from Sandbox to Production, follow these critical steps to ensure secure and successful payments.

1. Environment Configuration

Update your environment variables with your live credentials from the PesaPal Dashboard.

PESAPAL_CONSUMER_KEY=your_live_key
PESAPAL_CONSUMER_SECRET=your_live_secret
PESAPAL_ENVIRONMENT=production

2. Update Client Initialization

Ensure your client is initialized with the 'production' environment.

const pesapal = new PesapalClient({
  consumerKey: process.env.PESAPAL_CONSUMER_KEY!,
  consumerSecret: process.env.PESAPAL_CONSUMER_SECRET!,
  environment: 'production', // MUST be 'production' for live payments
});

3. Handle IPNs Securely (Webhooks)

When PesaPal sends an IPN (Instant Payment Notification) to your server, you must verify the transaction status before updating your database.

Example: Next.js API Route (app/api/pesapal-webhook/route.ts)

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const orderTrackingId = searchParams.get('OrderTrackingId');
  const orderNotificationId = searchParams.get('OrderNotificationId');

  if (!orderTrackingId) return new Response('Missing ID', { status: 400 });

  await pesapal.authenticate();
  const status = await pesapal.getTransactionStatus(orderTrackingId);

  if (status.payment_status_code === 'COMPLETED') {
    // 1. Mark order as paid in your DB
    // 2. Trigger post-payment logic (e.g. send email)
  }

  // Return exactly what PesaPal expects to acknowledge receipt
  return Response.json({
    orderNotificationId,
    orderTrackingId,
    status: 200
  });
}

Framework Setup

I have provided ready-to-use examples for popular frameworks. Each example includes a shared CheckoutForm component and secure API routes.

Next.js Example

  1. API Integration: Implements App Router API routes (app/api/checkout/route.ts) to securely initialize payments.
  2. Components: Uses Shadcn-inspired UI components for a premium look and feel.
  3. Setup:
    • Copy .env.example to .env and add your PesaPal keys.
    • Run pnpm install && pnpm dev.

Nuxt.js Example

  1. Server Routes: Uses Nitro server routes (server/api/checkout.post.ts) for server-side logic.
  2. Vue Integration: Features a reactive CheckoutForm.vue component with Tailwind CSS.
  3. Setup:
    • Add keys to .env or runtimeConfig in nuxt.config.ts.
    • Run pnpm install && pnpm dev.

SvelteKit Example

  1. Server Actions: Leverages SvelteKit Form Actions (+page.server.ts) for seamless form submission.
  2. Modern Styling: Uses Svelte with Tailwind CSS for a fast and beautiful experience.
  3. Setup:
    • Define keys in .env (accessed via $env/static/private).
    • Run pnpm install && pnpm dev.

Error Handling

The library provides comprehensive error classes to help you easily debug and handle failures at different stages.

import { 
  PesapalClient,
  PesapalAuthenticationError,
  PesapalValidationError,
  PesapalAPIError,
  PesapalNetworkError
} from '@obare13/pesapal-v3';

try {
  await pesapal.submitOrder(payload);
} catch (error) {
  if (error instanceof PesapalValidationError) {
    console.error("Missing fields or bad input data:", error.message);
  } else if (error instanceof PesapalAuthenticationError) {
    console.error("Token invalid or expired:", error.message);
  } else if (error instanceof PesapalAPIError) {
    console.error("PesaPal API returned an error:", error.message, error.response);
  } else if (error instanceof PesapalNetworkError) {
    console.error("Fetch request failed totally (e.g. timeout)", error.message);
  } else {
    console.error("An unknown error occurred", error);
  }
}

Open Source & Contributions

This project is open-source. Feel free to fork it, modify it, or contribute to its development.

Git Repository: https://github.com/g-obare13/pesapal-ts

git clone https://github.com/g-obare13/pesapal-ts.git
cd pesapal-ts
pnpm install

Features

  • Dependency-free: Pure TypeScript using native Fetch API.
  • Edge Runtime compatible: Works on Cloudflare Workers, Vercel Edge, etc.
  • Fully Typed: Catch errors at compile-time with complete type definitions.
  • Rich Documentation: Comprehensive JSDoc comments for all methods and types.
  • Sandbox & Production: Easy toggling between environments.