pec-payment-sdk 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.fa.md +212 -0
  3. package/README.md +212 -0
  4. package/dist/cjs/PecClient.d.ts +28 -0
  5. package/dist/cjs/PecClient.d.ts.map +1 -0
  6. package/dist/cjs/PecClient.js +218 -0
  7. package/dist/cjs/constants.d.ts +13 -0
  8. package/dist/cjs/constants.d.ts.map +1 -0
  9. package/dist/cjs/constants.js +15 -0
  10. package/dist/cjs/errors.d.ts +14 -0
  11. package/dist/cjs/errors.d.ts.map +1 -0
  12. package/dist/cjs/errors.js +28 -0
  13. package/dist/cjs/index.d.ts +6 -0
  14. package/dist/cjs/index.d.ts.map +1 -0
  15. package/dist/cjs/index.js +30 -0
  16. package/dist/cjs/soapClient.d.ts +6 -0
  17. package/dist/cjs/soapClient.d.ts.map +1 -0
  18. package/dist/cjs/soapClient.js +44 -0
  19. package/dist/cjs/types.d.ts +122 -0
  20. package/dist/cjs/types.d.ts.map +1 -0
  21. package/dist/cjs/types.js +2 -0
  22. package/dist/cjs/utils.d.ts +43 -0
  23. package/dist/cjs/utils.d.ts.map +1 -0
  24. package/dist/cjs/utils.js +162 -0
  25. package/dist/esm/PecClient.d.ts +28 -0
  26. package/dist/esm/PecClient.d.ts.map +1 -0
  27. package/dist/esm/PecClient.js +211 -0
  28. package/dist/esm/constants.d.ts +13 -0
  29. package/dist/esm/constants.d.ts.map +1 -0
  30. package/dist/esm/constants.js +12 -0
  31. package/dist/esm/errors.d.ts +14 -0
  32. package/dist/esm/errors.d.ts.map +1 -0
  33. package/dist/esm/errors.js +22 -0
  34. package/dist/esm/index.d.ts +6 -0
  35. package/dist/esm/index.d.ts.map +1 -0
  36. package/dist/esm/index.js +4 -0
  37. package/dist/esm/package.json +3 -0
  38. package/dist/esm/soapClient.d.ts +6 -0
  39. package/dist/esm/soapClient.d.ts.map +1 -0
  40. package/dist/esm/soapClient.js +36 -0
  41. package/dist/esm/types.d.ts +122 -0
  42. package/dist/esm/types.d.ts.map +1 -0
  43. package/dist/esm/types.js +1 -0
  44. package/dist/esm/utils.d.ts +43 -0
  45. package/dist/esm/utils.d.ts.map +1 -0
  46. package/dist/esm/utils.js +144 -0
  47. package/package.json +62 -0
