pec-payment-sdk
v1.1.2
Published
TypeScript SDK for PEC (Parsian Electronic Commerce) payment gateway.
Maintainers
Readme
pec-payment-sdk
English | فارسی
TypeScript/JavaScript SDK for PEC (Parsian Electronic Commerce / تجارت الکترونیک پارسیان) payment gateway. Works with Node.js, Express, Fastify, NestJS, Next.js, and any CommonJS or ESM project.
Built on official PEC SOAP services (same endpoints as the bank’s PHP samples) with typed APIs and developer-friendly helpers.
Features
- Standard sale, confirm, and reverse flows
- Online multiplexed payments (تسهیم آنلاین)
- Government ID payments and government multiplexed payments
- Bill payment and bill inquiry
- Mobile top-up
- Sale transaction reporting (REST API)
- Rial / Toman amount handling
- CommonJS (
require) and ESM (import) support - Full TypeScript types
Requirements
- Node.js 18+
Installation
npm install pec-payment-sdkQuick start
ESM / TypeScript
import {
PecClient,
generateOrderId,
parseCallback,
shouldConfirmPayment,
isSuccessStatus,
} from 'pec-payment-sdk';
const client = new PecClient({
loginAccount: process.env.PEC_LOGIN_ACCOUNT!,
callbackUrl: 'https://your-shop.com/payment/callback',
});
const sale = await client.requestPayment({
amount: 50000,
currency: 'toman', // default; SDK sends 500,000 Rials to PEC
orderId: generateOrderId(),
});
if (sale.paymentUrl) {
// Redirect the customer to the bank payment page
res.redirect(sale.paymentUrl);
}CommonJS
const {
PecClient,
generateOrderId,
parseCallback,
shouldConfirmPayment,
} = require('pec-payment-sdk');
const client = new PecClient({
loginAccount: process.env.PEC_LOGIN_ACCOUNT,
callbackUrl: 'https://your-shop.com/payment/callback',
});Payment flow
1. Your server → client.requestPayment()
2. Redirect user → sale.paymentUrl (PEC gateway)
3. User pays → Bank redirects to your callbackUrl
4. Your server → parseCallback() + client.confirmPayment()Callback handler (Express example)
After payment, PEC POSTs to your callback URL with fields such as Token, status, OrderId, RRN, Amount, and TerminalNo. Pass req.body to parseCallback(). If your route reads query parameters instead, merge them into one object first.
Callback URLs may use HTTP (e.g. http://localhost) for local development or HTTPS in production.
app.post('/payment/callback', async (req, res) => {
const callback = parseCallback(req.body);
if (!shouldConfirmPayment(callback)) {
return res.redirect('/payment/failed');
}
const result = await client.confirmPayment({ token: callback.token });
if (isSuccessStatus(result.status)) {
return res.redirect(`/payment/success?rrn=${result.rrn}`);
}
res.redirect('/payment/failed');
});Currency
PEC expects amounts in Rials. Pass the amount in the unit your app uses:
| currency | You pass | Sent to PEC |
|------------|----------|-------------|
| 'toman' (default) | 50000 | 500000 Rials |
| 'rial' | 500000 | 500000 Rials |
import { toRials } from 'pec-payment-sdk';
toRials(50000, 'toman'); // 500000
toRials(500000, 'rial'); // 500000For multiplexed payments, each account amount uses the same currency as the main request.
API reference
Client
const client = new PecClient({
loginAccount: string; // Merchant PIN (LoginAccount)
callbackUrl?: string; // Default callback if omitted per request
});Payment methods
| Method | Description |
|--------|-------------|
| requestPayment() | Standard sale / goods & services |
| requestMultiplexedPayment() | Online split payment across IBAN accounts |
| requestGovernmentPayment() | Payment with government account ID |
| requestGovernmentMultiplexedPayment() | Government payment with split accounts |
| requestBillPayment() | Bill payment |
| getBillInfo() | Bill inquiry before payment |
| requestMobileTopup() | Mobile charge / top-up |
| confirmPayment() | Confirm (settle) a successful payment |
| reversePayment() | Reverse a payment (within bank time limit) |
| getSaleReport() | Fetch transactions via PEC reporting REST API |
Utilities
| Export | Description |
|--------|-------------|
| generateOrderId() | Generate a unique order ID |
| getPaymentPageUrl(token) | Build PEC redirect URL |
| parseCallback(body) | Parse bank callback POST body |
| shouldConfirmPayment(callback) | Check if callback is OK to confirm |
| isSuccessStatus(status) | true when PEC status is 0 |
| isValidUrl(url) | Validate HTTP/HTTPS callback URL |
| toRials(amount, currency) | Convert amount to Rials |
| validateAmount(amount) | Throw if amount is invalid |
| validateSaleReportDateRange(from, to) | Enforce max 30-day report window |
Errors
| Class | When |
|-------|------|
| PecValidationError | Invalid input (e.g. missing callback URL) |
| PecTransportError | Network or SOAP failure |
| PecError | General PEC-related error |
Module formats
Use the same package name in both styles — Node and bundlers pick the right build automatically:
// CommonJS
const { PecClient } = require('pec-payment-sdk');// ESM
import { PecClient } from 'pec-payment-sdk';Environment variables (recommended)
PEC_LOGIN_ACCOUNT=your_merchant_pinNever commit your merchant PIN. Use environment variables or a secrets manager.
Links
License
MIT © Alireza Mohammadvali
