npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@flixora/airxpay

v0.0.5

Published

AirXPay Initialization Data activities API__for Node & Express etc.

Readme

@flixora/airxpay 🚀

npm version license downloads

Official AirXPay SDK for Node.js - Easily integrate merchant onboarding and payment services into your application.

📦 Installation

npm install @flixora/airxpay
# or
yarn add @flixora/airxpay

🔑 Environment Setup

Create a .env file in your project root:

AIRXPAY_SECRET_KEY=your_secret_key_here
AIRXPAY_CLIENT_KEY=your_client_key_here

📝 Complete Express.js Controller Example

Here's a production-ready controller showing how to integrate the SDK in your Express.js application:

// controllers/sellerController.ts
import { Request, Response } from "express";
import { AirXPay } from "@flixora/airxpay";

// 🔒 Backend keys from .env
const AIRXPAY_SECRET_KEY = process.env.AIRXPAY_SECRET_KEY || "";
const AIRXPAY_CLIENT_KEY = process.env.AIRXPAY_CLIENT_KEY || "";

if (!AIRXPAY_SECRET_KEY)
  throw new Error("AIRXPAY_SECRET_KEY is not defined in .env");
if (!AIRXPAY_CLIENT_KEY)
  throw new Error("AIRXPAY_CLIENT_KEY is not defined in .env");

/**
 * ✅ CREATE SELLER (CREATE MERCHANT)
 * frontend sends publicKey as 'publicKey' in body
 */
export const createSeller = async (req: Request, res: Response) => {
  console.log("📥 [CREATE SELLER] Request received:", new Date().toISOString());

  try {
    const { seller, publicKey } = req.body;
    console.log("📦 [CREATE SELLER] Body keys:", Object.keys(req.body));

    // 🔹 Validate required fields
    if (!seller?.merchantName || !seller?.merchantEmail) {
      return res.status(400).json({
        success: false,
        message: "merchantName and merchantEmail are required",
      });
    }
    if (!publicKey) {
      return res.status(400).json({
        success: false,
        message: "frontend public key is required",
      });
    }

    // 🔹 Prepare merchant data
    const merchantData = {
      merchantName: seller.merchantName,
      merchantEmail: seller.merchantEmail,
      merchantPhone: seller.merchantPhone,
      businessName: seller.businessName,
      businessType: seller.businessType || "individual",
      businessCategory: seller.businessCategory,
      country: seller.country || "India",
      nationality: seller.nationality || "Indian",
      dob: seller.dob,
      mode: seller.mode || "test",
      metadata: seller.metadata || {},
      kycDetails: seller.kycDetails,
      bankDetails: seller.bankDetails,
      publicKey,
    };

    console.log("🔑 [CREATE SELLER] Prepared merchant data:", {
      merchantName: merchantData.merchantName,
      merchantEmail: merchantData.merchantEmail,
      hasPublicKey: !!merchantData.publicKey,
    });

    // 🔹 Call SDK → which calls company backend → returns token + merchant
    console.log("📡 [CREATE SELLER] Calling AirXPay.flixora.createMerchant...");
    const result = await AirXPay.flixora.createMerchant(publicKey, {
      ...merchantData,
      clientKey: AIRXPAY_CLIENT_KEY,
      secretKey: AIRXPAY_SECRET_KEY,
    });

    console.log("✅ [CREATE SELLER] Merchant created successfully:", {
      merchantId: result.merchant.merchantId,
      airxpayMerchantId: result.merchant.airxpayMerchantId,
      status: result.merchant.status,
    });

    // 🔹 Return final response to frontend
    return res.status(200).json({
      success: true,
      message: "Merchant created successfully",
      merchantId: result.merchant.merchantId,
      airxpayMerchantId: result.merchant.airxpayMerchantId,
      walletId: result.merchant.walletId,
      status: result.merchant.status,
      kycStatus: result.merchant.kycStatus,
      isKycCompleted: result.merchant.isKycCompleted,
      isBankDetailsCompleted: result.merchant.isBankDetailsCompleted,
      mode: result.merchant.mode,
      token: result.token,
    });
  } catch (error: any) {
    console.error("❌ [CREATE SELLER] Error:", error);

    return res.status(error.statusCode || 500).json({
      success: false,
      message: error.message || "Failed to create merchant",
      error: error.data || null,
    });
  }
};

🔍 Controller Explanation (Step by Step)

Let me break down what's happening in the controller:

1. Environment Variables Setup

const AIRXPAY_SECRET_KEY = process.env.AIRXPAY_SECRET_KEY || "";
const AIRXPAY_CLIENT_KEY = process.env.AIRXPAY_CLIENT_KEY || "";
  • AIRXPAY_SECRET_KEY: Your secret key for authentication (never exposed to frontend)
  • AIRXPAY_CLIENT_KEY: Your client key for identification
  • Both keys are loaded from .env file for security

