Frontend

Browser SDK

Add hosted M-Pesa checkout to any website. Drop in a CDN script, pass a payment account identifier, and let PayNexus handle the STK Push flow in a secure popup.

How It Works

The Browser SDK uses a hosted checkout flow — your page never touches API keys, and PayNexus handles the M-Pesa interaction securely.

1

Add the CDN Script

Load PayNexus from the CDN on your website. No npm install or build step required.

2

Open Hosted Checkout

Pass your accountId, amount, description, and return/cancel URLs to open the M-Pesa payment popup.

3

Receive the Result

Redirect the customer or unlock content after payment completes. Handle cancellations gracefully.

Quick Start

Add M-Pesa checkout to any page in under 5 minutes.

1. Load the CDN

html

2. Initialize and Open Checkout

javascript
const checkout = PayNexusHostedCheckout();

document.getElementById('payBtn').addEventListener('click', async () => {
  try {
    const result = await checkout.open({
      accountId: 'ACC_ZVTDYYYL',
      amount: 100,
      description: 'Premium Article Access - AI Future',
      returnUrl: 'https://example.com/thanks.html',
      cancelUrl: 'https://example.com/cancelled.html',
    });

    console.log('Payment completed:', result.reference, result.amount);
    window.location.href = 'thanks.html';
  } catch (error) {
    if (error.code === 'cancelled') {
      window.location.href = 'cancelled.html';
    } else {
      alert('Payment initialization failed. Please try again.');
    }
  }
});

3. Add a Trigger Button

html

Use Your Payment Account Identifier

The hosted checkout flow uses accountId — the identifier for the payment account receiving the money. This keeps API keys completely out of the page.

No API Keys in Your HTML

The hosted checkout flow does not require publishing secret or public API keys in your HTML. Only the accountId is needed, which is safe for client-side use.

Find your accountId in the PayNexus dashboard under Payment Accounts. It looks like this:

text
Account ID: ACC_ZVTDYYYL

Popup vs Redirect

The Browser SDK supports two checkout modes depending on your UX needs:

Popup Mode

Uses checkout.open() to launch the M-Pesa flow in a centered popup. The customer stays on your page and can resume after payment.

javascript
const result = await checkout.open({
  accountId: 'ACC_ZVTDYYYL',
  amount: 100,
  description: 'Premium Article',
  returnUrl: 'https://example.com/thanks',
  cancelUrl: 'https://example.com/cancelled'
});

Redirect Mode

Uses checkout.redirect() for a full-page hosted checkout. Ideal for simple flows where you want the customer on PayNexus-hosted pages.

javascript
checkout.redirect({
  accountId: 'ACC_ZVTDYYYL',
  amount: 100,
  description: 'Premium Article',
  returnUrl: 'https://example.com/thanks',
  cancelUrl: 'https://example.com/cancelled'
});

Configuration Options

Pass the following options to checkout.open() or checkout.redirect():

Option Type Required Description
accountId string Yes Your PayNexus payment account identifier (e.g. ACC_ZVTDYYYL).
amount number Yes Payment amount in KES (minimum 1).
description string No Payment description shown to the customer during STK Push.
returnUrl string No URL to redirect to after successful payment.
cancelUrl string No URL to redirect to if the customer cancels or the payment fails.
reference string No Custom payment reference (invoice ID, order number, etc.). Auto-generated if omitted.
phoneNumber string No Pre-fill the customer's phone number (2547... format) to skip the entry step.

Handling the Result

After the customer completes or cancels the payment, the SDK resolves or rejects the promise accordingly.

Success Result

javascript
const result = await checkout.open({...});

console.log(result);
// {
//   reference: "PAY_abc123xyz",
//   amount: 100,
//   status: "completed",
//   phoneNumber: "254712345678",
//   accountId: "ACC_ZVTDYYYL"
// }

Error Handling

javascript
try {
  const result = await checkout.open({...});
} catch (error) {
  switch (error.code) {
    case 'cancelled':
      // Customer closed popup or clicked cancel
      window.location.href = cancelUrl;
      break;
    case 'failed':
      // Payment failed (insufficient funds, timeout, etc.)
      showError('Payment failed. Please try again.');
      break;
    case 'network':
      // Network error contacting PayNexus
      showError('Connection issue. Check your internet and retry.');
      break;
    default:
      showError('Payment initialization failed. Please try again.');
  }
}
Error Code Meaning Suggested Action
cancelled Customer closed the popup or navigated away Redirect to cancelUrl
failed Payment failed (insufficient funds, timeout, wrong PIN) Show retry option
network Network error or PayNexus unreachable Retry after connectivity is restored
invalid_params Missing or invalid checkout configuration Check accountId, amount, and URLs
account_not_found The accountId does not exist or is inactive Verify account ID in dashboard

Use Cases

The Browser SDK is ideal for any scenario where you want to collect M-Pesa payments without managing payment infrastructure:

Premium Content

Unlock articles, videos, or downloads after one-time payment.

Event Tickets

Sell tickets for events, webinars, and workshops.

Donations

Accept contributions with custom or fixed amounts.

Digital Products

Sell software, templates, or digital goods.

Course Enrollments

Collect fees for online courses or training.

Service Fees

Charge for consultations, bookings, or on-demand services.

Security Notes

The Browser SDK is designed with security as the top priority:

API keys never touch the browser

The hosted checkout runs on PayNexus servers. Only your accountId is needed, which is not a secret.

STK Push is served from PayNexus domains

The actual M-Pesa authorization happens on PayNexus-hosted pages, not on your domain.

Webhook verification for server-side confirmation

Always verify payment status server-side using the PayNexus API or webhooks rather than trusting only the frontend result.

Validate returnUrl and cancelUrl

Use HTTPS URLs you control. Avoid accepting arbitrary URLs from user input to prevent open redirect vulnerabilities.

Always Verify Server-Side

While the SDK result is reliable for UX flows, you should always confirm payment status via the PayNexus API or webhooks before delivering goods or services. Never trust only the client-side result.

Verifying Payments Server-Side

Use the Payment Reference returned by the SDK to confirm the payment status from your backend:

javascript
const response = await fetch(
  'https://paynexus.co.ke/api/payments/' + reference,
  {
    headers: {
      'X-API-Key': 'sk_...'
    }
  }
);

const transaction = await response.json();
if (transaction.data.status === 'completed') {
  // Deliver the product / service
}
php
$ch = curl_init();

curl_setopt_array($ch, [
  CURLOPT_URL => 'https://paynexus.co.ke/api/payments/' . $reference,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'X-API-Key: sk_...'
  ]
]);

$response = curl_exec($ch);
$transaction = json_decode($response, true);

if ($transaction['data']['status'] === 'completed') {
  // Deliver the product / service
}
python
import requests

response = requests.get(
    'https://paynexus.co.ke/api/payments/' + reference,
    headers={'X-API-Key': 'sk_...'}
)

transaction = response.json()
if transaction['data']['status'] == 'completed':
    # Deliver the product / service
    pass

Build Faster

Add M-Pesa checkout to any website today. No server code required for basic checkout.

Ready to integrate?

Grab your accountId from the PayNexus Dashboard and drop the CDN script into your page. You'll be accepting M-Pesa payments in minutes.