Skip to Content
SDKsJavaScript / TypeScript

JavaScript / TypeScript SDK

TypeScript/JavaScript client library for the QPay V2 API. Uses the native fetch API — works in Node.js 18+ and modern browsers. Automatic camelCase/snake_case conversion between JS and the QPay API.

npm GitHub

Installation

npm install qpay-js

Or with other package managers:

yarn add qpay-js pnpm add qpay-js

Configuration

From Environment Variables

Set the following variables, then call loadConfigFromEnv():

VariableDescription
QPAY_BASE_URLQPay API base URL (e.g., https://merchant.qpay.mn)
QPAY_USERNAMEQPay merchant username
QPAY_PASSWORDQPay merchant password
QPAY_INVOICE_CODEDefault invoice code
QPAY_CALLBACK_URLPayment callback URL
import { QPayClient, loadConfigFromEnv } from 'qpay-js'; const client = new QPayClient(loadConfigFromEnv());

Manual Configuration

import { QPayClient } from 'qpay-js'; import type { QPayConfig } from 'qpay-js'; const config: QPayConfig = { baseUrl: 'https://merchant.qpay.mn', username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD', invoiceCode: 'YOUR_INVOICE_CODE', callbackUrl: 'https://example.com/api/qpay/callback', }; const client = new QPayClient(config);

Quick Start

import { QPayClient, loadConfigFromEnv } from 'qpay-js'; const config = loadConfigFromEnv(); const client = new QPayClient(config); const invoice = await client.createSimpleInvoice({ invoiceCode: config.invoiceCode, senderInvoiceNo: 'ORDER-001', invoiceReceiverCode: 'terminal', invoiceDescription: 'Payment for Order #001', amount: 10000, callbackUrl: config.callbackUrl, }); console.log(invoice.invoiceId); // "abc123..." console.log(invoice.qPayShortUrl); // "https://qpay.mn/s/..." console.log(invoice.qrImage); // base64-encoded QR image for (const url of invoice.urls) { console.log(`${url.name}: ${url.link}`); }

Create Invoice

Simple Invoice

const invoice = await client.createSimpleInvoice({ invoiceCode: 'TEST_INVOICE', senderInvoiceNo: 'ORDER-002', invoiceReceiverCode: 'terminal', invoiceDescription: 'Quick payment', senderBranchCode: 'BRANCH01', // optional amount: 10000, callbackUrl: 'https://example.com/api/qpay/callback', });

Full Invoice

const invoice = await client.createInvoice({ invoiceCode: 'TEST_INVOICE', senderInvoiceNo: 'ORDER-003', invoiceReceiverCode: 'terminal', invoiceDescription: 'Detailed invoice', amount: 100000, callbackUrl: 'https://example.com/api/qpay/callback', lines: [ { lineDescription: 'Product A', lineQuantity: '2', lineUnitPrice: '50000', }, ], });

Cancel Invoice

await client.cancelInvoice('invoice-id-here');

Check Payment

const result = await client.checkPayment({ objectType: 'INVOICE', objectId: invoice.invoiceId, offset: { pageNumber: 1, pageLimit: 10 }, }); if (result.count > 0) { console.log(`Payment received! Paid: ${result.paidAmount} MNT`); for (const row of result.rows) { console.log(` ${row.paymentId}: ${row.paymentStatus} (${row.paymentAmount} ${row.paymentCurrency})`); } } else { console.log('No payment yet'); }

List Payments

const result = await client.listPayments({ objectType: 'INVOICE', objectId: invoice.invoiceId, startDate: '2024-01-01', endDate: '2024-12-31', offset: { pageNumber: 1, pageLimit: 20 }, }); console.log(`Total: ${result.count}`); for (const item of result.rows) { console.log(`${item.paymentId} | ${item.paymentDate} | ${item.paymentAmount} ${item.paymentCurrency}`); }

Get details for a single payment:

const detail = await client.getPayment('payment-id-here'); console.log(`Payment ${detail.paymentId}: ${detail.paymentStatus} (${detail.paymentAmount} ${detail.paymentCurrency})`);

Webhook Handling

QPay sends a POST request to your callbackUrl when a payment completes. Here is how to handle it in Express:

import express from 'express'; import { QPayClient, loadConfigFromEnv } from 'qpay-js'; const app = express(); app.use(express.json()); const client = new QPayClient(loadConfigFromEnv()); app.post('/api/qpay/callback', async (req, res) => { const { payment_id } = req.body; // Verify the payment by calling QPay API const result = await client.checkPayment({ objectType: 'INVOICE', objectId: payment_id, }); if (result.count > 0) { // Payment verified -- update your order status console.log(`Payment confirmed: ${payment_id} (${result.paidAmount} MNT)`); } res.sendStatus(200); });

Error Handling

All API errors throw a QPayError with structured information:

import { QPayError, isQPayError, ERR_INVOICE_NOT_FOUND, ERR_AUTHENTICATION_FAILED } from 'qpay-js'; try { await client.createSimpleInvoice(request); } catch (err) { if (isQPayError(err)) { console.log(err.statusCode); // 400, 401, 404, etc. console.log(err.code); // "INVOICE_NOTFOUND" console.log(err.message); // "qpay: INVOICE_NOTFOUND - Invoice not found (status 404)" console.log(err.rawBody); // Raw JSON response body switch (err.code) { case ERR_INVOICE_NOT_FOUND: // Handle missing invoice break; case ERR_AUTHENTICATION_FAILED: // Handle auth failure break; } } else { // Non-API error (network, etc.) console.error(err); } }

Available Error Code Constants

import { ERR_AUTHENTICATION_FAILED, // "AUTHENTICATION_FAILED" ERR_INVOICE_NOT_FOUND, // "INVOICE_NOTFOUND" ERR_INVOICE_PAID, // "INVOICE_PAID" ERR_INVOICE_ALREADY_CANCELED, // "INVOICE_ALREADY_CANCELED" ERR_INVOICE_CODE_INVALID, // "INVOICE_CODE_INVALID" ERR_INVALID_AMOUNT, // "INVALID_AMOUNT" ERR_PAYMENT_NOT_FOUND, // "PAYMENT_NOTFOUND" ERR_PAYMENT_ALREADY_CANCELED, // "PAYMENT_ALREADY_CANCELED" ERR_PERMISSION_DENIED, // "PERMISSION_DENIED" // ... and many more } from 'qpay-js';

Browser Usage

This library works in modern browsers that support the fetch API. Use manual configuration instead of loadConfigFromEnv():

<script type="module"> import { QPayClient } from 'qpay-js'; const client = new QPayClient({ baseUrl: 'https://merchant.qpay.mn', username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD', invoiceCode: 'YOUR_INVOICE_CODE', callbackUrl: 'https://example.com/callback', }); const invoice = await client.createSimpleInvoice({ invoiceCode: 'YOUR_CODE', senderInvoiceNo: 'WEB-001', invoiceReceiverCode: 'terminal', invoiceDescription: 'Web payment', amount: 5000, callbackUrl: 'https://example.com/callback', }); document.getElementById('qr').src = `data:image/png;base64,${invoice.qrImage}`; </script>

API Reference

MethodDescriptionReturns
new QPayClient(config)Create a new clientQPayClient
getToken()Authenticate and return a token pairPromise<TokenResponse>
refreshToken()Refresh the current access tokenPromise<TokenResponse>
createInvoice(req)Create a detailed invoicePromise<InvoiceResponse>
createSimpleInvoice(req)Create a simple invoicePromise<InvoiceResponse>
createEbarimtInvoice(req)Create an invoice with ebarimtPromise<InvoiceResponse>
cancelInvoice(invoiceId)Cancel an invoice by IDPromise<void>
getPayment(paymentId)Get payment details by IDPromise<PaymentDetail>
checkPayment(req)Check if a payment has been madePromise<PaymentCheckResponse>
listPayments(req)List payments with filtersPromise<PaymentListResponse>
cancelPayment(paymentId, req?)Cancel a card paymentPromise<void>
refundPayment(paymentId, req?)Refund a card paymentPromise<void>
createEbarimt(req)Create an electronic tax receiptPromise<EbarimtResponse>
cancelEbarimt(paymentId)Cancel an ebarimt by payment IDPromise<EbarimtResponse>
Last updated on