2. Request Validation

if (!seller?.merchantName || !seller?.merchantEmail) {
  return res.status(400).json({ success: false, message: "..." });
}
if (!publicKey) {
  return res.status(400).json({ success: false, message: "..." });
}
  • Validates that frontend sent required fields
  • Checks for merchantName, merchantEmail, and publicKey
  • Returns 400 error if any required field is missing

3. Data Preparation

const merchantData = {
  merchantName: seller.merchantName,
  merchantEmail: seller.merchantEmail,
  merchantPhone: seller.merchantPhone,
  businessName: seller.businessName,
  businessType: seller.businessType || "individual", // Default value
  country: seller.country || "India", // Default value
  nationality: seller.nationality || "Indian", // Default value
  mode: seller.mode || "test", // Default to test mode
  kycDetails: seller.kycDetails, // Optional KYC documents
  bankDetails: seller.bankDetails, // Optional bank details
  publicKey, // Frontend public key
};
  • Maps frontend data to SDK expected format
  • Sets default values for optional fields
  • Includes KYC and bank details if provided

4. SDK Call

const result = await AirXPay.flixora.createMerchant(publicKey, {
  ...merchantData,
  clientKey: AIRXPAY_CLIENT_KEY,
  secretKey: AIRXPAY_SECRET_KEY,
});
  • Calls the SDK's createMerchant method
  • Passes frontend public key and merchant data
  • Adds backend keys (clientKey, secretKey) for authentication
  • SDK internally calls company backend API

5. Response Handling

return res.status(200).json({
  success: true,
  message: "Merchant created successfully",
  merchantId: result.merchant.merchantId,
  airxpayMerchantId: result.merchant.airxpayMerchantId,
  walletId: result.merchant.walletId,
  status: result.merchant.status,
  kycStatus: result.merchant.kycStatus,
  isKycCompleted: result.merchant.isKycCompleted,
  isBankDetailsCompleted: result.merchant.isBankDetailsCompleted,
  mode: result.merchant.mode,
  token: result.token,
});
  • Returns success response to frontend
  • Includes all important merchant data:
    • merchantId: Your internal merchant ID
    • airxpayMerchantId: AirXPay's system ID
    • walletId: Merchant's wallet ID
    • status: Current merchant status
    • kycStatus: KYC verification status
    • token: Auth token for future API calls

6. Error Handling

catch (error: any) {
  return res.status(error.statusCode || 500).json({
    success: false,
    message: error.message || "Failed to create merchant",
    error: error.data || null,
  });
}
  • Catches any errors from SDK or backend
  • Returns appropriate HTTP status code
  • Sends error details to frontend

🎯 Alternative Usage Patterns

Pattern 1: Minimal Implementation