@@ -0,0 +1,122 @@
1
+ export type Currency = 'rial' | 'toman';
2
+ export type OrderId = string | number;
3
+ export interface PecClientOptions {
4
+ /** Merchant terminal PIN (`LoginAccount` in PEC SOAP requests). */
5
+ loginAccount: string;
6
+ /** Default callback URL when not provided per request. */
7
+ callbackUrl?: string;
8
+ }
9
+ export interface RequestPaymentInput {
10
+ /** Amount in the unit specified by `currency`. Converted to Rials before sending to PEC. */
11
+ amount: number;
12
+ orderId: OrderId;
13
+ currency?: Currency;
14
+ callbackUrl?: string;
15
+ additionalData?: string;
16
+ originator?: string;
17
+ }
18
+ export interface PaymentTokenResult {
19
+ status: number;
20
+ message: string;
21
+ token: string;
22
+ paymentUrl?: string;
23
+ }
24
+ export interface ConfirmPaymentInput {
25
+ token: string | number;
26
+ }
27
+ export interface ConfirmPaymentResult {
28
+ status: number;
29
+ token: string;
30
+ cardNumberMasked: string;
31
+ rrn: string;
32
+ }
33
+ export interface ReversePaymentInput {
34
+ token: string | number;
35
+ }
36
+ export interface ReversePaymentResult {
37
+ status: number;
38
+ message: string;
39
+ token: string;
40
+ }
41
+ export interface MultiplexedAccount {
42
+ amount: number;
43
+ iban: string;
44
+ payId: string;
45
+ }
46
+ export interface RequestMultiplexedPaymentInput {
47
+ amount: number;
48
+ orderId: OrderId;
49
+ accounts: MultiplexedAccount[];
50
+ currency?: Currency;
51
+ callbackUrl?: string;
52
+ originator?: string;
53
+ }
54
+ export interface RequestGovernmentPaymentInput {
55
+ amount: number;
56
+ orderId: OrderId;
57
+ govId: string;
58
+ currency?: Currency;
59
+ callbackUrl?: string;
60
+ originator?: string;
61
+ }
62
+ export interface RequestGovernmentMultiplexedPaymentInput {
63
+ amount: number;
64
+ orderId: OrderId;
65
+ govId: string;
66
+ accounts: MultiplexedAccount[];
67
+ currency?: Currency;
68
+ callbackUrl?: string;
69
+ originator?: string;
70
+ }
71
+ export interface RequestBillPaymentInput {
72
+ orderId: OrderId;
73
+ billId: string;
74
+ payId: string;
75
+ callbackUrl?: string;
76
+ additionalData?: string;
77
+ originator?: string;
78
+ }
79
+ export interface GetBillInfoInput {
80
+ billId: string;
81
+ payId: string;
82
+ }
83
+ export interface BillInfoResult {
84
+ status: number;
85
+ message: string;
86
+ amount: string;
87
+ billId: string;
88
+ payId: string;
89
+ }
90
+ export interface RequestMobileTopupInput {
91
+ orderId: OrderId;
92
+ chargeMobileNumber: string;
93
+ requesterMobileNumber: string;
94
+ topupType: string | number;
95
+ amount: number;
96
+ currency?: Currency;
97
+ callbackUrl?: string;
98
+ additionalData?: string;
99
+ originator?: string;
100
+ }
101
+ export interface GetSaleReportInput {
102
+ username: string;
103
+ password: string;
104
+ fromDate: string;
105
+ toDate: string;
106
+ rrn?: string;
107
+ orderId?: OrderId;
108
+ token?: string | number;
109
+ }
110
+ export interface GetSaleReportResult {
111
+ [key: string]: unknown;
112
+ }
113
+ /** Fields POSTed by PEC to the merchant callback URL after payment. */
114
+ export interface CallbackPayload {
115
+ token: string;
116
+ status: number;
117
+ orderId: string;
118
+ terminalNo: string;
119
+ amount: string;
120
+ rrn: string;
121
+ }
122
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ import type { CallbackPayload, Currency, MultiplexedAccount } from './types.js';
2
+ /** Converts an amount to Rials for PEC API requests. */
3
+ export declare function toRials(amount: number, currency?: Currency): number;
4
+ /** Ensures amount is a positive finite number. */
5
+ export declare function validateAmount(amount: number): void;
6
+ export declare function getPaymentPageUrl(token: string | number): string;
7
+ export declare function isSuccessStatus(status: number | string): boolean;
8
+ /** Returns true when the bank callback indicates a successful payment worth confirming. */
9
+ export declare function shouldConfirmPayment(callback: CallbackPayload): boolean;
10
+ export declare function generateOrderId(): string;
11
+ /** Validates callback URLs (HTTP for local dev, HTTPS for production). */
12
+ export declare function isValidUrl(url: string): boolean;
13
+ /** @deprecated Use {@link isValidUrl} instead. */
14
+ export declare function isValidHttpsUrl(url: string): boolean;
15
+ /**
16
+ * Parses the bank callback payload (PEC POSTs to your callback URL).
17
+ * Pass `req.body` for POST callbacks; merge `req.query` if your route uses GET.
18
+ */
19
+ export declare function parseCallback(body: Record<string, unknown>): CallbackPayload;
20
+ export declare function normalizeSoapField(value: unknown): string;
21
+ export declare function normalizeSoapNumber(value: unknown): number;
22
+ export declare function buildPaymentTokenResult(status: unknown, token: unknown, message: unknown): {
23
+ status: number;
24
+ token: string;
25
+ message: string;
26
+ paymentUrl?: string;
27
+ };
28
+ export declare function mapMultiplexedAccounts(accounts: MultiplexedAccount[], currency?: Currency): Array<{
29
+ Amount: number;
30
+ IBAN: string;
31
+ PayId: string;
32
+ }>;
33
+ export declare function validateMultiplexedAccounts(accounts: MultiplexedAccount[]): void;
34
+ /** Validates sale report date range (max 30 days, end after start). */
35
+ export declare function validateSaleReportDateRange(fromDate: string, toDate: string): void;
36
+ export declare function normalizeBillInfoResult(payload: Record<string, unknown>): {
37
+ status: number;
38
+ message: string;
39
+ amount: string;
40
+ billId: string;
41
+ payId: string;
42
+ };
43
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAMhF,wDAAwD;AACxD,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAkB,GAAG,MAAM,CAG5E;AAED,kDAAkD;AAClD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAInD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAEhE;AAED,2FAA2F;AAC3F,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAEvE;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAU/C;AAED,kDAAkD;AAClD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD;AAoBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAS5E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQzD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE1D;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,OAAO,GACf;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAgBzE;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,kBAAkB,EAAE,EAC9B,QAAQ,GAAE,QAAkB,GAC3B,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAQxD;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAchF;AAED,uEAAuE;AACvE,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAelF;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAQA"}
@@ -0,0 +1,144 @@
1
+ import { randomBytes } from 'crypto';
2
+ import { PAYMENT_PAGE_BASE, PEC_SUCCESS_STATUS } from './constants.js';
3
+ import { PecValidationError } from './errors.js';
4
+ const MAX_SALE_REPORT_RANGE_MS = 30 * 24 * 60 * 60 * 1000;
5
+ /** Converts an amount to Rials for PEC API requests. */
6
+ export function toRials(amount, currency = 'toman') {
7
+ validateAmount(amount);
8
+ return currency === 'toman' ? amount * 10 : amount;
9
+ }
10
+ /** Ensures amount is a positive finite number. */
11
+ export function validateAmount(amount) {
12
+ if (!Number.isFinite(amount) || amount <= 0) {
13
+ throw new PecValidationError('amount must be a positive number');
14
+ }
15
+ }
16
+ export function getPaymentPageUrl(token) {
17
+ return `${PAYMENT_PAGE_BASE}${token}`;
18
+ }
19
+ export function isSuccessStatus(status) {
20
+ return Number(status) === PEC_SUCCESS_STATUS;
21
+ }
22
+ /** Returns true when the bank callback indicates a successful payment worth confirming. */
23
+ export function shouldConfirmPayment(callback) {
24
+ return callback.status === PEC_SUCCESS_STATUS && Number(callback.rrn) > 0;
25
+ }
26
+ export function generateOrderId() {
27
+ return randomBytes(20).toString('hex');
28
+ }
29
+ /** Validates callback URLs (HTTP for local dev, HTTPS for production). */
30
+ export function isValidUrl(url) {
31
+ try {
32
+ const parsed = new URL(url);
33
+ return ((parsed.protocol === 'https:' || parsed.protocol === 'http:') &&
34
+ parsed.hostname.length > 0);
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ /** @deprecated Use {@link isValidUrl} instead. */
41
+ export function isValidHttpsUrl(url) {
42
+ return isValidUrl(url) && url.startsWith('https:');
43
+ }
44
+ function readField(body, keys) {
45
+ for (const key of keys) {
46
+ const value = body[key];
47
+ if (value !== undefined && value !== null && value !== '') {
48
+ return String(value);
49
+ }
50
+ }
51
+ return '';
52
+ }
53
+ function parseCallbackStatus(body) {
54
+ const raw = readField(body, ['status', 'Status']);
55
+ if (raw === '') {
56
+ return NaN;
57
+ }
58
+ return Number(raw);
59
+ }
60
+ /**
61
+ * Parses the bank callback payload (PEC POSTs to your callback URL).
62
+ * Pass `req.body` for POST callbacks; merge `req.query` if your route uses GET.
63
+ */
64
+ export function parseCallback(body) {
65
+ return {
66
+ token: readField(body, ['Token', 'token']),
67
+ status: parseCallbackStatus(body),
68
+ orderId: readField(body, ['OrderId', 'orderId']),
69
+ terminalNo: readField(body, ['TerminalNo', 'terminalNo']),
70
+ amount: readField(body, ['Amount', 'amount']),
71
+ rrn: readField(body, ['RRN', 'rrn']),
72
+ };
73
+ }
74
+ export function normalizeSoapField(value) {
75
+ if (value === undefined || value === null) {
76
+ return '';
77
+ }
78
+ if (Array.isArray(value)) {
79
+ return normalizeSoapField(value[0]);
80
+ }
81
+ return String(value);
82
+ }
83
+ export function normalizeSoapNumber(value) {
84
+ return Number(normalizeSoapField(value));
85
+ }
86
+ export function buildPaymentTokenResult(status, token, message) {
87
+ const normalizedStatus = normalizeSoapNumber(status);
88
+ const normalizedToken = normalizeSoapField(token);
89
+ const normalizedMessage = normalizeSoapField(message);
90
+ const result = {
91
+ status: normalizedStatus,
92
+ token: normalizedToken,
93
+ message: normalizedMessage,
94
+ };
95
+ if (isSuccessStatus(normalizedStatus) && normalizedToken.length > 0) {
96
+ return { ...result, paymentUrl: getPaymentPageUrl(normalizedToken) };
97
+ }
98
+ return result;
99
+ }
100
+ export function mapMultiplexedAccounts(accounts, currency = 'toman') {
101
+ validateMultiplexedAccounts(accounts);
102
+ return accounts.map((account) => ({
103
+ Amount: toRials(account.amount, currency),
104
+ IBAN: account.iban,
105
+ PayId: account.payId,
106
+ }));
107
+ }
108
+ export function validateMultiplexedAccounts(accounts) {
109
+ if (!Array.isArray(accounts) || accounts.length === 0) {
110
+ throw new PecValidationError('accounts must be a non-empty array');
111
+ }
112
+ for (const account of accounts) {
113
+ validateAmount(account.amount);
114
+ if (!account.iban?.trim()) {
115
+ throw new PecValidationError('each account must include a valid iban');
116
+ }
117
+ if (!account.payId?.trim()) {
118
+ throw new PecValidationError('each account must include a valid payId');
119
+ }
120
+ }
121
+ }
122
+ /** Validates sale report date range (max 30 days, end after start). */
123
+ export function validateSaleReportDateRange(fromDate, toDate) {
124
+ const from = new Date(fromDate);
125
+ const to = new Date(toDate);
126
+ if (Number.isNaN(from.getTime()) || Number.isNaN(to.getTime())) {
127
+ throw new PecValidationError('fromDate and toDate must be valid date strings');
128
+ }
129
+ if (to.getTime() < from.getTime()) {
130
+ throw new PecValidationError('toDate must be on or after fromDate');
131
+ }
132
+ if (to.getTime() - from.getTime() > MAX_SALE_REPORT_RANGE_MS) {
133
+ throw new PecValidationError('date range must not exceed 30 days');
134
+ }
135
+ }
136
+ export function normalizeBillInfoResult(payload) {
137
+ return {
138
+ status: normalizeSoapNumber(payload.Status),
139
+ message: normalizeSoapField(payload.Message),
140
+ amount: normalizeSoapField(payload.Amount),
141
+ billId: normalizeSoapField(payload.BillId),
142
+ payId: normalizeSoapField(payload.PayId),
143
+ };
144
+ }
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "pec-payment-sdk",
3
+ "version": "1.1.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/AlirezaMoVali/pec-sdk.git"
7
+ },
8
+ "bugs": {
9
+ "url": "https://github.com/AlirezaMoVali/pec-sdk/issues"
10
+ },
11
+ "homepage": "https://github.com/AlirezaMoVali/pec-sdk#readme",
12
+ "keywords": [
13
+ "pec",
14
+ "parsian",
15
+ "payment",
16
+ "gateway",
17
+ "shaparak",
18
+ "iran",
19
+ "ipg"
20
+ ],
21
+ "description": "TypeScript SDK for PEC (Parsian Electronic Commerce) payment gateway.",
22
+ "type": "commonjs",
23
+ "main": "./dist/cjs/index.js",
24
+ "module": "./dist/esm/index.js",
25
+ "types": "./dist/cjs/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "import": {
29
+ "types": "./dist/esm/index.d.ts",
30
+ "default": "./dist/esm/index.js"
31
+ },
32
+ "require": {
33
+ "types": "./dist/cjs/index.d.ts",
34
+ "default": "./dist/cjs/index.js"
35
+ }
36
+ },
37
+ "./package.json": "./package.json"
38
+ },
39
+ "sideEffects": false,
40
+ "engines": {
41
+ "node": ">=18"
42
+ },
43
+ "scripts": {
44
+ "build": "rm -rf dist && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && node scripts/postbuild-esm.mjs",
45
+ "prepublishOnly": "npm run build",
46
+ "test": "vitest run"
47
+ },
48
+ "author": "Alireza Mohammadvali <a.mv99@outlook.com> (https://github.com/AlirezaMoVali)",
49
+ "license": "MIT",
50
+ "devDependencies": {
51
+ "@types/node": "^22.10.0",
52
+ "typescript": "^5.4.4",
53
+ "vitest": "^3.0.0"
54
+ },
55
+ "dependencies": {
56
+ "axios": "^1.6.8",
57
+ "soap": "^1.1.7"
58
+ },
59
+ "files": [
60
+ "dist"
61
+ ]
62
+ }