Angular cannot handle Paystack webhooks. Webhooks are server-to-server HTTP POST requests from Paystack to your backend. Angular runs in the browser and has no server endpoint. You need a backend (Node.js, Python, PHP, Go, or any server framework) to receive and verify webhooks. Your Angular app checks the payment status by querying your backend API.
Webhooks are HTTP POST requests that Paystack sends from its servers to a URL on your server. The destination is a backend endpoint like https://api.yourapp.com/webhooks/paystack. That endpoint must be a running server process that can accept incoming HTTP connections over HTTPS.
Angular is a frontend JavaScript framework. It renders components in the user's browser. A browser cannot accept incoming HTTP connections from Paystack's servers. There is no port to listen on, no public URL to register, and no way for Paystack to reach a user's browser.
This applies to all Angular versions. It also applies to every other frontend-only framework: React, Vue, Svelte (without SvelteKit). Webhooks are strictly a backend concern.
Here is how a Paystack integration works when your frontend is an Angular SPA:
Customer Browser (Angular SPA)
|
| 1. Opens Paystack Popup, customer pays
v
Paystack Servers
|
| 2. Sends webhook POST to your backend
v
Your Backend (Express, Django, Laravel, etc.)
|
| 3. Verifies signature, processes event, updates DB
v
Database
^
| 4. Angular app fetches updated state via HttpClient
|
Customer Browser (Angular SPA)
The Angular app and the webhook handler are completely separate. They share the database, but that is their only connection.
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
After the customer completes payment, your Angular app polls your backend to check the order status:
// src/app/services/order.service.ts
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { firstValueFrom } from 'rxjs';
import { environment } from '../../environments/environment';
@Injectable({ providedIn: 'root' })
export class OrderService {
private http = inject(HttpClient);
async pollStatus(reference: string, maxAttempts: number): Promise<string> {
for (var i = 0; i < maxAttempts; i++) {
var result = await firstValueFrom(
this.http.get<{ status: string }>(
environment.apiUrl + '/api/orders/status',
{ params: { reference: reference } }
)
);
if (result.status === 'paid') {
return 'paid';
}
// Wait 2 seconds before next attempt
await new Promise(function(resolve) { setTimeout(resolve, 2000); });
}
return 'pending';
}
}
The Angular app asks your backend: "Has the webhook confirmed this payment?" It does not call the Paystack API directly. It simply checks what your backend already knows.
You need a backend to handle Paystack webhooks. Here are guides for every major framework:
Node.js:
Python:
PHP:
Other:
Serverless:
If you are already using NestJS, it is the natural choice because it uses TypeScript and decorators that feel familiar to Angular developers.
1. Trying to create an Angular "webhook listener." Angular HttpClient sends requests. It does not receive them. There is no way to set up an HTTP server in the browser.
2. Putting the Paystack secret key in environment.ts. Angular environment files are compiled into the JavaScript bundle and visible in the browser. Your secret key will be exposed. Keep it on the server only.
3. Calling the Paystack Verify API from Angular. This requires the secret key in the Authorization header. Call it from your backend instead.
4. Treating the popup callback as final confirmation. The popup callback runs in the browser and can be faked or missed. The webhook is the reliable source of truth. Your backend should update orders via webhook, and your Angular app should check the backend for the final status.
5. Not handling the timing gap. Sometimes the webhook arrives at your backend before the popup callback finishes in Angular. Sometimes the popup callback finishes first. Your Angular app should poll for the confirmed status rather than assuming a fixed order of events.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course