@aruntimalsina/fonepay-reusable-client
v1.0.1
Published
Dependency-free Node.js client for Fonepay QR payments and settlement verification through a reusable REST API
Maintainers
Readme
Fonepay Reusable JavaScript Client
A dependency-free Node.js client for the Fonepay QR payment and settlement-verification REST API. Use it in Express, Next.js server routes, NestJS, Fastify, serverless functions, background workers, and other JavaScript or TypeScript backends.
This package does not call Fonepay directly from the browser. Your application calls the reusable Fonepay service, which keeps merchant credentials on the server and normalizes QR creation and payment verification.
Features
- Dynamic Fonepay QR payment requests
- Payment verification against settlement reports
- Exact merchant-reference and amount matching
- Optional internal API-key authentication
- Standard
fetchsupport with no runtime dependencies - Request timeout handling
- Normalized
FonepayApiErrorerrors - Works with Node.js 18+, Express, Next.js, NestJS, Fastify, and server jobs
- NPR payment support
Search keywords
Fonepay, Fonepay API, Fonepay QR, Nepal payments, Nepal payment gateway, QR payment, dynamic QR, payment verification, settlement verification, digital payments, Node.js payments, JavaScript payments, Express payments, and Next.js payments.
Installation
npm install @aruntimalsina/fonepay-reusable-clientNode.js 18 or newer is required because the package uses the native fetch API.
Configuration
Keep the service URL and API key in backend environment variables:
FONEPAY_SERVICE_URL=https://payments.example.com
FONEPAY_SERVICE_API_KEY=your-service-api-keyThe API key is optional when the reusable service is running on a private network without service authentication.
Complete example
import { FonepayClient } from '@aruntimalsina/fonepay-reusable-client';
const fonepay = new FonepayClient({
baseUrl: process.env.FONEPAY_SERVICE_URL,
apiKey: process.env.FONEPAY_SERVICE_API_KEY,
});
// 1. Create a local payment record first.
const reference = `ORDER-${order.id}`;
// 2. Ask the reusable service for a QR payload.
const qr = await fonepay.createQr({
merchantReference: reference,
amount: order.total,
currency: 'NPR',
});
// Return qr.qrMessage to your web or mobile frontend and render it as a QR code.
// 3. Verify from a protected backend endpoint or worker after the customer pays.
const payment = await fonepay.verifyPayment({
merchantReference: reference,
amount: order.total,
daysBack: 7,
});
// 4. Make the local update idempotent.
if (payment.verified) {
await markOrderPaidOnce(order.id, payment.transactionId);
}API
new FonepayClient(options)
| Option | Required | Description |
|---|---:|---|
| baseUrl | yes | URL of your deployed reusable Fonepay REST service |
| apiKey | no | Internal service key, sent as X-Internal-Key |
| timeoutMs | no | Request timeout, default 20000 |
| fetchImpl | no | Custom fetch implementation for tests or runtimes |
createQr({ merchantReference, amount, currency })
Returns a QR payload response:
{
"qrMessage": "...",
"terminalId": 123,
"amount": 250,
"currency": "NPR",
"merchantReference": "ORDER-1001"
}Pass qrMessage to a QR renderer in your own frontend. This package intentionally does not assume React, Vue, React Native, or another UI framework.
verifyPayment({ merchantReference, amount, fromDate, toDate, daysBack })
Returns a normalized verification result:
{
"verified": true,
"status": "paid",
"transactionId": "FP-123",
"amount": 250,
"merchantReference": "ORDER-1001"
}Only mark an order paid when verified === true. Store the returned transaction ID and prevent duplicate local updates.
Error handling
import { FonepayApiError } from '@aruntimalsina/fonepay-reusable-client';
try {
const result = await fonepay.verifyPayment({
merchantReference: 'ORDER-1001',
amount: 250,
daysBack: 7,
});
} catch (error) {
if (error instanceof FonepayApiError) {
console.error(error.code, error.status, error.message);
}
throw error;
}Errors expose status, code, and optional details fields. Common codes include UNAUTHORIZED, INVALID_PAYMENT, GATEWAY_UNAVAILABLE, NETWORK_ERROR, TIMEOUT, and REQUEST_FAILED.
Recommended payment flow
create local order
↓
request QR from Fonepay service
↓
show QR to customer
↓
customer pays with a Fonepay-supported bank or wallet
↓
verify payment from backend/worker
↓
mark order paid once and save transaction IDThe reusable service does not store your orders. Your application owns payment records, order state, retries, and idempotency.
Security
- Use this package only in trusted server-side code.
- Never expose
FONEPAY_SERVICE_API_KEYin browser or mobile bundles. - Never put Fonepay merchant credentials in this package or frontend code.
- Use HTTPS for the reusable service in production.
- Use a unique merchant reference for each payment.
- Treat client-side payment success messages as untrusted.
Other stacks
The same reusable service also provides SDKs and guides for Python, PHP/Laravel, Java/Spring Boot, Go, .NET, and generic REST clients:
https://github.com/dannybyarun/fonepay-reusable
License
MIT © Arun Timalsina