// If you only need basic merchant creation
export const quickCreateSeller = async (req: Request, res: Response) => {
  try {
    const { email, name, publicKey } = req.body;
    
    const result = await AirXPay.flixora.createMerchant(publicKey, {
      merchantName: name,
      merchantEmail: email,
      clientKey: process.env.AIRXPAY_CLIENT_KEY!,
      secretKey: process.env.AIRXPAY_SECRET_KEY!,
    });

    res.json({ success: true, token: result.token });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
};

Pattern 2: With KYC Documents

// When frontend sends KYC documents
export const createSellerWithKYC = async (req: Request, res: Response) => {
  try {
    const { seller, publicKey, kycDocs } = req.body;
    
    const result = await AirXPay.flixora.createMerchant(publicKey, {
      merchantName: seller.name,
      merchantEmail: seller.email,
      merchantPhone: seller.phone,
      kycDetails: {
        panCardUrl: kycDocs.panCard,
        aadhaarUrl: kycDocs.aadhaar,
        selfieUrl: kycDocs.selfie,
      },
      clientKey: process.env.AIRXPAY_CLIENT_KEY!,
      secretKey: process.env.AIRXPAY_SECRET_KEY!,
    });

    res.json({ success: true, data: result });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
};

Pattern 3: With Bank Details

// When frontend provides bank information
export const createSellerWithBank = async (req: Request, res: Response) => {
  try {
    const { seller, publicKey, bank } = req.body;
    
    const result = await AirXPay.flixora.createMerchant(publicKey, {
      merchantName: seller.name,
      merchantEmail: seller.email,
      bankDetails: {
        accountHolderName: bank.holderName,
        accountNumber: bank.accountNumber,
        ifscCode: bank.ifsc,
        upiId: bank.upi,
      },
      clientKey: process.env.AIRXPAY_CLIENT_KEY!,
      secretKey: process.env.AIRXPAY_SECRET_KEY!,
    });

    res.json({ success: true, data: result });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
};

Pattern 4: NestJS Controller

// sellers.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { AirXPay } from '@flixora/airxpay';

@Controller('sellers')
export class SellersController {
  @Post('create')
  async createSeller(@Body() body: any) {
    try {
      const { seller, publicKey } = body;
      
      const result = await AirXPay.flixora.createMerchant(publicKey, {
        merchantName: seller.name,
        merchantEmail: seller.email,
        clientKey: process.env.AIRXPAY_CLIENT_KEY!,
        secretKey: process.env.AIRXPAY_SECRET_KEY!,
      });

      return { success: true, data: result };
    } catch (error) {
      throw new Error(`Failed to create seller: ${error.message}`);
    }
  }
}

Pattern 5: Koa.js Middleware

// middleware/airxpay.ts
import { Context, Next } from 'koa';
import { AirXPay } from '@flixora/airxpay';

export const createSellerMiddleware = async (ctx: Context, next: Next) => {
  try {
    const { seller, publicKey } = ctx.request.body;
    
    const result = await AirXPay.flixora.createMerchant(publicKey, {
      merchantName: seller.name,
      merchantEmail: seller.email,
      clientKey: process.env.AIRXPAY_CLIENT_KEY!,
      secretKey: process.env.AIRXPAY_SECRET_KEY!,
    });

    ctx.body = { success: true, data: result };
  } catch (error) {
    ctx.status = 500;
    ctx.body = { success: false, error: error.message };
  }
};

📚 API Reference

AirXPay.flixora.createMerchant(publicKey, merchantData)

Creates a new merchant in the AirXPay system.

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | publicKey | string | ✅ | Frontend public key for authentication | | merchantData | MerchantData | ✅ | Merchant details object |

MerchantData Object:

| Field | Type | Required | Description | |-------|------|----------|-------------| | merchantName | string | ✅ | Full name of the merchant | | merchantEmail | string | ✅ | Email address | | merchantPhone | string | ❌ | Phone number (10-15 digits) | | businessName | string | ❌ | Business/Store name | | businessType | 'individual' \| 'company' | ❌ | Type of business | | mode | 'test' \| 'live' | ❌ | Environment mode | | kycDetails | KycDocuments | ❌ | KYC document URLs/info | | bankDetails | BankDetails | ❌ | Bank account details | | clientKey | string | ✅ | Your client key from env | | secretKey | string | ✅ | Your secret key from env |

Returns: Promise<MerchantResponse>

AirXPay.flixora.getMerchantStatus(token)

Fetches the current status of a merchant.

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | token | string | ✅ | Token received from createMerchant |

Returns: Promise<MerchantData> - Clean merchant data object

🎯 Features

  • Full TypeScript Support - Complete type definitions
  • 🔐 Secure - Automatic token management and refresh
  • 📡 Event Driven - Subscribe to SDK events
  • Performance Monitoring - Built-in execution time measurement
  • 🛡️ Validation - Input validation for all operations
  • 🔌 Plugin System - Extend functionality with custom plugins
  • 🚀 Framework Agnostic - Works with Express, NestJS, Koa, Fastify

📡 Events

Subscribe to SDK events for real-time updates:

import { AirXPay } from '@flixora/airxpay';

// Listen for merchant creation
AirXPay.events.on('merchantCreated', (data) => {
  console.log('New merchant created:', data);
});

// Listen for status fetches
AirXPay.events.on('merchantStatusFetched', (data) => {
  console.log('Status fetched:', data);
});

⚙️ Configuration

The SDK comes with default configuration:

{
  baseURL: 'http://172.20.10.12:7000', // API base URL
  autoRefreshToken: true // Auto-refresh auth tokens
}

🛠️ Advanced Usage

With Performance Tracking

import { measureExecutionTime } from '@flixora/airxpay/performance';

const result = await measureExecutionTime(() => 
  AirXPay.flixora.createMerchant(publicKey, merchantData)
);
// Output: "Execution time: 234 ms"

Custom Validation

import { validateMerchantPhone } from '@flixora/airxpay/rules';

if (!validateMerchantPhone('9876543210')) {
  throw new Error('Invalid phone number');
}

📋 Types

import type { 
  MerchantData,
  MerchantResponse,
  KycStatus,
  BankDetails 
} from '@flixora/airxpay';

// Use types in your code
const merchant: MerchantData = {
  merchantName: 'John Doe',
  merchantEmail: '[email protected]',
  // ...
};

🔧 Error Handling

import { AirXPayError } from '@flixora/airxpay/errors';

try {
  await AirXPay.flixora.createMerchant(publicKey, merchantData);
} catch (error) {
  if (error instanceof AirXPayError) {
    console.error(`SDK Error [${error.code}]:`, error.message);
  } else {
    console.error('Unexpected error:', error);
  }
}

📝 License

MIT © Flixora

🤝 Support

🚦 Status

Last Commit


Made with ❤️ by Flixora Team