Code Examples
Real-world examples to help you get started
Basic Payment Charge
Initiate a simple M-Pesa payment charge:
import { pesastream } from '@/lib/pesastream';
async function processPayment(phone: string, amount: number) {
try {
const payment = await pesastream.charge({
amount: amount,
currency: 'KES',
phone: phone,
description: 'Order #123'
});
console.log('Payment initiated:', payment.transactionId);
return payment;
} catch (error) {
console.error('Payment failed:', error);
throw error;
}
}React Payment Component
Build a reusable payment component:
'use client';
import { useState } from 'react';
import { Loader } from 'lucide-react';
export function PaymentButton({ amount }: { amount: number }) {
const [phone, setPhone] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const [success, setSuccess] = useState('');
const handlePayment = async () => {
setLoading(true);
setError('');
setSuccess('');
try {
const response = await fetch('/api/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone, amount })
});
if (!response.ok) throw new Error('Payment failed');
const data = await response.json();
setSuccess(`Payment processing: ${data.transactionId}`);
} catch (err) {
setError(err instanceof Error ? err.message : 'Payment error');
} finally {
setLoading(false);
}
};
return (
<div className="space-y-4">
<input
type="tel"
placeholder="+254712345678"
value={phone}
onChange={(e) => setPhone(e.target.value)}
className="w-full px-4 py-2 border rounded-lg"
/>
<button
onClick={handlePayment}
disabled={loading}
className="w-full bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 disabled:opacity-50"
>
{loading ? <Loader className="animate-spin" /> : `Pay KES ${amount}`}
</button>
{error && <p className="text-red-600">{error}</p>}
{success && <p className="text-green-600">{success}</p>}
</div>
);
}API Route Handler
Create an API endpoint to handle payments:
// app/api/payments/route.ts
import { pesastream } from '@/lib/pesastream';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const { phone, amount } = await request.json();
if (!phone || !amount) {
return NextResponse.json(
{ error: 'Phone and amount required' },
{ status: 400 }
);
}
try {
const payment = await pesastream.charge({
amount,
currency: 'KES',
phone,
description: `Payment for Order`
});
return NextResponse.json(payment);
} catch (error) {
return NextResponse.json(
{ error: 'Payment processing failed' },
{ status: 500 }
);
}
}Send Payout
Send money to a beneficiary:
async function sendPayout(phone: string, amount: number) {
try {
const payout = await pesastream.payout({
amount: amount,
phone: phone,
reference: `salary-2024-${Date.now()}`
});
console.log('Payout sent:', payout.payoutId);
return payout;
} catch (error) {
console.error('Payout failed:', error);
throw error;
}
}Query Transaction Status
Check the status of a transaction:
async function getTransactionStatus(transactionId: string) {
try {
const transaction = await pesastream.getTransaction(transactionId);
console.log('Status:', transaction.status);
console.log('Amount:', transaction.amount);
console.log('Timestamp:', transaction.createdAt);
return transaction;
} catch (error) {
console.error('Failed to fetch transaction:', error);
throw error;
}
}