Handle Paystack Webhooks in Angular
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.
Why Angular Cannot Receive Webhooks
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.
The Correct Architecture
Here is how a Paystack integration works when your frontend is an Angular SPA:
- Angular (frontend): Opens the Paystack checkout popup. The customer pays.
- Paystack: Processes the payment and sends a webhook POST to your backend server.
- Your backend: Receives the webhook, verifies the HMAC SHA512 signature, processes the event, and updates the database.
- Angular (frontend): Polls your backend API or uses WebSocket to check the payment status and update the UI.
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.
What Angular Does After Payment
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.
Choose a Backend for Webhook Handling
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.
Mistakes Angular Developers Make with Webhooks
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.
Key Takeaways
- ✓Angular is a client-side framework that runs in the browser. It cannot receive Paystack webhooks.
- ✓Webhooks are server-to-server HTTP POST requests that need a backend endpoint with a public URL.
- ✓Your backend receives the webhook, verifies the HMAC SHA512 signature, and updates your database.
- ✓Your Angular frontend checks the updated state from your backend via HttpClient calls.
- ✓Never expose your Paystack secret key in Angular code. Angular environment files are bundled into the client.
- ✓Choose any backend framework for webhook handling: Express, NestJS, Django, FastAPI, Laravel, Go, Rails, Spring Boot, or ASP.NET Core.
Frequently Asked Questions
- Can Angular receive Paystack webhooks?
- No. Angular runs in the browser and cannot accept incoming HTTP POST requests from Paystack. You need a backend server to receive webhooks.
- What is the best backend for Paystack webhooks if I use Angular?
- NestJS is a natural fit for Angular developers because it uses TypeScript, decorators, and a similar module-based architecture. Express is simpler if you want something lightweight. Django or Laravel work well if you prefer Python or PHP.
- How does my Angular app know when a payment is confirmed via webhook?
- After the customer pays, your Angular app polls your backend API to check the order status. Your backend was updated by the webhook. You can also use WebSockets or Server-Sent Events for real-time updates.
- Is it safe to store the Paystack public key in Angular environment files?
- Yes, the public key is safe to expose. It is designed to be used in client-side code. Only the secret key must be kept on the server.
- Can I use Angular Universal to handle webhooks server-side?
- Angular Universal is for server-side rendering of Angular pages, not for creating API endpoints. While you could technically create a custom Express middleware alongside Universal, it is better to use a proper backend framework for API endpoints and webhook handlers.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon