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

@marmopay/node-sdk

v1.0.3

Published

Official Node.js SDK for Marmopay Payment Gateway

Readme

Marmopay Node.js SDK

Official Node.js SDK for Marmopay Payment Gateway. Accept payments across Kenya and Uganda with M-Pesa, Airtel Money, and card payments.

Features

  • 💳 Payment Processing - Create and manage payments
  • 🔍 Transaction Management - Query and track transactions
  • 💰 Refund Processing - Process full and partial refunds
  • 🔐 Webhook Verification - Secure webhook signature validation
  • 📘 TypeScript Support - Full type definitions included
  • 🔄 Automatic Retries - Built-in retry logic with exponential backoff
  • Promise-based API - Modern async/await support

Installation

npm install @marmopay/node-sdk
yarn add @marmopay/node-sdk
pnpm add @marmopay/node-sdk

Quick Start

import { Marmopay } from '@marmopay/node-sdk';

// Initialize the SDK
const marmopay = new Marmopay({
  apiKey: process.env.MARMOPAY_API_KEY,
  environment: 'live', // or 'test'
  webhookSecret: process.env.MARMOPAY_WEBHOOK_SECRET,
});

// Create a payment
const payment = await marmopay.payments.create({
  amount: 1000, // Amount in cents (1000 = 10.00 KES)
  currency: 'KES',
  customer: {
    email: '[email protected]',
    phone: '+254712345678',
  },
  callbackUrl: 'https://your-domain.com/payment/callback',
  description: 'Order #12345',
});

console.log('Payment URL:', payment.paymentUrl);
// Redirect customer to payment.paymentUrl

Configuration

Required

  • apiKey - Your Marmopay API key (get from dashboard)

Optional

  • environment - 'test' or 'live' (default: 'test')
  • webhookSecret - Your webhook secret for signature verification
  • baseUrl - Custom API base URL (default: auto-selected based on environment)
  • timeout - Request timeout in milliseconds (default: 30000)
  • retries - Number of retry attempts (default: 3)

API Reference

Payments

Create Payment

const payment = await marmopay.payments.create({
  amount: 1000, // IMPORTANT: Must be a number (1000 = 10.00 KES in cents)
  currency: 'KES',
  customer: {
    email: '[email protected]',
    phone: '+254712345678',
    firstName: 'John', // optional
    lastName: 'Doe', // optional
  },
  callbackUrl: 'https://your-domain.com/callback', // optional
  reference: 'ORD-12345', // optional, auto-generated if not provided
  description: 'Order payment', // optional
  metadata: { // optional
    orderId: '12345',
    customField: 'value',
  },
});

⚠️ Important Note About Amount:

  • amount must be a number, not a string
  • Specify amounts in the smallest currency unit (cents/kobo)
  • Examples: 1000 = 10.00 KES, 50000 = 500.00 KES

Get Payment

const payment = await marmopay.payments.get('TXN-20240115-ABC123');
console.log(payment.status); // 'pending', 'success', 'failed'

List Payments

const payments = await marmopay.payments.list({
  limit: 20,
  page: 1,
});

Transactions

Get Transaction

const transaction = await marmopay.transactions.get('TXN-20240115-ABC123');

if (transaction.status === 'success') {
  console.log('Payment confirmed!');
  // Fulfill order
}

List Transactions

const transactions = await marmopay.transactions.list({
  status: 'success',
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  limit: 50,
  page: 1,
});

Refunds

Create Refund

// Full refund
const refund = await marmopay.refunds.create({
  transactionId: 123,
  reason: 'Customer request',
});

// Partial refund
const partialRefund = await marmopay.refunds.create({
  transactionId: 123,
  amount: '500.00', // Refund half
  reason: 'Partial refund',
});

Get Refund

const refund = await marmopay.refunds.get(456);
console.log(refund.status); // 'pending', 'completed', 'failed'

Webhooks

Webhooks are the recommended way to receive real-time payment notifications.

📌 Getting Your Webhook Secret:

  1. Log in to your Marmopay dashboard at https://marmopay.com
  2. Navigate to Settings → Webhooks
  3. Click "Rotate Secret" to generate a new webhook secret
  4. Copy the secret and store it securely in your environment variables

🔐 Security Note:

  • Each merchant has a unique webhook secret
  • Marmopay signs all webhooks using your merchant-specific secret
  • The SDK verifies signatures using the same secret you provide
  • Never share your webhook secret publicly or commit it to version control

Express.js Example

import express from 'express';
import { Marmopay } from '@marmopay/node-sdk';

const app = express();
const marmopay = new Marmopay({
  apiKey: process.env.MARMOPAY_API_KEY,
  webhookSecret: process.env.MARMOPAY_WEBHOOK_SECRET, // ⚠️ REQUIRED for webhook verification
});

// Use express.raw() for webhook routes to preserve signature
app.post(
  '/webhooks/marmopay',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const signature = req.headers['x-marmopay-signature'] as string;

    try {
      // Verify and parse webhook using YOUR merchant-specific secret
      const event = marmopay.webhooks.parse(req.body, signature);

      // Process event
      switch (event.event) {
        case 'payment.success':
          console.log('Payment successful:', event.data);
          // Fulfill order
          break;

        case 'payment.failed':
          console.log('Payment failed:', event.data);
          // Notify customer
          break;

        case 'refund.processed':
          console.log('Refund processed:', event.data);
          // Update order
          break;
      }

      // Always respond quickly (within 5 seconds)
      res.json({ received: true });
    } catch (error) {
      console.error('Webhook verification failed:', error);
      res.status(401).json({ error: 'Invalid signature' });
    }
  }
);

Manual Verification

const isValid = marmopay.webhooks.verify(req.body, signature);

if (isValid) {
  const event = JSON.parse(req.body);
  // Process event
}

Error Handling

The SDK throws specific error types for different scenarios:

import {
  AuthenticationError,
  ValidationError,
  NotFoundError,
  RateLimitError,
  NetworkError,
  WebhookSignatureError,
} from '@marmopay/node-sdk';

try {
  const payment = await marmopay.payments.create(paymentData);
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof ValidationError) {
    console.error('Invalid data:', error.details);
  } else if (error instanceof NotFoundError) {
    console.error('Resource not found');
  } else if (error instanceof RateLimitError) {
    console.error('Rate limit exceeded');
  } else if (error instanceof NetworkError) {
    console.error('Network error:', error.message);
  } else {
    console.error('Unexpected error:', error);
  }
}

TypeScript Support

The SDK is written in TypeScript and includes full type definitions:

import { Marmopay, Payment, Transaction, Refund } from '@marmopay/node-sdk';

const marmopay = new Marmopay({ apiKey: 'your-key' });

// Types are automatically inferred
const payment: Payment = await marmopay.payments.create({...});
const transaction: Transaction = await marmopay.transactions.get('ref');

Environment Variables

Create a .env file:

MARMOPAY_API_KEY=mmp_test_your_key_here
MARMOPAY_WEBHOOK_SECRET=whsec_your_secret_here
MARMOPAY_ENVIRONMENT=test

Load with dotenv:

import 'dotenv/config';
import { Marmopay } from '@marmopay/node-sdk';

const marmopay = new Marmopay({
  apiKey: process.env.MARMOPAY_API_KEY!,
  environment: process.env.MARMOPAY_ENVIRONMENT as 'test' | 'live',
  webhookSecret: process.env.MARMOPAY_WEBHOOK_SECRET,
});

Testing

The SDK works seamlessly with test API keys:

const marmopay = new Marmopay({
  apiKey: 'mmp_test_your_test_key', // Test key
  environment: 'test',
});

// Use test phone numbers and amounts
const payment = await marmopay.payments.create({
  amount: '100.00', // Test amount
  currency: 'KES',
  customer: {
    email: '[email protected]',
    phone: '+254700000000', // Test phone
  },
});

Best Practices

1. Use Environment Variables

Never hardcode API keys in your code.

2. Always Verify Webhooks

if (!marmopay.webhooks.verify(req.body, signature)) {
  return res.status(401).send('Invalid signature');
}

3. Respond to Webhooks Quickly

app.post('/webhooks/marmopay', async (req, res) => {
  // Verify signature
  
  // Respond immediately
  res.json({ received: true });
  
  // Process async
  processWebhookAsync(event);
});

4. Implement Idempotency

const processedWebhooks = new Set();

if (processedWebhooks.has(event.data.reference)) {
  console.log('Already processed');
  return;
}

processedWebhooks.add(event.data.reference);
// Process webhook

5. Handle Errors Gracefully

try {
  await marmopay.payments.create(data);
} catch (error) {
  if (error instanceof ValidationError) {
    // Show user-friendly message
  } else {
    // Log and alert developers
  }
}

Support

  • 📧 Email: [email protected]
  • 📚 Documentation: https://docs.marmopay.com
  • 💬 Discord: https://discord.gg/marmopay
  • 🐛 Issues: https://github.com/marmopay/node-sdk/issues

License

MIT License - see LICENSE file for details

Changelog

v1.0.0 (2024-01-15)

  • Initial release
  • Payment creation and retrieval
  • Transaction management
  • Refund processing
  • Webhook verification
  • Full TypeScript support
  • Automatic retries
  • Comprehensive error handling