@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-sdkyarn add @marmopay/node-sdkpnpm add @marmopay/node-sdkQuick 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.paymentUrlConfiguration
Required
apiKey- Your Marmopay API key (get from dashboard)
Optional
environment-'test'or'live'(default:'test')webhookSecret- Your webhook secret for signature verificationbaseUrl- 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:
amountmust 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:
- Log in to your Marmopay dashboard at https://marmopay.com
- Navigate to Settings → Webhooks
- Click "Rotate Secret" to generate a new webhook secret
- 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=testLoad 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 webhook5. 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
