Payment Events
Event-driven payment status tracking with on, once, and wait
PaymentInstance Events
The PaymentInstance returned by collectPayment() emits events as the payment progresses through its lifecycle.
const payment = nile.collectPayment({ /* ... */ });
payment.on("processing", handleProcessing);
payment.on("success", handleSuccess);
payment.on("failed", handleFailed);
payment.on("cancelled", handleCancelled);
payment.on("error", handleError);Event Reference
| Event | Payload | When It Fires |
|---|---|---|
processing | Transaction | Payment initiated, awaiting customer confirmation |
success | Transaction | Payment completed successfully |
failed | Transaction | Payment failed (customer rejected or timeout) |
cancelled | Transaction | Payment cancelled by customer or system |
error | PaymentError | Network error or polling timeout during lifecycle |
on(event, handler)
Registers a handler for an event. Handler is called every time the event fires.
payment.on("success", (tx) => {
console.log("Transaction ID:", tx.transactionId);
});once(event, handler)
Registers a handler that fires only once, then automatically removes itself.
payment.once("success", (tx) => {
// This runs only on first success
fulfillOrder(tx.metadata.orderId);
});off(event, handler)
Removes a previously registered handler.
const handler = (tx) => console.log(tx.status);
payment.on("success", handler);
// ... later
payment.off("success", handler);Chaining
Event methods return the PaymentInstance, enabling chaining.
payment
.on("success", handleSuccess)
.on("failed", handleFailed)
.on("cancelled", handleCancelled)
.on("error", handleError);wait()
Returns a Promise<Transaction> that resolves when a terminal state is reached (success, failed, or cancelled). Rejects on error or timeout.
try {
const tx = await payment.wait();
if (tx.status === "successful") {
// Order confirmed
} else {
// Handle failed/cancelled
}
} catch (error) {
// Network error or timeout exceeded
}Express Route Handler Example
import express from "express";
import { createNilePay } from "@nilepay/sdk";
const app = express();
const nile = createNilePay({ /* config */ });
app.post("/api/pay", async (req, res) => {
const { amount, phone, orderId } = req.body;
const reference = crypto.randomUUID();
const payment = nile.collectPayment({
amount,
currency: "UGX",
customer: { phone },
reference,
metadata: { orderId },
});
// Respond immediately, process async
res.json({ reference, status: "initiated" });
// Handle outcome asynchronously
payment
.on("success", (tx) => {
updateOrderStatus(orderId, "paid");
sendConfirmationEmail(tx.customer.email);
})
.on("failed", (tx) => {
updateOrderStatus(orderId, "payment_failed");
})
.on("error", (err) => {
console.error("Payment error:", err.message);
// Implement retry logic if needed
});
});When to Use Events vs wait()
| Scenario | Approach |
|---|---|
| HTTP API with immediate response | Use on() handlers, respond 202 Accepted |
| Background job/processor | Use on() for state updates |
| CLI or script | Use await payment.wait() |
| Need specific state only | Use once() |
Transaction Payload
interface Transaction {
transactionId: string;
reference: string;
status: TransactionStatus;
amount: number;
currency: string;
providerReference?: string;
createdAt: string;
updatedAt: string;
}
type TransactionStatus =
| "pending"
| "processing"
| "successful"
| "failed"
| "cancelled";