Implementing Dynamic QR Code Payments with Fonepay Nepal in Node.js: A Complete Developer Guide

Digital payments have revolutionized the way we handle transactions, and in Nepal, Fonepay stands as one of the leading payment gateways enabling seamless digital transactions. In this comprehensive guide, we’ll explore how to implement Fonepay’s dynamic QR code payment system using Node.js, providing you with a complete understanding of the integration process.

What is Fonepay Dynamic QR Code?

Fonepay’s Dynamic QR Code system allows merchants to generate unique QR codes for each transaction with specific amounts and transaction details. Unlike static QR codes that have fixed amounts, dynamic QR codes are generated on-the-fly for each payment request, making them ideal for e-commerce platforms and varying transaction amounts.

Prerequisites

Before diving into the implementation, ensure you have:

  • Node.js installed (version 14 or higher)
  • A Fonepay merchant account with API credentials
  • Basic knowledge of JavaScript/TypeScript
  • Understanding of REST APIs and HTTP requests

Required Dependencies

First, let’s install the necessary packages:

npm install axios crypto dotenv xml2js
  • axios: For making HTTP requests to Fonepay APIs
  • crypto: For generating HMAC-SHA512 hashes for security
  • dotenv: For managing environment variables
  • xml2js: For parsing XML responses from Fonepay

Environment Configuration

Create a .env file with your Fonepay credentials:

# Fonepay API URLs
FONEPAY_DYNAMICQR_URL=https://merchantapi.fonepay.com/api/merchant/merchantDetailsForThirdParty
FONEPAY_PG_URL=https://clientapi.fonepay.com
# Merchant Credentials
FONEPAY_PG_MERCHANT_CODE=your_merchant_code ( Call your bank to get the secret key)
FONEPAY_PG_MERCHANT_SECRET=your_merchant_secret ( Call your bank to get the secret key)
FONEPAY_USERNAME=your_username (Use fonepay login username)
FONEPAY_PASSWORD=your_password (use fonepay login password)

# Application URLs
CLIENT_URL=http://localhost:3000

Core Implementation

1. Setting Up the Payment Service

Let’s start by creating our main payment service class:

const crypto = require('crypto');
const axios = require('axios');
const xml2js = require('xml2js');

class FonepayService {
  constructor() {
    this.merchantCode = process.env.FONEPAY_PG_MERCHANT_CODE;
    this.merchantSecret = process.env.FONEPAY_PG_MERCHANT_SECRET;
    this.username = process.env.FONEPAY_USERNAME;
    this.password = process.env.FONEPAY_PASSWORD;
    this.dynamicQrUrl = process.env.FONEPAY_DYNAMICQR_URL;
    this.pgUrl = process.env.FONEPAY_PG_URL;
  }
}

2. Generating Dynamic QR Codes

The core function for generating dynamic QR codes involves creating a secure hash and making an API request to Fonepay:

async generateQrCodeUrl(transactionId, amount, remarks1, remarks2) {
  try {
    const url = `${this.dynamicQrUrl}/thirdPartyDynamicQrDownload`;
    
    // Create data validation hash
    const dataToHash = `${amount},${transactionId},${this.merchantCode},${remarks1},${remarks2}`;
    const dataValidation = crypto
      .createHmac('sha512', this.merchantSecret)
      .update(dataToHash)
      .digest('hex');

    // Prepare payload
    const payload = {
      amount: amount,
      remarks1: remarks1,
      remarks2: remarks2,
      prn: transactionId, // Payment Reference Number
      merchantCode: this.merchantCode,
      dataValidation: dataValidation,
      username: this.username,
      password: this.password,
    };

    const headers = {
      'Content-Type': 'application/json',
    };

    const response = await axios.post(url, payload, { headers });
    return response.data;
  } catch (error) {
    throw new Error(`Failed to generate QR code: ${error.message}`);
  }
}

Key Components Explained:

  • dataToHash: A concatenated string of payment details used for security validation
  • dataValidation: HMAC-SHA512 hash ensuring data integrity
  • PRN (Payment Reference Number): Unique identifier for each transaction
  • remarks1 & remarks2: Additional information fields for the transaction

3. Payment Verification System

After a customer scans the QR code and makes payment, you need to verify the transaction status:

async verifyPaymentQR(prn) {
  try {
    const url = `${this.dynamicQrUrl}/thirdPartyDynamicQrGetStatus`;
    
    // Create validation hash for verification
    const dataToHash = `${prn},${this.merchantCode}`;
    const dataValidation = crypto
      .createHmac('sha512', this.merchantSecret)
      .update(dataToHash)
      .digest('hex');

    const payload = {
      prn: prn,
      merchantCode: this.merchantCode,
      dataValidation: dataValidation,
      username: this.username,
      password: this.password,
    };

    const response = await axios.post(url, payload);
    return response.data;
  } catch (error) {
    console.error('Error verifying QR code:', error);
    return { success: false, message: error.message };
  }
}

Security Best Practices

  1. Environment Variables: Never expose your merchant secret in client-side code
  2. HTTPS: Always use HTTPS in production for secure communication
  3. Input Validation: Validate all input parameters before processing
  4. Hash Verification: Always verify the integrity of responses using HMAC hashes
  5. Timeout Handling: Implement proper timeout mechanisms for API calls
  6. Error Logging: Log errors securely without exposing sensitive information

Production Deployment Checklist

Before deploying to production:

  •  Update all environment variables with production credentials
  •  Change API URLs to production endpoints
  •  Implement proper logging and monitoring
  •  Set up SSL certificates
  •  Configure proper CORS settings
  •  Implement rate limiting
  •  Set up database for transaction logging
  •  Test with small amounts first

Conclusion

Implementing Fonepay’s dynamic QR code system in Node.js provides a robust foundation for digital payments in Nepal. The system offers flexibility for both mobile QR code payments and web-based redirect payments, making it suitable for various business models.

Key takeaways from this implementation:

  • Security is paramount – always validate and hash your data
  • Implement proper error handling and user feedback
  • Use environment variables for sensitive configuration
  • Test thoroughly before production deployment
  • Monitor transaction flows and implement proper logging

This implementation provides a solid starting point that you can extend based on your specific business requirements. Remember to stay updated with Fonepay’s API documentation as they may introduce new features or changes to existing endpoints.

Happy coding, and may your digital payments flow smoothly!

2 thoughts on “Implementing Dynamic QR Code Payments with Fonepay Nepal in Node.js: A Complete Developer Guide”

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top