Real-time Payment Notifications
Learn about the multiple notification methods available in NakaPay React components for instant payment status updates.
Overview
NakaPay React components support multiple real-time notification methods to ensure reliable payment status updates. The components automatically prioritize the most reliable method available and gracefully fall back to alternatives when needed.
- Instant payment confirmations without page refreshes
- Automatic fallback mechanisms ensure reliability
- Multiple transport methods for different deployment scenarios
- Built-in connection status indicators
Notification Priority Order
The components try real-time methods in this order, providing reliable fallbacks:
- Ably (if
useAbly={true}
) - Most reliable, cloud-based - WebSocket (if
useWebhooks={true}
) - Direct connection to your server - Server-Sent Events (if
useSSE={true}
) - HTTP streaming - Polling (automatic fallback) - Checks payment status every 2 seconds
1. Ably (Recommended)
Ably provides the most reliable real-time updates using cloud infrastructure with 99.999% uptime guarantee.
✅ Advantages
- • 99.999% uptime guarantee
- • Global edge network
- • Automatic reconnection
- • Message delivery guarantees
- • No server maintenance required
⚠️ Requirements
- • Ably account and API key
- • Webhook configuration
- • Monthly Ably subscription
1import { NakaPayButton } from 'nakapay-react';
2
3<NakaPayButton
4 amount={50000}
5 description="Product purchase"
6 useAbly={true}
7 ablyApiKey="your-ably-api-key"
8 onPaymentSuccess={(payment) => {
9 console.log('Payment completed via Ably!', payment);
10 // Payment is automatically confirmed
11 // Modal closes after 3 seconds
12 }}
13 onPaymentError={(error) => {
14 console.error('Payment failed:', error);
15 }}
16/>
Setup Instructions
- Sign up for an Ably account
- Create a new app and get your API key
- Configure NakaPay webhooks to publish to Ably channel
payment-{paymentId}
- Use your Ably API key in the React component
2. WebSocket Connection
Direct WebSocket connection to your webhook server for low-latency updates.
✅ Advantages
- • Very low latency
- • Full control over infrastructure
- • Bidirectional communication
- • No third-party dependencies
⚠️ Requirements
- • WebSocket server implementation
- • Manual reconnection handling
- • Server maintenance and scaling
1import { NakaPayButton } from 'nakapay-react';
2
3<NakaPayButton
4 amount={50000}
5 description="Product purchase"
6 useWebhooks={true}
7 webhookUrl="ws://localhost:3002"
8 onPaymentSuccess={(payment) => {
9 console.log('Payment completed via WebSocket!', payment);
10 }}
11/>
WebSocket Server Example
1// Example WebSocket server (Node.js with Socket.IO)
2const express = require('express');
3const http = require('http');
4const socketIo = require('socket.io');
5
6const app = express();
7const server = http.createServer(app);
8const io = socketIo(server, {
9 cors: {
10 origin: "http://localhost:3000",
11 methods: ["GET", "POST"]
12 }
13});
14
15app.use(express.json());
16
17// Handle client connections
18io.on('connection', (socket) => {
19 console.log('Client connected:', socket.id);
20
21 // Join payment-specific room
22 socket.on('join-payment-room', (paymentId) => {
23 socket.join(`payment-${paymentId}`);
24 console.log(`Client joined room: payment-${paymentId}`);
25 });
26
27 socket.on('disconnect', () => {
28 console.log('Client disconnected:', socket.id);
29 });
30});
31
32// Webhook endpoint from NakaPay
33app.post('/webhooks/nakapay', (req, res) => {
34 const event = req.body;
35
36 if (event.type === 'payment.completed') {
37 // Notify all clients in the payment room
38 io.to(`payment-${event.data.paymentId}`).emit('payment-completed', {
39 paymentId: event.data.paymentId,
40 status: 'completed'
41 });
42 }
43
44 res.status(200).send('OK');
45});
46
47server.listen(3002, () => {
48 console.log('WebSocket server running on port 3002');
49});
3. Server-Sent Events (SSE)
HTTP streaming for one-way server-to-client communication, ideal for serverless platforms.
✅ Advantages
- • HTTP-based (firewall friendly)
- • Automatic reconnection
- • Works with serverless platforms
- • Simple implementation
⚠️ Limitations
- • One-way communication only
- • Limited concurrent connections
- • Browser connection limits
1import { NakaPayButton } from 'nakapay-react';
2
3<NakaPayButton
4 amount={50000}
5 description="Product purchase"
6 useSSE={true}
7 onPaymentSuccess={(payment) => {
8 console.log('Payment completed via SSE!', payment);
9 }}
10/>
SSE Endpoint Example
1// Example SSE endpoint (Next.js API route)
2// pages/api/payments/stream.js or app/api/payments/stream/route.js
3
4export async function GET(request) {
5 const { searchParams } = new URL(request.url);
6 const paymentId = searchParams.get('paymentId');
7
8 const stream = new ReadableStream({
9 start(controller) {
10 // Send initial connection message
11 controller.enqueue(`data: {"type":"connected","paymentId":"${paymentId}"}
12
13`);
14
15 // Set up payment status listener
16 // This would typically listen to your database changes
17 // or subscribe to webhook events
18 const checkPaymentStatus = setInterval(async () => {
19 try {
20 const payment = await getPaymentStatus(paymentId);
21 if (payment.status === 'completed') {
22 controller.enqueue(`data: {"type":"payment-update","paymentId":"${paymentId}","event":"payment.completed"}
23
24`);
25 clearInterval(checkPaymentStatus);
26 controller.close();
27 }
28 } catch (error) {
29 console.error('SSE error:', error);
30 }
31 }, 1000);
32
33 // Clean up on client disconnect
34 request.signal.addEventListener('abort', () => {
35 clearInterval(checkPaymentStatus);
36 controller.close();
37 });
38 }
39 });
40
41 return new Response(stream, {
42 headers: {
43 'Content-Type': 'text/event-stream',
44 'Cache-Control': 'no-cache',
45 'Connection': 'keep-alive',
46 },
47 });
48}
4. Polling (Automatic Fallback)
When no real-time method is configured, components automatically fall back to polling your status endpoint.
✅ Advantages
- • Universal compatibility
- • No additional setup required
- • Simple implementation
- • Reliable fallback
⚠️ Trade-offs
- • Higher latency (2-5 seconds)
- • More API requests
- • Less responsive user experience
1import { NakaPayButton } from 'nakapay-react';
2
3<NakaPayButton
4 amount={50000}
5 description="Product purchase"
6 pollInterval={3000} // Check every 3 seconds
7 statusEndpoint="/api/payment-status"
8 onPaymentSuccess={(payment) => {
9 console.log('Payment completed via polling!', payment);
10 }}
11/>
Status Endpoint Example
1// Backend status endpoint (Express.js)
2app.get('/api/payment-status/:id', async (req, res) => {
3 try {
4 const paymentId = req.params.id;
5 const payment = await nakaPay.getPaymentStatus(paymentId);
6
7 res.json({
8 id: payment.id,
9 status: payment.status, // 'pending', 'completed', 'failed', 'expired'
10 amount: payment.amount,
11 description: payment.description
12 });
13 } catch (error) {
14 console.error('Error checking payment status:', error);
15 res.status(500).json({ error: error.message });
16 }
17});
Deployment Scenarios
Vercel / Serverless Platforms
For serverless deployments, SSE or Ably are recommended:
1// Recommended for Vercel
2<NakaPayButton
3 amount={50000}
4 description="Product purchase"
5 useAbly={true} // or useSSE={true}
6 ablyApiKey="your-ably-api-key"
7 onPaymentSuccess={handleSuccess}
8/>
Traditional Server Deployments
With dedicated servers, WebSocket provides the best performance:
1// Recommended for VPS/dedicated servers
2<NakaPayButton
3 amount={50000}
4 description="Product purchase"
5 useWebhooks={true}
6 webhookUrl="ws://your-server.com:3002"
7 onPaymentSuccess={handleSuccess}
8/>
Development Environment
For local development, polling is the simplest approach:
1// Simple for development
2<NakaPayButton
3 amount={50000}
4 description="Product purchase"
5 pollInterval={2000}
6 onPaymentSuccess={handleSuccess}
7/>
Connection Status Indicators
The components automatically show connection status to users:
Troubleshooting
Common Issues
❌ Real-time connection fails
Components automatically fall back to polling
- Check API keys and webhook URLs
- Verify CORS settings for WebSocket connections
- Ensure webhook endpoints are accessible
⚠️ Slow payment detection
Using polling fallback
- Enable a real-time method (Ably recommended)
- Reduce polling interval if needed
- Check webhook configuration
Debug Mode
Enable console logging to debug connection issues:
1// Add this to see detailed connection logs
2<NakaPayButton
3 amount={50000}
4 description="Product purchase"
5 useAbly={true}
6 ablyApiKey="your-ably-api-key"
7 onPaymentSuccess={(payment) => {
8 console.log('Payment successful:', payment);
9 }}
10/>
11
12// Check browser console for messages like:
13// "NakaPay: Connecting to Ably for payment abc123"
14// "NakaPay: Connected to Ably"
15// "NakaPay: Payment abc123 completed via Ably!"
Performance Comparison
Method | Latency | Reliability | Setup | Cost |
---|---|---|---|---|
Ably | ~100ms | 99.999% | Medium | $$$ |
WebSocket | ~50ms | 95-99% | Complex | $ |
SSE | ~200ms | 90-95% | Easy | $ |
Polling | 2-5s | 99% | None | Free |
Best Practices
Production Recommendations
- Use Ably for production - Most reliable with guaranteed message delivery
- Always have polling as fallback - Components handle this automatically
- Monitor connection status - Use the built-in status indicators
- Handle network failures gracefully - Components reconnect automatically
- Test with network throttling - Ensure fallbacks work properly
Development Tips
- Start with polling - Simplest for initial development
- Add real-time later - Easy to upgrade existing implementations
- Use browser dev tools - Monitor WebSocket/SSE connections
- Check console logs - Components log connection status
Further Reading
For more details, check out these related resources:
- React Components - Complete component documentation
- Webhooks - Setting up webhook endpoints
- API Reference - Backend API documentation
- SDK Guide - Server-side implementation