Skip to main content
When you use Moflay, you usually do not build directly against Safaricom callbacks. Moflay receives the Daraja callback, updates the transaction, and can then send a signed webhook to your backend.

Event model

Moflay currently exposes webhook events for:
  • payment.completed
  • payment.failed
  • customer.created
  • customer.updated
  • customer.deleted

Configure webhooks

1

Open the Webhooks page

In the dashboard, open Webhooks.
2

Create an endpoint

Use the webhook portal to add the URL that should receive Moflay events.
3

Subscribe to events

Select the payment and customer events your backend needs.
4

Store the signing secret

Save the webhook signing secret in your backend environment variables.

Verify webhook signatures

Moflay webhooks use Svix-style signing headers. Verify the request before you trust the payload.
import { Webhook } from "svix";

const secret = process.env.MOFLAY_WEBHOOK_SIGNING_SECRET!;
const body = await request.text();

const payload = new Webhook(secret).verify(body, {
  "svix-id": request.headers.get("svix-id") ?? "",
  "svix-timestamp": request.headers.get("svix-timestamp") ?? "",
  "svix-signature": request.headers.get("svix-signature") ?? "",
});

console.log(payload);

What a webhook gives you

Use webhook events to:
  • Mark orders as paid
  • Unlock access after payment
  • Send customer notifications
  • Keep your internal transaction state in sync

Safaricom callbacks vs Moflay webhooks

  • Safaricom callback: Handled by Moflay
  • Moflay webhook: Sent from Moflay to your application
This is why you can keep your integration focused on business events instead of low-level Daraja callback plumbing.

Verify the result

Your webhook setup is correct when:
  • Your endpoint receives a test or live event from Moflay
  • Signature verification succeeds
  • Your application processes the event idempotently