Guides

Real-time Payment Notifications

Learn about the multiple notification methods available in NakaPay React components for instant payment status updates.

Last updated on June 1, 2025

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.

🎯 Key Benefits:
  • 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:

  1. Ably (if useAbly={true}) - Most reliable, cloud-based
  2. WebSocket (if useWebhooks={true}) - Direct connection to your server
  3. Server-Sent Events (if useSSE={true}) - HTTP streaming
  4. 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

  1. Sign up for an Ably account
  2. Create a new app and get your API key
  3. Configure NakaPay webhooks to publish to Ably channel payment-{paymentId}
  4. 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:

⚡ Real-time connected (59:32)
Waiting for payment... (59:32)
Connecting...
Checking payment... (59:32)

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

MethodLatencyReliabilitySetupCost
Ably~100ms99.999%Medium$$$
WebSocket~50ms95-99%Complex$
SSE~200ms90-95%Easy$
Polling2-5s99%NoneFree

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: