simplepay-js-sdk 0.8.3 → 0.10.0
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.
- package/README-ENG.md +6 -4
- package/README.md +6 -4
- package/dist/index.d.ts +6 -2
- package/dist/index.js +28 -28
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/basic.spec.ts +127 -0
- package/src/oneTime.spec.ts +4 -0
- package/src/oneTime.ts +4 -4
- package/src/recurring.spec.ts +2 -0
- package/src/recurring.ts +3 -3
- package/src/types.ts +5 -1
- package/src/utils.spec.ts +14 -0
- package/src/utils.ts +5 -2
package/README-ENG.md
CHANGED
|
@@ -28,10 +28,10 @@ pnpm add simplepay-js-sdk
|
|
|
28
28
|
Set the following environment variables in your `.env` file:
|
|
29
29
|
|
|
30
30
|
- `SIMPLEPAY_LOGGER` If it set to `true`, it will log varibles - useful only for debugging.
|
|
31
|
-
- `SIMPLEPAY_MERCHANT_KEY_HUF` Your Simplepay secret merchant key. Set `SIMPLEPAY_MERCHANT_KEY_EUR` and `SIMPLEPAY_MERCHANT_KEY_USD` for accepting EUR and USD payments.
|
|
32
|
-
- `SIMPLEPAY_MERCHANT_ID_HUF` Your Simplepay merchant id. Set `SIMPLEPAY_MERCHANT_ID_EUR` and `SIMPLEPAY_MERCHANT_ID_USD` for accepting EUR and USD payments.
|
|
31
|
+
- `SIMPLEPAY_MERCHANT_KEY_HUF` Your Simplepay secret merchant key. Set `SIMPLEPAY_MERCHANT_KEY_HUF_SZEP` for accepting SZÉP kártyás payments. Set `SIMPLEPAY_MERCHANT_KEY_EUR` and `SIMPLEPAY_MERCHANT_KEY_USD` for accepting EUR and USD payments.
|
|
32
|
+
- `SIMPLEPAY_MERCHANT_ID_HUF` Your Simplepay merchant id. Set `SIMPLEPAY_MERCHANT_ID_HUF_SZEP` for accepting SZÉP kártyás payments. Set `SIMPLEPAY_MERCHANT_ID_EUR` and `SIMPLEPAY_MERCHANT_ID_USD` for accepting EUR and USD payments.
|
|
33
33
|
- `SIMPLEPAY_PRODUCTION` If it set to `true`, it will use production environment, otherwise it will use sandbox environment.
|
|
34
|
-
- `SIMPLEPAY_REDIRECT_URL` The URL of your site, where the customer will be redirected after the payment.
|
|
34
|
+
- `SIMPLEPAY_REDIRECT_URL` The URL of your site, where the customer will be redirected after the payment. Can also be provided when starting a payment so you can define different redirect urls for different payments.
|
|
35
35
|
|
|
36
36
|
## Usage
|
|
37
37
|
|
|
@@ -48,7 +48,7 @@ try {
|
|
|
48
48
|
const response = await startPayment({
|
|
49
49
|
orderRef: 'order-12',
|
|
50
50
|
total: 1212,
|
|
51
|
-
currency: 'HUF', // optional, HUF | EUR | USD, defaults to HUF
|
|
51
|
+
currency: 'HUF', // optional, HUF | HUF_SZEP | EUR | USD, defaults to HUF
|
|
52
52
|
customerEmail: 'rrd@webmania.cc',
|
|
53
53
|
language: 'HU', // optional, AR | BG | CS | DE | EN | ES | FR | IT | HR | HU | PL | RO | RU | SK | TR | ZH, defaults to HU
|
|
54
54
|
method: 'CARD', // optional, CARD | WIRE, defaults to CARD
|
|
@@ -60,6 +60,8 @@ try {
|
|
|
60
60
|
zip: '1234',
|
|
61
61
|
address: 'Sehol u. 0',
|
|
62
62
|
},
|
|
63
|
+
}, {
|
|
64
|
+
redirectUrl: 'http://url.to.redirect' // optional, defaults to the value of the SIMPLEPAY_REDIRECT_URL environment variable
|
|
63
65
|
})
|
|
64
66
|
return response
|
|
65
67
|
} catch (error) {
|
package/README.md
CHANGED
|
@@ -28,10 +28,10 @@ pnpm add simplepay-js-sdk
|
|
|
28
28
|
Állítsd be a következő környezeti változókat a `.env` fájlban:
|
|
29
29
|
|
|
30
30
|
- `SIMPLEPAY_LOGGER` Ha `true`-ra van állítva, naplózza a változókat - csak hibakereséshez hasznos.
|
|
31
|
-
- `SIMPLEPAY_MERCHANT_KEY_HUF` A te SimplePay titkos kereskedői kulcsod. Állítsd be a `SIMPLEPAY_MERCHANT_KEY_EUR` és `SIMPLEPAY_MERCHANT_KEY_USD` értékeket EUR és USD fizetések elfogadásához.
|
|
32
|
-
- `SIMPLEPAY_MERCHANT_ID_HUF` A te SimplePay kereskedői azonosítód. Állítsd be a `SIMPLEPAY_MERCHANT_ID_EUR` és `SIMPLEPAY_MERCHANT_ID_USD` értékeket EUR és USD fizetések elfogadásához.
|
|
31
|
+
- `SIMPLEPAY_MERCHANT_KEY_HUF` A te SimplePay titkos kereskedői kulcsod. Állítsd be a `SIMPLEPAY_MERCHANT_KEY_HUF_SZEP` értéket SZÉP kártyás fizetésekhez. Állítsd be a `SIMPLEPAY_MERCHANT_KEY_EUR` és `SIMPLEPAY_MERCHANT_KEY_USD` értékeket EUR és USD fizetések elfogadásához.
|
|
32
|
+
- `SIMPLEPAY_MERCHANT_ID_HUF` A te SimplePay kereskedői azonosítód. Állítsd be a `SIMPLEPAY_MERCHANT_ID_HUF_SZEP` értéket SZÉP kártyás fizetésekhez. Állítsd be a `SIMPLEPAY_MERCHANT_ID_EUR` és `SIMPLEPAY_MERCHANT_ID_USD` értékeket EUR és USD fizetések elfogadásához.
|
|
33
33
|
- `SIMPLEPAY_PRODUCTION` Ha `true`-ra van állítva, éles környezetet használ, egyébként teszt környezetet.
|
|
34
|
-
- `SIMPLEPAY_REDIRECT_URL` A te weboldalad URL-je, ahova a vásárló átirányításra kerül a fizetés után.
|
|
34
|
+
- `SIMPLEPAY_REDIRECT_URL` A te weboldalad URL-je, ahova a vásárló átirányításra kerül a fizetés után. Ez a fizetés indításakor is megadható, így különböző redirect url-eket definiálhatsz különböző fizetésekhez.
|
|
35
35
|
|
|
36
36
|
## Használat
|
|
37
37
|
|
|
@@ -48,7 +48,7 @@ try {
|
|
|
48
48
|
const response = await startPayment({
|
|
49
49
|
orderRef: 'order-12',
|
|
50
50
|
total: 1212,
|
|
51
|
-
currency: 'HUF', // opcionális, HUF | EUR | USD, alapértelmezett: HUF
|
|
51
|
+
currency: 'HUF', // opcionális, HUF | HUF_SZEP | EUR | USD, alapértelmezett: HUF
|
|
52
52
|
customerEmail: 'rrd@webmania.cc',
|
|
53
53
|
language: 'HU', // opcionális, AR | BG | CS | DE | EN | ES | FR | IT | HR | HU | PL | RO | RU | SK | TR | ZH, alapértelmezett: HU
|
|
54
54
|
method: 'CARD', // opcionális, CARD | WIRE, alapértelmezett: CARD
|
|
@@ -60,6 +60,8 @@ try {
|
|
|
60
60
|
zip: '1234',
|
|
61
61
|
address: 'Sehol u. 0',
|
|
62
62
|
},
|
|
63
|
+
}, {
|
|
64
|
+
redirectUrl: 'http://url.to.redirect' // opcionális, alapértelmezetten a SIMPLEPAY_REDIRECT_URL környezeti változó értéke
|
|
63
65
|
})
|
|
64
66
|
return response
|
|
65
67
|
} catch (error) {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export declare const cancelCard: (cardId: string) => Promise<SimplePayCancelCard
|
|
|
2
2
|
|
|
3
3
|
export declare const checkSignature: (responseText: string, signature: string, merchantKey: string) => boolean;
|
|
4
4
|
|
|
5
|
-
declare const CURRENCIES: readonly ["HUF", "EUR", "USD"];
|
|
5
|
+
declare const CURRENCIES: readonly ["HUF", "HUF_SZEP", "EUR", "USD"];
|
|
6
6
|
|
|
7
7
|
export declare type Currency = typeof CURRENCIES[number];
|
|
8
8
|
|
|
@@ -16,6 +16,10 @@ export declare type Language = typeof LANGUAGES[number];
|
|
|
16
16
|
|
|
17
17
|
declare const LANGUAGES: readonly ["AR", "BG", "CS", "DE", "EN", "ES", "FR", "IT", "HR", "HU", "PL", "RO", "RU", "SK", "TR", "ZH"];
|
|
18
18
|
|
|
19
|
+
declare interface PaymentConfig {
|
|
20
|
+
redirectUrl?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
declare interface PaymentData {
|
|
20
24
|
orderRef: string;
|
|
21
25
|
total: number | string;
|
|
@@ -86,7 +90,7 @@ declare interface SimplePayResult {
|
|
|
86
90
|
declare interface SimplePayTokenResponse extends Omit<SimplePayResponse, 'paymentUrl' | 'timeout'> {
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
export declare const startPayment: (paymentData: PaymentData) => Promise<SimplePayResponse>;
|
|
93
|
+
export declare const startPayment: (paymentData: PaymentData, config?: PaymentConfig) => Promise<SimplePayResponse>;
|
|
90
94
|
|
|
91
95
|
export declare const startRecurringPayment: (paymentData: RecurringPaymentData) => Promise<SimplePayRecurringResponse>;
|
|
92
96
|
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import S from "crypto";
|
|
2
|
-
const
|
|
2
|
+
const d = ["HUF", "HUF_SZEP", "EUR", "USD"], i = (...e) => {
|
|
3
3
|
process.env.SIMPLEPAY_LOGGER === "true" && console.log("👉 ", ...e);
|
|
4
4
|
}, E = (e) => {
|
|
5
|
-
if (!
|
|
5
|
+
if (!d.includes(e))
|
|
6
6
|
throw new Error(`Unsupported currency: ${e}`);
|
|
7
|
-
const n = "https://secure.simplepay.hu/payment/v2", r = "https://sandbox.simplepay.hu/payment/v2", t = "
|
|
7
|
+
const n = "https://secure.simplepay.hu/payment/v2", r = "https://sandbox.simplepay.hu/payment/v2", t = "SimplePay_Rrd_0.9.0", s = process.env[`SIMPLEPAY_MERCHANT_KEY_${e}`], c = process.env[`SIMPLEPAY_MERCHANT_ID_${e}`], o = process.env.SIMPLEPAY_PRODUCTION === "true" ? n : r, u = o + "/start", R = o + "/dorecurring", a = o + "/cardcancel";
|
|
8
8
|
return {
|
|
9
9
|
MERCHANT_KEY: s,
|
|
10
10
|
MERCHANT_ID: c,
|
|
@@ -13,19 +13,19 @@ const g = ["HUF", "EUR", "USD"], i = (...e) => {
|
|
|
13
13
|
API_URL_CARD_CANCEL: a,
|
|
14
14
|
SDK_VERSION: t
|
|
15
15
|
};
|
|
16
|
-
},
|
|
16
|
+
}, g = (e) => JSON.stringify(e).replace(/\//g, "\\/"), m = (e, n) => {
|
|
17
17
|
const r = S.createHmac("sha384", n.trim());
|
|
18
18
|
return r.update(e, "utf8"), r.digest("base64");
|
|
19
|
-
}, _ = (e, n, r) => n ===
|
|
19
|
+
}, _ = (e, n, r) => n === m(e, r), P = (e) => e.toISOString().replace(/\.\d{3}Z$/, "+00:00"), A = (e) => {
|
|
20
20
|
var r, t;
|
|
21
21
|
const n = (t = (r = Object.entries(process.env).find(
|
|
22
22
|
([s, c]) => s.startsWith("SIMPLEPAY_MERCHANT_ID_") && c === e
|
|
23
23
|
)) == null ? void 0 : r[0]) == null ? void 0 : t.replace("SIMPLEPAY_MERCHANT_ID_", "");
|
|
24
24
|
if (!n)
|
|
25
25
|
throw new Error(`Merchant id not found in the environment: ${e}`);
|
|
26
|
-
return n;
|
|
27
|
-
},
|
|
28
|
-
const s =
|
|
26
|
+
return n.replace("_SZEP", "");
|
|
27
|
+
}, p = async (e, n, r) => l(e, n, r, "oneTime"), I = async (e, n, r) => l(e, n, r, "recurring"), f = async (e, n, r) => l(e, n, r, "token"), h = async (e, n, r) => l(e, n, r, "cancelCard"), l = async (e, n, r, t) => {
|
|
28
|
+
const s = g(n), c = m(s, r);
|
|
29
29
|
i({ function: `SimplePay/makeRequest/${t}`, bodyString: s, signature: c });
|
|
30
30
|
try {
|
|
31
31
|
const o = await fetch(e, {
|
|
@@ -64,26 +64,26 @@ const g = ["HUF", "EUR", "USD"], i = (...e) => {
|
|
|
64
64
|
orderRef: o.o,
|
|
65
65
|
tokens: o.tokens
|
|
66
66
|
};
|
|
67
|
-
}, w = async (e) => {
|
|
67
|
+
}, w = async (e, n = {}) => {
|
|
68
68
|
i({ function: "SimplePay/startPayment", paymentData: e });
|
|
69
|
-
const
|
|
70
|
-
if (i({ function: "SimplePay/startPayment", MERCHANT_KEY:
|
|
71
|
-
throw new Error(`Missing SimplePay configuration for ${
|
|
72
|
-
const
|
|
69
|
+
const r = e.currency || "HUF", { MERCHANT_KEY: t, MERCHANT_ID: s, API_URL_PAYMENT: c, SDK_VERSION: o } = E(r);
|
|
70
|
+
if (i({ function: "SimplePay/startPayment", MERCHANT_KEY: t, MERCHANT_ID: s, API_URL_PAYMENT: c }), !t || !s)
|
|
71
|
+
throw new Error(`Missing SimplePay configuration for ${r}`);
|
|
72
|
+
const u = {
|
|
73
73
|
salt: S.randomBytes(16).toString("hex"),
|
|
74
|
-
merchant:
|
|
74
|
+
merchant: s,
|
|
75
75
|
orderRef: e.orderRef,
|
|
76
|
-
currency:
|
|
76
|
+
currency: r.replace("_SZEP", ""),
|
|
77
77
|
customerEmail: e.customerEmail,
|
|
78
78
|
language: e.language || "HU",
|
|
79
|
-
sdkVersion:
|
|
79
|
+
sdkVersion: o,
|
|
80
80
|
methods: [e.method || "CARD"],
|
|
81
81
|
total: String(e.total),
|
|
82
|
-
timeout:
|
|
83
|
-
url: process.env.SIMPLEPAY_REDIRECT_URL || "http://url.to.redirect",
|
|
82
|
+
timeout: P(new Date(Date.now() + 30 * 60 * 1e3)),
|
|
83
|
+
url: n.redirectUrl || process.env.SIMPLEPAY_REDIRECT_URL || "http://url.to.redirect",
|
|
84
84
|
invoice: e.invoice
|
|
85
85
|
};
|
|
86
|
-
return
|
|
86
|
+
return p(c, u, t);
|
|
87
87
|
}, y = 6, C = new Date(Date.now() + y * 30 * 24 * 60 * 60 * 1e3), M = 12e3, N = 3, L = async (e) => {
|
|
88
88
|
i({ function: "SimplePay/startRecurringPayment", paymentData: e });
|
|
89
89
|
const n = e.currency || "HUF", { MERCHANT_KEY: r, MERCHANT_ID: t, API_URL_PAYMENT: s, SDK_VERSION: c } = E(n);
|
|
@@ -93,7 +93,7 @@ const g = ["HUF", "EUR", "USD"], i = (...e) => {
|
|
|
93
93
|
salt: S.randomBytes(16).toString("hex"),
|
|
94
94
|
merchant: t,
|
|
95
95
|
orderRef: e.orderRef,
|
|
96
|
-
currency: n,
|
|
96
|
+
currency: n.replace("_SZEP", ""),
|
|
97
97
|
customer: e.customer,
|
|
98
98
|
customerEmail: e.customerEmail,
|
|
99
99
|
language: e.language || "HU",
|
|
@@ -101,16 +101,16 @@ const g = ["HUF", "EUR", "USD"], i = (...e) => {
|
|
|
101
101
|
methods: ["CARD"],
|
|
102
102
|
recurring: {
|
|
103
103
|
times: e.recurring.times || N,
|
|
104
|
-
until: e.recurring.until ||
|
|
104
|
+
until: e.recurring.until || P(C),
|
|
105
105
|
maxAmount: e.recurring.maxAmount || M
|
|
106
106
|
},
|
|
107
107
|
threeDSReqAuthMethod: "02",
|
|
108
108
|
total: String(e.total),
|
|
109
|
-
timeout:
|
|
109
|
+
timeout: P(new Date(Date.now() + 30 * 60 * 1e3)),
|
|
110
110
|
url: process.env.SIMPLEPAY_REDIRECT_URL || "http://url.to.redirect",
|
|
111
111
|
invoice: e.invoice
|
|
112
112
|
};
|
|
113
|
-
return
|
|
113
|
+
return I(s, o, r);
|
|
114
114
|
}, H = async (e) => {
|
|
115
115
|
i({ function: "SimplePay/startTokenPayment", paymentData: e });
|
|
116
116
|
const n = e.currency || "HUF", { MERCHANT_KEY: r, MERCHANT_ID: t, API_URL_RECURRING: s, SDK_VERSION: c } = E(n);
|
|
@@ -120,7 +120,7 @@ const g = ["HUF", "EUR", "USD"], i = (...e) => {
|
|
|
120
120
|
salt: S.randomBytes(16).toString("hex"),
|
|
121
121
|
merchant: t,
|
|
122
122
|
orderRef: e.orderRef,
|
|
123
|
-
currency: n,
|
|
123
|
+
currency: n.replace("_SZEP", ""),
|
|
124
124
|
customer: e.customer,
|
|
125
125
|
customerEmail: e.customerEmail,
|
|
126
126
|
language: e.language || "HU",
|
|
@@ -130,11 +130,11 @@ const g = ["HUF", "EUR", "USD"], i = (...e) => {
|
|
|
130
130
|
type: "MIT",
|
|
131
131
|
threeDSReqAuthMethod: "02",
|
|
132
132
|
total: String(e.total),
|
|
133
|
-
timeout:
|
|
133
|
+
timeout: P(new Date(Date.now() + 30 * 60 * 1e3)),
|
|
134
134
|
url: process.env.SIMPLEPAY_REDIRECT_URL || "http://recurring.url.to.redirect",
|
|
135
135
|
invoice: e.invoice
|
|
136
136
|
};
|
|
137
|
-
return
|
|
137
|
+
return f(s, o, r);
|
|
138
138
|
}, k = async (e) => {
|
|
139
139
|
i({ function: "SimplePay/cancelCard", cardId: e });
|
|
140
140
|
const { API_URL_CARD_CANCEL: n, MERCHANT_KEY: r, MERCHANT_ID: t, SDK_VERSION: s } = E("HUF");
|
|
@@ -151,11 +151,11 @@ const g = ["HUF", "EUR", "USD"], i = (...e) => {
|
|
|
151
151
|
export {
|
|
152
152
|
k as cancelCard,
|
|
153
153
|
_ as checkSignature,
|
|
154
|
-
|
|
154
|
+
m as generateSignature,
|
|
155
155
|
U as getPaymentResponse,
|
|
156
156
|
w as startPayment,
|
|
157
157
|
L as startRecurringPayment,
|
|
158
158
|
H as startTokenPayment,
|
|
159
|
-
|
|
159
|
+
P as toISO8601DateString
|
|
160
160
|
};
|
|
161
161
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/types.ts","../src/utils.ts","../src/oneTime.ts","../src/recurring.ts"],"sourcesContent":["export type PaymentMethod = 'CARD' | 'WIRE'\n\nexport const CURRENCIES = ['HUF', 'EUR', 'USD'] as const\nexport type Currency = typeof CURRENCIES[number]\n\nexport const LANGUAGES = [\n 'AR', // Arabic\n 'BG', // Bulgarian\n 'CS', // Czech\n 'DE', // German\n 'EN', // English\n 'ES', // Spanish\n 'FR', // French\n 'IT', // Italian\n 'HR', // Croatian\n 'HU', // Hungarian\n 'PL', // Polish\n 'RO', // Romanian\n 'RU', // Russian\n 'SK', // Slovak\n 'TR', // Turkish\n 'ZH', // Chinese\n] as const\nexport type Language = typeof LANGUAGES[number]\n\nexport interface PaymentData {\n orderRef: string\n total: number | string\n customerEmail: string\n currency?: Currency\n language?: Language\n method?: PaymentMethod\n invoice?: {\n name: string\n country: string\n state: string\n city: string\n zip: string\n address: string\n address2?: string\n phone?: string\n }\n}\n\nexport type ISO8601DateString = string\nexport interface Recurring {\n times: number,\n until: ISO8601DateString,\n maxAmount: number\n}\nexport interface RecurringPaymentData extends PaymentData {\n customer: string,\n recurring: Recurring\n}\n\nexport interface TokenPaymentData extends Omit<PaymentData, 'method'> {\n method: 'CARD',\n customer: string,\n token: string\n}\n\nexport interface SimplePayRequestBody extends Omit<PaymentData, 'total'> {\n total: string\n salt: string\n merchant: string\n sdkVersion: string\n methods: PaymentMethod[]\n timeout: string\n url: string\n}\n\nexport interface SimplePayRecurringRequestBody extends SimplePayRequestBody {\n customer: string\n recurring: Recurring\n threeDSReqAuthMethod: '02' // only registered users can use this\n}\n\nexport interface SimplePayTokenRequestBody extends SimplePayRequestBody {\n customer: string\n token: string\n threeDSReqAuthMethod: '02' // only registered users can use this\n type: 'MIT' // Merchant Initiated Transaction\n}\n\nexport interface SimplePayCancelCardRequestBody {\n salt: string\n cardId: string\n merchant: string\n sdkVersion: string\n}\n\nexport interface SimplePayResponse {\n salt: string\n merchant: string\n orderRef: string\n currency: Currency\n transactionId: string\n timeout: ISO8601DateString\n total: string\n paymentUrl: string\n errorCodes?: string[]\n}\n\nexport interface SimplePayRecurringResponse extends SimplePayResponse {\n tokens: string[]\n}\n\nexport interface SimplePayTokenResponse extends Omit<SimplePayResponse, 'paymentUrl' | 'timeout'> { }\n\nexport interface SimplePayCancelCardResponse {\n salt: string\n merchant: string\n cardId: string\n status: 'DISABLED'\n expiry: string\n}\n\nexport type SimplePayEvents = 'SUCCESS' | 'FAIL' | 'TIMEOUT' | 'CANCEL'\n\nexport interface SimplePayAPIResult {\n r: number // response code\n t: string // transaction id\n e: SimplePayEvents // event\n m: string // merchant id\n o: string // order id\n}\n\nexport interface SimplePayResult {\n responseCode: number,\n transactionId: string,\n event: SimplePayEvents,\n merchantId: string,\n orderRef: string,\n tokens?: string[],\n}\n","import crypto from 'crypto'\nimport { CURRENCIES, Currency, ISO8601DateString, SimplePayAPIResult, SimplePayCancelCardRequestBody, SimplePayCancelCardResponse, SimplePayRecurringRequestBody, SimplePayRecurringResponse, SimplePayRequestBody, SimplePayResponse, SimplePayResult, SimplePayTokenRequestBody, SimplePayTokenResponse } from \"./types\"\n\nexport const simplepayLogger = (...args: any[]) => {\n if (process.env.SIMPLEPAY_LOGGER !== 'true') {\n return\n }\n\n console.log('👉 ', ...args)\n}\n\nexport const getSimplePayConfig = (currency: Currency) => {\n if (!CURRENCIES.includes(currency)) {\n throw new Error(`Unsupported currency: ${currency}`)\n }\n\n const SIMPLEPAY_API_URL = 'https://secure.simplepay.hu/payment/v2'\n const SIMPLEPAY_SANDBOX_URL = 'https://sandbox.simplepay.hu/payment/v2'\n const SDK_VERSION = 'SimplePayV2.1_Rrd_0.8.2'\n const MERCHANT_KEY = process.env[`SIMPLEPAY_MERCHANT_KEY_${currency}`]\n const MERCHANT_ID = process.env[`SIMPLEPAY_MERCHANT_ID_${currency}`]\n\n const API_URL = process.env.SIMPLEPAY_PRODUCTION === 'true' ? SIMPLEPAY_API_URL : SIMPLEPAY_SANDBOX_URL\n const API_URL_PAYMENT = API_URL + '/start'\n const API_URL_RECURRING = API_URL + '/dorecurring'\n const API_URL_CARD_CANCEL = API_URL + '/cardcancel'\n return {\n MERCHANT_KEY,\n MERCHANT_ID,\n API_URL_PAYMENT,\n API_URL_RECURRING,\n API_URL_CARD_CANCEL,\n SDK_VERSION\n }\n}\n\n// escaping slashes for the request body to prevent strange SimplePay API errors (eg Missing Signature)\nexport const prepareRequestBody = (body: any) =>\n JSON.stringify(body).replace(/\\//g, '\\\\/')\n\nexport const generateSignature = (body: string, merchantKey: string) => {\n const hmac = crypto.createHmac('sha384', merchantKey.trim())\n hmac.update(body, 'utf8')\n return hmac.digest('base64')\n}\n\nexport const checkSignature = (responseText: string, signature: string, merchantKey: string) =>\n signature === generateSignature(responseText, merchantKey)\n\nexport const toISO8601DateString = (date: Date): ISO8601DateString => date.toISOString().replace(/\\.\\d{3}Z$/, '+00:00')\n\nexport const getCurrencyFromMerchantId = (merchantId: string) => {\n const currency = Object.entries(process.env)\n .find(([key, value]) =>\n key.startsWith('SIMPLEPAY_MERCHANT_ID_') && value === merchantId\n )?.[0]?.replace('SIMPLEPAY_MERCHANT_ID_', '') as Currency\n if (!currency) {\n throw new Error(`Merchant id not found in the environment: ${merchantId}`)\n }\n return currency\n}\n\nexport const makeSimplePayRequest = async (apiUrl: string, requestBody: SimplePayRequestBody, merchantKey: string) => {\n return makeRequest(apiUrl, requestBody, merchantKey, 'oneTime') as Promise<SimplePayResponse>\n}\n\nexport const makeSimplePayRecurringRequest = async (apiUrl: string, requestBody: SimplePayRecurringRequestBody, merchantKey: string) => {\n return makeRequest(apiUrl, requestBody, merchantKey, 'recurring') as Promise<SimplePayRecurringResponse>\n}\n\nexport const makeSimplePayTokenRequest = async (apiUrl: string, requestBody: SimplePayTokenRequestBody, merchantKey: string) => {\n return makeRequest(apiUrl, requestBody, merchantKey, 'token') as Promise<SimplePayTokenResponse>\n}\n\nexport const makeSimplePayCancelCardRequest = async (apiUrl: string, requestBody: SimplePayCancelCardRequestBody, merchantKey: string) => {\n return makeRequest(apiUrl, requestBody, merchantKey, 'cancelCard') as Promise<SimplePayCancelCardResponse>\n}\n\nconst makeRequest = async (apiUrl: string, requestBody: SimplePayRequestBody | SimplePayRecurringRequestBody | SimplePayTokenRequestBody | SimplePayCancelCardRequestBody, merchantKey: string, type: 'oneTime' | 'recurring' | 'token' | 'cancelCard') => {\n const bodyString = prepareRequestBody(requestBody)\n const signature = generateSignature(bodyString, merchantKey)\n simplepayLogger({ function: `SimplePay/makeRequest/${type}`, bodyString, signature })\n\n try {\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Signature': signature,\n },\n body: bodyString,\n })\n\n simplepayLogger({ function: `SimplePay/makeRequest/${type}`, response })\n\n if (!response.ok) {\n throw new Error(`SimplePay API error: ${response.status}`)\n }\n\n const responseSignature = response.headers.get('Signature')\n simplepayLogger({ function: `SimplePay/makeRequest/${type}`, responseSignature })\n if (!responseSignature) {\n throw new Error('Missing response signature')\n }\n\n const responseText = await response.text()\n const responseJSON = JSON.parse(responseText) as { errorCodes?: string[] }\n simplepayLogger({ function: `SimplePay/makeRequest/${type}`, responseText, responseJSON })\n\n if (responseJSON.errorCodes) {\n throw new Error(`SimplePay API error: ${responseJSON.errorCodes}`)\n }\n\n if (!checkSignature(responseText, responseSignature, merchantKey)) {\n throw new Error('Invalid response signature')\n }\n\n return responseJSON\n\n } catch (error) {\n throw error\n }\n}\n\nexport const getPaymentResponse = (r: string, signature: string) => {\n simplepayLogger({ function: 'SimplePay/getPaymentResponse', r, signature })\n signature = decodeURIComponent(signature)\n const rDecoded = Buffer.from(r, 'base64').toString('utf-8')\n const rDecodedJSON = JSON.parse(rDecoded) as SimplePayAPIResult\n const currency = getCurrencyFromMerchantId(rDecodedJSON.m)\n const { MERCHANT_KEY } = getSimplePayConfig(currency as Currency)\n\n if (!checkSignature(rDecoded, signature, MERCHANT_KEY || '')) {\n simplepayLogger({ function: 'SimplePay/getPaymentResponse', rDecoded, signature })\n throw new Error('Invalid response signature')\n }\n\n const responseJson = JSON.parse(rDecoded)\n const response: SimplePayResult = {\n responseCode: responseJson.r,\n transactionId: responseJson.t,\n event: responseJson.e,\n merchantId: responseJson.m,\n orderRef: responseJson.o,\n tokens: responseJson.tokens,\n }\n\n return response\n}\n","import crypto from 'crypto'\nimport { PaymentData, SimplePayRequestBody } from './types'\nimport { simplepayLogger, getSimplePayConfig, toISO8601DateString, makeSimplePayRequest } from './utils'\n\nconst startPayment = async (paymentData: PaymentData) => {\n simplepayLogger({ function: 'SimplePay/startPayment', paymentData })\n const currency = paymentData.currency || 'HUF'\n const { MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ function: 'SimplePay/startPayment', MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT })\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error(`Missing SimplePay configuration for ${currency}`)\n }\n\n const requestBody: SimplePayRequestBody = {\n salt: crypto.randomBytes(16).toString('hex'),\n merchant: MERCHANT_ID,\n orderRef: paymentData.orderRef,\n currency,\n customerEmail: paymentData.customerEmail,\n language: paymentData.language || 'HU',\n sdkVersion: SDK_VERSION,\n methods: [paymentData.method || 'CARD'],\n total: String(paymentData.total),\n timeout: toISO8601DateString(new Date(Date.now() + 30 * 60 * 1000)),\n url: process.env.SIMPLEPAY_REDIRECT_URL || 'http://url.to.redirect',\n invoice: paymentData.invoice,\n }\n\n return makeSimplePayRequest(API_URL_PAYMENT, requestBody, MERCHANT_KEY)\n}\n\nexport { startPayment }\n","import crypto from 'crypto'\nimport { SimplePayRecurringRequestBody, RecurringPaymentData, TokenPaymentData, SimplePayTokenRequestBody, SimplePayCancelCardRequestBody} from './types'\nimport { getSimplePayConfig, simplepayLogger, toISO8601DateString, makeSimplePayTokenRequest, makeSimplePayRecurringRequest, makeSimplePayRequest, makeSimplePayCancelCardRequest} from './utils'\n\nconst INTERVAL_IN_MONTHS = 6\nconst DEFAULT_UNTIL = new Date(Date.now() + INTERVAL_IN_MONTHS * 30 * 24 * 60 * 60 * 1000)\nconst DEFAULT_MAX_AMOUNT = 12000\nconst DEFAULT_TIMES = 3\n\nconst startRecurringPayment = async (paymentData: RecurringPaymentData) => {\n simplepayLogger({ function: 'SimplePay/startRecurringPayment', paymentData })\n const currency = paymentData.currency || 'HUF'\n const { MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ function: 'SimplePay/startRecurringPayment', MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT })\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error(`Missing SimplePay configuration for ${currency}`)\n }\n\n const requestBody: SimplePayRecurringRequestBody = {\n salt: crypto.randomBytes(16).toString('hex'),\n merchant: MERCHANT_ID,\n orderRef: paymentData.orderRef,\n currency,\n customer: paymentData.customer,\n customerEmail: paymentData.customerEmail,\n language: paymentData.language || 'HU',\n sdkVersion: SDK_VERSION,\n methods: ['CARD'],\n recurring: {\n times: paymentData.recurring.times || DEFAULT_TIMES,\n until: paymentData.recurring.until || toISO8601DateString(DEFAULT_UNTIL),\n maxAmount: paymentData.recurring.maxAmount || DEFAULT_MAX_AMOUNT\n },\n threeDSReqAuthMethod: '02', \n total: String(paymentData.total),\n timeout: toISO8601DateString(new Date(Date.now() + 30 * 60 * 1000)),\n url: process.env.SIMPLEPAY_REDIRECT_URL || 'http://url.to.redirect',\n invoice: paymentData.invoice,\n }\n\n return makeSimplePayRecurringRequest(API_URL_PAYMENT, requestBody, MERCHANT_KEY)\n}\n\nconst startTokenPayment = async (paymentData: TokenPaymentData) => {\n simplepayLogger({ function: 'SimplePay/startTokenPayment', paymentData })\n const currency = paymentData.currency || 'HUF'\n const { MERCHANT_KEY, MERCHANT_ID, API_URL_RECURRING, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ function: 'SimplePay/startTokenPayment', MERCHANT_KEY, MERCHANT_ID, API_URL_RECURRING })\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error(`Missing SimplePay configuration for ${currency}`)\n }\n\n const requestBody: SimplePayTokenRequestBody = {\n salt: crypto.randomBytes(16).toString('hex'),\n merchant: MERCHANT_ID,\n orderRef: paymentData.orderRef,\n currency,\n customer: paymentData.customer,\n customerEmail: paymentData.customerEmail,\n language: paymentData.language || 'HU',\n sdkVersion: SDK_VERSION,\n methods: ['CARD'],\n token: paymentData.token,\n type: 'MIT',\n threeDSReqAuthMethod: '02',\n total: String(paymentData.total),\n timeout: toISO8601DateString(new Date(Date.now() + 30 * 60 * 1000)),\n url: process.env.SIMPLEPAY_REDIRECT_URL || 'http://recurring.url.to.redirect',\n invoice: paymentData.invoice,\n }\n\n return makeSimplePayTokenRequest(API_URL_RECURRING, requestBody, MERCHANT_KEY)\n}\n\nconst cancelCard = async (cardId: string) => {\n simplepayLogger({ function: 'SimplePay/cancelCard', cardId })\n const {API_URL_CARD_CANCEL, MERCHANT_KEY, MERCHANT_ID, SDK_VERSION} = getSimplePayConfig('HUF')\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error(`Missing SimplePay configuration for HUF`)\n }\n\n const requestBody: SimplePayCancelCardRequestBody = {\n salt: crypto.randomBytes(16).toString('hex'),\n cardId,\n merchant: MERCHANT_ID,\n sdkVersion: SDK_VERSION,\n }\n return makeSimplePayCancelCardRequest(API_URL_CARD_CANCEL, requestBody, MERCHANT_KEY)\n}\n\nexport { startRecurringPayment, startTokenPayment , cancelCard}\n"],"names":["CURRENCIES","simplepayLogger","args","getSimplePayConfig","currency","SIMPLEPAY_API_URL","SIMPLEPAY_SANDBOX_URL","SDK_VERSION","MERCHANT_KEY","MERCHANT_ID","API_URL","API_URL_PAYMENT","API_URL_RECURRING","API_URL_CARD_CANCEL","prepareRequestBody","body","generateSignature","merchantKey","hmac","crypto","checkSignature","responseText","signature","toISO8601DateString","date","getCurrencyFromMerchantId","merchantId","_b","_a","key","value","makeSimplePayRequest","apiUrl","requestBody","makeRequest","makeSimplePayRecurringRequest","makeSimplePayTokenRequest","makeSimplePayCancelCardRequest","type","bodyString","response","responseSignature","responseJSON","error","getPaymentResponse","r","rDecoded","rDecodedJSON","responseJson","startPayment","paymentData","INTERVAL_IN_MONTHS","DEFAULT_UNTIL","DEFAULT_MAX_AMOUNT","DEFAULT_TIMES","startRecurringPayment","startTokenPayment","cancelCard","cardId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/types.ts","../src/utils.ts","../src/oneTime.ts","../src/recurring.ts"],"sourcesContent":["export type PaymentMethod = 'CARD' | 'WIRE'\n\nexport const CURRENCIES = ['HUF', 'HUF_SZEP', 'EUR', 'USD'] as const\nexport type Currency = typeof CURRENCIES[number]\n\nexport const LANGUAGES = [\n 'AR', // Arabic\n 'BG', // Bulgarian\n 'CS', // Czech\n 'DE', // German\n 'EN', // English\n 'ES', // Spanish\n 'FR', // French\n 'IT', // Italian\n 'HR', // Croatian\n 'HU', // Hungarian\n 'PL', // Polish\n 'RO', // Romanian\n 'RU', // Russian\n 'SK', // Slovak\n 'TR', // Turkish\n 'ZH', // Chinese\n] as const\nexport type Language = typeof LANGUAGES[number]\n\nexport interface PaymentData {\n orderRef: string\n total: number | string\n customerEmail: string\n currency?: Currency\n language?: Language\n method?: PaymentMethod\n invoice?: {\n name: string\n country: string\n state: string\n city: string\n zip: string\n address: string\n address2?: string\n phone?: string\n }\n}\n\nexport interface PaymentConfig {\n redirectUrl?: string\n}\n\nexport type ISO8601DateString = string\nexport interface Recurring {\n times: number,\n until: ISO8601DateString,\n maxAmount: number\n}\nexport interface RecurringPaymentData extends PaymentData {\n customer: string,\n recurring: Recurring\n}\n\nexport interface TokenPaymentData extends Omit<PaymentData, 'method'> {\n method: 'CARD',\n customer: string,\n token: string\n}\n\nexport interface SimplePayRequestBody extends Omit<PaymentData, 'total'> {\n total: string\n salt: string\n merchant: string\n sdkVersion: string\n methods: PaymentMethod[]\n timeout: string\n url: string\n}\n\nexport interface SimplePayRecurringRequestBody extends SimplePayRequestBody {\n customer: string\n recurring: Recurring\n threeDSReqAuthMethod: '02' // only registered users can use this\n}\n\nexport interface SimplePayTokenRequestBody extends SimplePayRequestBody {\n customer: string\n token: string\n threeDSReqAuthMethod: '02' // only registered users can use this\n type: 'MIT' // Merchant Initiated Transaction\n}\n\nexport interface SimplePayCancelCardRequestBody {\n salt: string\n cardId: string\n merchant: string\n sdkVersion: string\n}\n\nexport interface SimplePayResponse {\n salt: string\n merchant: string\n orderRef: string\n currency: Currency\n transactionId: string\n timeout: ISO8601DateString\n total: string\n paymentUrl: string\n errorCodes?: string[]\n}\n\nexport interface SimplePayRecurringResponse extends SimplePayResponse {\n tokens: string[]\n}\n\nexport interface SimplePayTokenResponse extends Omit<SimplePayResponse, 'paymentUrl' | 'timeout'> { }\n\nexport interface SimplePayCancelCardResponse {\n salt: string\n merchant: string\n cardId: string\n status: 'DISABLED'\n expiry: string\n}\n\nexport type SimplePayEvents = 'SUCCESS' | 'FAIL' | 'TIMEOUT' | 'CANCEL'\n\nexport interface SimplePayAPIResult {\n r: number // response code\n t: string // transaction id\n e: SimplePayEvents // event\n m: string // merchant id\n o: string // order id\n}\n\nexport interface SimplePayResult {\n responseCode: number,\n transactionId: string,\n event: SimplePayEvents,\n merchantId: string,\n orderRef: string,\n tokens?: string[],\n}\n","import crypto from 'crypto'\nimport { CURRENCIES, Currency, ISO8601DateString, SimplePayAPIResult, SimplePayCancelCardRequestBody, SimplePayCancelCardResponse, SimplePayRecurringRequestBody, SimplePayRecurringResponse, SimplePayRequestBody, SimplePayResponse, SimplePayResult, SimplePayTokenRequestBody, SimplePayTokenResponse } from \"./types\"\n\nexport const simplepayLogger = (...args: any[]) => {\n if (process.env.SIMPLEPAY_LOGGER !== 'true') {\n return\n }\n\n console.log('👉 ', ...args)\n}\n\nexport const getSimplePayConfig = (currency: Currency) => {\n if (!CURRENCIES.includes(currency)) {\n throw new Error(`Unsupported currency: ${currency}`)\n }\n\n const SIMPLEPAY_API_URL = 'https://secure.simplepay.hu/payment/v2'\n const SIMPLEPAY_SANDBOX_URL = 'https://sandbox.simplepay.hu/payment/v2'\n const SDK_VERSION = 'SimplePay_Rrd_0.9.0'\n const MERCHANT_KEY = process.env[`SIMPLEPAY_MERCHANT_KEY_${currency}`]\n const MERCHANT_ID = process.env[`SIMPLEPAY_MERCHANT_ID_${currency}`]\n\n const API_URL = process.env.SIMPLEPAY_PRODUCTION === 'true' ? SIMPLEPAY_API_URL : SIMPLEPAY_SANDBOX_URL\n const API_URL_PAYMENT = API_URL + '/start'\n const API_URL_RECURRING = API_URL + '/dorecurring'\n const API_URL_CARD_CANCEL = API_URL + '/cardcancel'\n return {\n MERCHANT_KEY,\n MERCHANT_ID,\n API_URL_PAYMENT,\n API_URL_RECURRING,\n API_URL_CARD_CANCEL,\n SDK_VERSION\n }\n}\n\n// escaping slashes for the request body to prevent strange SimplePay API errors (eg Missing Signature)\nexport const prepareRequestBody = (body: any) =>\n JSON.stringify(body).replace(/\\//g, '\\\\/')\n\nexport const generateSignature = (body: string, merchantKey: string) => {\n const hmac = crypto.createHmac('sha384', merchantKey.trim())\n hmac.update(body, 'utf8')\n return hmac.digest('base64')\n}\n\nexport const checkSignature = (responseText: string, signature: string, merchantKey: string) =>\n signature === generateSignature(responseText, merchantKey)\n\nexport const toISO8601DateString = (date: Date): ISO8601DateString => date.toISOString().replace(/\\.\\d{3}Z$/, '+00:00')\n\nexport const getCurrencyFromMerchantId = (merchantId: string) => {\n const currency = Object.entries(process.env)\n .find(([key, value]) =>\n key.startsWith('SIMPLEPAY_MERCHANT_ID_') && value === merchantId\n )?.[0]?.replace('SIMPLEPAY_MERCHANT_ID_', '') as Currency\n\n if (!currency) {\n throw new Error(`Merchant id not found in the environment: ${merchantId}`)\n }\n\n // if currency ends with _SZEP, remove it\n return currency.replace('_SZEP', '')\n}\n\nexport const makeSimplePayRequest = async (apiUrl: string, requestBody: SimplePayRequestBody, merchantKey: string) => {\n return makeRequest(apiUrl, requestBody, merchantKey, 'oneTime') as Promise<SimplePayResponse>\n}\n\nexport const makeSimplePayRecurringRequest = async (apiUrl: string, requestBody: SimplePayRecurringRequestBody, merchantKey: string) => {\n return makeRequest(apiUrl, requestBody, merchantKey, 'recurring') as Promise<SimplePayRecurringResponse>\n}\n\nexport const makeSimplePayTokenRequest = async (apiUrl: string, requestBody: SimplePayTokenRequestBody, merchantKey: string) => {\n return makeRequest(apiUrl, requestBody, merchantKey, 'token') as Promise<SimplePayTokenResponse>\n}\n\nexport const makeSimplePayCancelCardRequest = async (apiUrl: string, requestBody: SimplePayCancelCardRequestBody, merchantKey: string) => {\n return makeRequest(apiUrl, requestBody, merchantKey, 'cancelCard') as Promise<SimplePayCancelCardResponse>\n}\n\nconst makeRequest = async (apiUrl: string, requestBody: SimplePayRequestBody | SimplePayRecurringRequestBody | SimplePayTokenRequestBody | SimplePayCancelCardRequestBody, merchantKey: string, type: 'oneTime' | 'recurring' | 'token' | 'cancelCard') => {\n const bodyString = prepareRequestBody(requestBody)\n const signature = generateSignature(bodyString, merchantKey)\n simplepayLogger({ function: `SimplePay/makeRequest/${type}`, bodyString, signature })\n\n try {\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Signature': signature,\n },\n body: bodyString,\n })\n\n simplepayLogger({ function: `SimplePay/makeRequest/${type}`, response })\n\n if (!response.ok) {\n throw new Error(`SimplePay API error: ${response.status}`)\n }\n\n const responseSignature = response.headers.get('Signature')\n simplepayLogger({ function: `SimplePay/makeRequest/${type}`, responseSignature })\n if (!responseSignature) {\n throw new Error('Missing response signature')\n }\n\n const responseText = await response.text()\n const responseJSON = JSON.parse(responseText) as { errorCodes?: string[] }\n simplepayLogger({ function: `SimplePay/makeRequest/${type}`, responseText, responseJSON })\n\n if (responseJSON.errorCodes) {\n throw new Error(`SimplePay API error: ${responseJSON.errorCodes}`)\n }\n\n if (!checkSignature(responseText, responseSignature, merchantKey)) {\n throw new Error('Invalid response signature')\n }\n\n return responseJSON\n\n } catch (error) {\n throw error\n }\n}\n\nexport const getPaymentResponse = (r: string, signature: string) => {\n simplepayLogger({ function: 'SimplePay/getPaymentResponse', r, signature })\n signature = decodeURIComponent(signature)\n const rDecoded = Buffer.from(r, 'base64').toString('utf-8')\n const rDecodedJSON = JSON.parse(rDecoded) as SimplePayAPIResult\n const currency = getCurrencyFromMerchantId(rDecodedJSON.m)\n const { MERCHANT_KEY } = getSimplePayConfig(currency as Currency)\n\n if (!checkSignature(rDecoded, signature, MERCHANT_KEY || '')) {\n simplepayLogger({ function: 'SimplePay/getPaymentResponse', rDecoded, signature })\n throw new Error('Invalid response signature')\n }\n\n const responseJson = JSON.parse(rDecoded)\n const response: SimplePayResult = {\n responseCode: responseJson.r,\n transactionId: responseJson.t,\n event: responseJson.e,\n merchantId: responseJson.m,\n orderRef: responseJson.o,\n tokens: responseJson.tokens,\n }\n\n return response\n}\n","import crypto from 'crypto'\nimport { Currency, PaymentConfig, PaymentData, SimplePayRequestBody } from './types'\nimport { simplepayLogger, getSimplePayConfig, toISO8601DateString, makeSimplePayRequest } from './utils'\n\nconst startPayment = async (paymentData: PaymentData, config: PaymentConfig = {}) => {\n simplepayLogger({ function: 'SimplePay/startPayment', paymentData })\n const currency = paymentData.currency || 'HUF'\n const { MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ function: 'SimplePay/startPayment', MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT })\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error(`Missing SimplePay configuration for ${currency}`)\n }\n\n const requestBody: SimplePayRequestBody = {\n salt: crypto.randomBytes(16).toString('hex'),\n merchant: MERCHANT_ID,\n orderRef: paymentData.orderRef,\n currency: currency.replace('_SZEP', '') as Currency,\n customerEmail: paymentData.customerEmail,\n language: paymentData.language || 'HU',\n sdkVersion: SDK_VERSION,\n methods: [paymentData.method || 'CARD'],\n total: String(paymentData.total),\n timeout: toISO8601DateString(new Date(Date.now() + 30 * 60 * 1000)),\n url: config.redirectUrl || process.env.SIMPLEPAY_REDIRECT_URL || 'http://url.to.redirect',\n invoice: paymentData.invoice,\n }\n\n return makeSimplePayRequest(API_URL_PAYMENT, requestBody, MERCHANT_KEY)\n}\n\nexport { startPayment }\n","import crypto from 'crypto'\nimport { SimplePayRecurringRequestBody, RecurringPaymentData, TokenPaymentData, SimplePayTokenRequestBody, SimplePayCancelCardRequestBody, Currency} from './types'\nimport { getSimplePayConfig, simplepayLogger, toISO8601DateString, makeSimplePayTokenRequest, makeSimplePayRecurringRequest, makeSimplePayRequest, makeSimplePayCancelCardRequest} from './utils'\n\nconst INTERVAL_IN_MONTHS = 6\nconst DEFAULT_UNTIL = new Date(Date.now() + INTERVAL_IN_MONTHS * 30 * 24 * 60 * 60 * 1000)\nconst DEFAULT_MAX_AMOUNT = 12000\nconst DEFAULT_TIMES = 3\n\nconst startRecurringPayment = async (paymentData: RecurringPaymentData) => {\n simplepayLogger({ function: 'SimplePay/startRecurringPayment', paymentData })\n const currency = paymentData.currency || 'HUF'\n const { MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ function: 'SimplePay/startRecurringPayment', MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT })\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error(`Missing SimplePay configuration for ${currency}`)\n }\n\n const requestBody: SimplePayRecurringRequestBody = {\n salt: crypto.randomBytes(16).toString('hex'),\n merchant: MERCHANT_ID,\n orderRef: paymentData.orderRef,\n currency: currency.replace('_SZEP', '') as Currency,\n customer: paymentData.customer,\n customerEmail: paymentData.customerEmail,\n language: paymentData.language || 'HU',\n sdkVersion: SDK_VERSION,\n methods: ['CARD'],\n recurring: {\n times: paymentData.recurring.times || DEFAULT_TIMES,\n until: paymentData.recurring.until || toISO8601DateString(DEFAULT_UNTIL),\n maxAmount: paymentData.recurring.maxAmount || DEFAULT_MAX_AMOUNT\n },\n threeDSReqAuthMethod: '02', \n total: String(paymentData.total),\n timeout: toISO8601DateString(new Date(Date.now() + 30 * 60 * 1000)),\n url: process.env.SIMPLEPAY_REDIRECT_URL || 'http://url.to.redirect',\n invoice: paymentData.invoice,\n }\n\n return makeSimplePayRecurringRequest(API_URL_PAYMENT, requestBody, MERCHANT_KEY)\n}\n\nconst startTokenPayment = async (paymentData: TokenPaymentData) => {\n simplepayLogger({ function: 'SimplePay/startTokenPayment', paymentData })\n const currency = paymentData.currency || 'HUF'\n const { MERCHANT_KEY, MERCHANT_ID, API_URL_RECURRING, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ function: 'SimplePay/startTokenPayment', MERCHANT_KEY, MERCHANT_ID, API_URL_RECURRING })\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error(`Missing SimplePay configuration for ${currency}`)\n }\n\n const requestBody: SimplePayTokenRequestBody = {\n salt: crypto.randomBytes(16).toString('hex'),\n merchant: MERCHANT_ID,\n orderRef: paymentData.orderRef,\n currency: currency.replace('_SZEP', '') as Currency,\n customer: paymentData.customer,\n customerEmail: paymentData.customerEmail,\n language: paymentData.language || 'HU',\n sdkVersion: SDK_VERSION,\n methods: ['CARD'],\n token: paymentData.token,\n type: 'MIT',\n threeDSReqAuthMethod: '02',\n total: String(paymentData.total),\n timeout: toISO8601DateString(new Date(Date.now() + 30 * 60 * 1000)),\n url: process.env.SIMPLEPAY_REDIRECT_URL || 'http://recurring.url.to.redirect',\n invoice: paymentData.invoice,\n }\n\n return makeSimplePayTokenRequest(API_URL_RECURRING, requestBody, MERCHANT_KEY)\n}\n\nconst cancelCard = async (cardId: string) => {\n simplepayLogger({ function: 'SimplePay/cancelCard', cardId })\n const {API_URL_CARD_CANCEL, MERCHANT_KEY, MERCHANT_ID, SDK_VERSION} = getSimplePayConfig('HUF')\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error(`Missing SimplePay configuration for HUF`)\n }\n\n const requestBody: SimplePayCancelCardRequestBody = {\n salt: crypto.randomBytes(16).toString('hex'),\n cardId,\n merchant: MERCHANT_ID,\n sdkVersion: SDK_VERSION,\n }\n return makeSimplePayCancelCardRequest(API_URL_CARD_CANCEL, requestBody, MERCHANT_KEY)\n}\n\nexport { startRecurringPayment, startTokenPayment , cancelCard}\n"],"names":["CURRENCIES","simplepayLogger","args","getSimplePayConfig","currency","SIMPLEPAY_API_URL","SIMPLEPAY_SANDBOX_URL","SDK_VERSION","MERCHANT_KEY","MERCHANT_ID","API_URL","API_URL_PAYMENT","API_URL_RECURRING","API_URL_CARD_CANCEL","prepareRequestBody","body","generateSignature","merchantKey","hmac","crypto","checkSignature","responseText","signature","toISO8601DateString","date","getCurrencyFromMerchantId","merchantId","_b","_a","key","value","makeSimplePayRequest","apiUrl","requestBody","makeRequest","makeSimplePayRecurringRequest","makeSimplePayTokenRequest","makeSimplePayCancelCardRequest","type","bodyString","response","responseSignature","responseJSON","error","getPaymentResponse","r","rDecoded","rDecodedJSON","responseJson","startPayment","paymentData","config","INTERVAL_IN_MONTHS","DEFAULT_UNTIL","DEFAULT_MAX_AMOUNT","DEFAULT_TIMES","startRecurringPayment","startTokenPayment","cancelCard","cardId"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simplepay-js-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "A Node.js utility for SimplePay payment integration",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"license": "MIT",
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.0.0",
|
|
41
|
-
"typescript": "~5.
|
|
41
|
+
"typescript": "~5.8.0",
|
|
42
42
|
"vite": "^6.0.3",
|
|
43
43
|
"vite-plugin-dts": "^4.3.0",
|
|
44
|
-
"vitest": "^
|
|
44
|
+
"vitest": "^3.0.0"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": ">=20.0.0"
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest'
|
|
2
|
+
import { startPayment } from './oneTime'
|
|
3
|
+
import { startRecurringPayment, startTokenPayment, cancelCard } from './recurring'
|
|
4
|
+
import { generateSignature, checkSignature, getPaymentResponse } from './utils'
|
|
5
|
+
|
|
6
|
+
const setEnv = () => {
|
|
7
|
+
process.env.SIMPLEPAY_MERCHANT_ID_HUF = 'testId'
|
|
8
|
+
process.env.SIMPLEPAY_MERCHANT_KEY_HUF = 'testKey'
|
|
9
|
+
process.env.SIMPLEPAY_MERCHANT_ID_HUF_SZEP = 'testIdSzep'
|
|
10
|
+
process.env.SIMPLEPAY_MERCHANT_KEY_HUF_SZEP = 'testKeySzep'
|
|
11
|
+
process.env.SIMPLEPAY_MERCHANT_ID_EUR = 'merchantEuroId'
|
|
12
|
+
process.env.SIMPLEPAY_MERCHANT_KEY_EUR = 'secretEuroKey'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe('SimplePay Basic Tests', () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
// Clear all environment variables before each test
|
|
18
|
+
delete process.env.SIMPLEPAY_MERCHANT_ID_HUF
|
|
19
|
+
delete process.env.SIMPLEPAY_MERCHANT_KEY_HUF
|
|
20
|
+
delete process.env.SIMPLEPAY_MERCHANT_ID_HUF_SZEP
|
|
21
|
+
delete process.env.SIMPLEPAY_MERCHANT_KEY_HUF_SZEP
|
|
22
|
+
delete process.env.SIMPLEPAY_MERCHANT_ID_EUR
|
|
23
|
+
delete process.env.SIMPLEPAY_MERCHANT_KEY_EUR
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
describe('Basic Signature Tests', () => {
|
|
27
|
+
it('should generate and verify signature correctly', () => {
|
|
28
|
+
const merchantKey = 'testKey'
|
|
29
|
+
const testData = { test: 'data' }
|
|
30
|
+
const body = JSON.stringify(testData)
|
|
31
|
+
|
|
32
|
+
const signature = generateSignature(body, merchantKey)
|
|
33
|
+
const isValid = checkSignature(body, signature, merchantKey)
|
|
34
|
+
|
|
35
|
+
expect(isValid).toBeTruthy()
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
describe('Basic Payment Tests', () => {
|
|
40
|
+
it('should throw error when merchant configuration is missing', async () => {
|
|
41
|
+
const paymentData = {
|
|
42
|
+
orderRef: 'TEST123',
|
|
43
|
+
customerEmail: 'test@example.com',
|
|
44
|
+
total: 1212
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
await expect(startPayment(paymentData)).rejects.toThrow('Missing SimplePay configuration')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('should throw error when recurring merchant configuration is missing', async () => {
|
|
51
|
+
const recurringPaymentData = {
|
|
52
|
+
orderRef: 'TEST123',
|
|
53
|
+
customerEmail: 'test@example.com',
|
|
54
|
+
total: 1212,
|
|
55
|
+
customer: 'Test Customer',
|
|
56
|
+
recurring: {
|
|
57
|
+
times: 3,
|
|
58
|
+
until: '2025-12-31T23:59:59+00:00',
|
|
59
|
+
maxAmount: 12000
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
await expect(startRecurringPayment(recurringPaymentData)).rejects.toThrow('Missing SimplePay configuration')
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('should throw error when token merchant configuration is missing', async () => {
|
|
67
|
+
const tokenPaymentData = {
|
|
68
|
+
orderRef: 'TEST123',
|
|
69
|
+
customerEmail: 'test@example.com',
|
|
70
|
+
total: 1212,
|
|
71
|
+
customer: 'Test Customer',
|
|
72
|
+
token: 'test-token',
|
|
73
|
+
method: 'CARD' as const
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
await expect(startTokenPayment(tokenPaymentData)).rejects.toThrow('Missing SimplePay configuration')
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
describe('Basic Response Tests', () => {
|
|
81
|
+
it('should correctly decode and verify payment response', () => {
|
|
82
|
+
setEnv()
|
|
83
|
+
const mockResponse = {
|
|
84
|
+
r: 0,
|
|
85
|
+
t: 504233881,
|
|
86
|
+
e: 'SUCCESS',
|
|
87
|
+
m: 'merchantEuroId',
|
|
88
|
+
o: 'test-order'
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const encodedResponse = Buffer.from(JSON.stringify(mockResponse)).toString('base64')
|
|
92
|
+
const signature = generateSignature(JSON.stringify(mockResponse), 'secretEuroKey')
|
|
93
|
+
|
|
94
|
+
const result = getPaymentResponse(encodedResponse, signature)
|
|
95
|
+
|
|
96
|
+
expect(result).toEqual({
|
|
97
|
+
responseCode: 0,
|
|
98
|
+
transactionId: 504233881,
|
|
99
|
+
event: 'SUCCESS',
|
|
100
|
+
merchantId: 'merchantEuroId',
|
|
101
|
+
orderRef: 'test-order'
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('should throw error for invalid signature in payment response', () => {
|
|
106
|
+
setEnv()
|
|
107
|
+
const mockResponse = {
|
|
108
|
+
r: 0,
|
|
109
|
+
t: 504233881,
|
|
110
|
+
e: 'SUCCESS',
|
|
111
|
+
m: 'merchantEuroId',
|
|
112
|
+
o: 'test-order'
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const encodedResponse = Buffer.from(JSON.stringify(mockResponse)).toString('base64')
|
|
116
|
+
const invalidSignature = 'invalid-signature'
|
|
117
|
+
|
|
118
|
+
expect(() => getPaymentResponse(encodedResponse, invalidSignature)).toThrow('Invalid response signature')
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
describe('Basic Card Cancel Test', () => {
|
|
123
|
+
it('should throw error when merchant configuration is missing for card cancel', async () => {
|
|
124
|
+
await expect(cancelCard('test-card-id')).rejects.toThrow('Missing SimplePay configuration')
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
})
|
package/src/oneTime.spec.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { getPaymentResponse, startPayment } from './index'
|
|
|
4
4
|
const setEnv = () => {
|
|
5
5
|
process.env.SIMPLEPAY_MERCHANT_ID_HUF = 'testId'
|
|
6
6
|
process.env.SIMPLEPAY_MERCHANT_KEY_HUF = 'testKey'
|
|
7
|
+
process.env.SIMPLEPAY_MERCHANT_ID_HUF_SZEP = 'testIdSzep'
|
|
8
|
+
process.env.SIMPLEPAY_MERCHANT_KEY_HUF_SZEP = 'testKeySzep'
|
|
7
9
|
process.env.SIMPLEPAY_MERCHANT_ID_EUR = 'merchantEuroId'
|
|
8
10
|
process.env.SIMPLEPAY_MERCHANT_KEY_EUR = 'secretEuroKey'
|
|
9
11
|
}
|
|
@@ -18,6 +20,8 @@ describe('SimplePay SDK Tests', () => {
|
|
|
18
20
|
// Clear all environment variables before each test
|
|
19
21
|
delete process.env.SIMPLEPAY_MERCHANT_ID_HUF
|
|
20
22
|
delete process.env.SIMPLEPAY_MERCHANT_KEY_HUF
|
|
23
|
+
delete process.env.SIMPLEPAY_MERCHANT_ID_HUF_SZEP
|
|
24
|
+
delete process.env.SIMPLEPAY_MERCHANT_KEY_HUF_SZEP
|
|
21
25
|
delete process.env.SIMPLEPAY_MERCHANT_ID_EUR
|
|
22
26
|
delete process.env.SIMPLEPAY_MERCHANT_KEY_EUR
|
|
23
27
|
})
|
package/src/oneTime.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import crypto from 'crypto'
|
|
2
|
-
import { PaymentData, SimplePayRequestBody } from './types'
|
|
2
|
+
import { Currency, PaymentConfig, PaymentData, SimplePayRequestBody } from './types'
|
|
3
3
|
import { simplepayLogger, getSimplePayConfig, toISO8601DateString, makeSimplePayRequest } from './utils'
|
|
4
4
|
|
|
5
|
-
const startPayment = async (paymentData: PaymentData) => {
|
|
5
|
+
const startPayment = async (paymentData: PaymentData, config: PaymentConfig = {}) => {
|
|
6
6
|
simplepayLogger({ function: 'SimplePay/startPayment', paymentData })
|
|
7
7
|
const currency = paymentData.currency || 'HUF'
|
|
8
8
|
const { MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT, SDK_VERSION } = getSimplePayConfig(currency)
|
|
@@ -16,14 +16,14 @@ const startPayment = async (paymentData: PaymentData) => {
|
|
|
16
16
|
salt: crypto.randomBytes(16).toString('hex'),
|
|
17
17
|
merchant: MERCHANT_ID,
|
|
18
18
|
orderRef: paymentData.orderRef,
|
|
19
|
-
currency,
|
|
19
|
+
currency: currency.replace('_SZEP', '') as Currency,
|
|
20
20
|
customerEmail: paymentData.customerEmail,
|
|
21
21
|
language: paymentData.language || 'HU',
|
|
22
22
|
sdkVersion: SDK_VERSION,
|
|
23
23
|
methods: [paymentData.method || 'CARD'],
|
|
24
24
|
total: String(paymentData.total),
|
|
25
25
|
timeout: toISO8601DateString(new Date(Date.now() + 30 * 60 * 1000)),
|
|
26
|
-
url: process.env.SIMPLEPAY_REDIRECT_URL || 'http://url.to.redirect',
|
|
26
|
+
url: config.redirectUrl || process.env.SIMPLEPAY_REDIRECT_URL || 'http://url.to.redirect',
|
|
27
27
|
invoice: paymentData.invoice,
|
|
28
28
|
}
|
|
29
29
|
|
package/src/recurring.spec.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { toISO8601DateString } from './utils'
|
|
|
5
5
|
const setEnv = () => {
|
|
6
6
|
process.env.SIMPLEPAY_MERCHANT_ID_HUF = 'testId'
|
|
7
7
|
process.env.SIMPLEPAY_MERCHANT_KEY_HUF = 'testKey'
|
|
8
|
+
process.env.SIMPLEPAY_MERCHANT_KEY_HUF_SZEP = 'testKeySzep'
|
|
8
9
|
process.env.SIMPLEPAY_MERCHANT_ID_EUR = 'merchantEuroId'
|
|
9
10
|
process.env.SIMPLEPAY_MERCHANT_KEY_EUR = 'secretEuroKey'
|
|
10
11
|
}
|
|
@@ -25,6 +26,7 @@ describe('SimplePay Recurring Tests', () => {
|
|
|
25
26
|
// Clear all environment variables before each test
|
|
26
27
|
delete process.env.SIMPLEPAY_MERCHANT_ID_HUF
|
|
27
28
|
delete process.env.SIMPLEPAY_MERCHANT_KEY_HUF
|
|
29
|
+
delete process.env.SIMPLEPAY_MERCHANT_KEY_HUF_SZEP
|
|
28
30
|
delete process.env.SIMPLEPAY_MERCHANT_ID_EUR
|
|
29
31
|
delete process.env.SIMPLEPAY_MERCHANT_KEY_EUR
|
|
30
32
|
})
|
package/src/recurring.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import crypto from 'crypto'
|
|
2
|
-
import { SimplePayRecurringRequestBody, RecurringPaymentData, TokenPaymentData, SimplePayTokenRequestBody, SimplePayCancelCardRequestBody} from './types'
|
|
2
|
+
import { SimplePayRecurringRequestBody, RecurringPaymentData, TokenPaymentData, SimplePayTokenRequestBody, SimplePayCancelCardRequestBody, Currency} from './types'
|
|
3
3
|
import { getSimplePayConfig, simplepayLogger, toISO8601DateString, makeSimplePayTokenRequest, makeSimplePayRecurringRequest, makeSimplePayRequest, makeSimplePayCancelCardRequest} from './utils'
|
|
4
4
|
|
|
5
5
|
const INTERVAL_IN_MONTHS = 6
|
|
@@ -21,7 +21,7 @@ const startRecurringPayment = async (paymentData: RecurringPaymentData) => {
|
|
|
21
21
|
salt: crypto.randomBytes(16).toString('hex'),
|
|
22
22
|
merchant: MERCHANT_ID,
|
|
23
23
|
orderRef: paymentData.orderRef,
|
|
24
|
-
currency,
|
|
24
|
+
currency: currency.replace('_SZEP', '') as Currency,
|
|
25
25
|
customer: paymentData.customer,
|
|
26
26
|
customerEmail: paymentData.customerEmail,
|
|
27
27
|
language: paymentData.language || 'HU',
|
|
@@ -56,7 +56,7 @@ const startTokenPayment = async (paymentData: TokenPaymentData) => {
|
|
|
56
56
|
salt: crypto.randomBytes(16).toString('hex'),
|
|
57
57
|
merchant: MERCHANT_ID,
|
|
58
58
|
orderRef: paymentData.orderRef,
|
|
59
|
-
currency,
|
|
59
|
+
currency: currency.replace('_SZEP', '') as Currency,
|
|
60
60
|
customer: paymentData.customer,
|
|
61
61
|
customerEmail: paymentData.customerEmail,
|
|
62
62
|
language: paymentData.language || 'HU',
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type PaymentMethod = 'CARD' | 'WIRE'
|
|
2
2
|
|
|
3
|
-
export const CURRENCIES = ['HUF', 'EUR', 'USD'] as const
|
|
3
|
+
export const CURRENCIES = ['HUF', 'HUF_SZEP', 'EUR', 'USD'] as const
|
|
4
4
|
export type Currency = typeof CURRENCIES[number]
|
|
5
5
|
|
|
6
6
|
export const LANGUAGES = [
|
|
@@ -42,6 +42,10 @@ export interface PaymentData {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export interface PaymentConfig {
|
|
46
|
+
redirectUrl?: string
|
|
47
|
+
}
|
|
48
|
+
|
|
45
49
|
export type ISO8601DateString = string
|
|
46
50
|
export interface Recurring {
|
|
47
51
|
times: number,
|
package/src/utils.spec.ts
CHANGED
|
@@ -5,6 +5,8 @@ import { checkSignature, generateSignature, getCurrencyFromMerchantId, getSimple
|
|
|
5
5
|
const setEnv = () => {
|
|
6
6
|
process.env.SIMPLEPAY_MERCHANT_ID_HUF = 'testId'
|
|
7
7
|
process.env.SIMPLEPAY_MERCHANT_KEY_HUF = 'testKey'
|
|
8
|
+
process.env.SIMPLEPAY_MERCHANT_ID_HUF_SZEP = 'testIdSzep'
|
|
9
|
+
process.env.SIMPLEPAY_MERCHANT_KEY_HUF_SZEP = 'testKeySzep'
|
|
8
10
|
process.env.SIMPLEPAY_MERCHANT_ID_EUR = 'merchantEuroId'
|
|
9
11
|
process.env.SIMPLEPAY_MERCHANT_KEY_EUR = 'secretEuroKey'
|
|
10
12
|
}
|
|
@@ -19,6 +21,8 @@ describe('SimplePay Utils Tests', () => {
|
|
|
19
21
|
// Clear all environment variables before each test
|
|
20
22
|
delete process.env.SIMPLEPAY_MERCHANT_ID_HUF
|
|
21
23
|
delete process.env.SIMPLEPAY_MERCHANT_KEY_HUF
|
|
24
|
+
delete process.env.SIMPLEPAY_MERCHANT_ID_HUF_SZEP
|
|
25
|
+
delete process.env.SIMPLEPAY_MERCHANT_KEY_HUF_SZEP
|
|
22
26
|
delete process.env.SIMPLEPAY_MERCHANT_ID_EUR
|
|
23
27
|
delete process.env.SIMPLEPAY_MERCHANT_KEY_EUR
|
|
24
28
|
})
|
|
@@ -90,6 +94,13 @@ describe('SimplePay Utils Tests', () => {
|
|
|
90
94
|
expect(config.MERCHANT_ID).toBe('testId')
|
|
91
95
|
expect(config.MERCHANT_KEY).toBe('testKey')
|
|
92
96
|
})
|
|
97
|
+
|
|
98
|
+
it('should return correct config for HUF_SZEP', () => {
|
|
99
|
+
setEnv()
|
|
100
|
+
const config = getSimplePayConfig('HUF_SZEP')
|
|
101
|
+
expect(config.MERCHANT_ID).toBe('testIdSzep')
|
|
102
|
+
expect(config.MERCHANT_KEY).toBe('testKeySzep')
|
|
103
|
+
})
|
|
93
104
|
|
|
94
105
|
it('should throw error for unsupported currency', () => {
|
|
95
106
|
expect(() => getSimplePayConfig('GBP' as Currency)).toThrow('Unsupported currency: GBP')
|
|
@@ -109,6 +120,9 @@ describe('SimplePay Utils Tests', () => {
|
|
|
109
120
|
setEnv()
|
|
110
121
|
const currency = getCurrencyFromMerchantId('testId')
|
|
111
122
|
expect(currency).toBe('HUF')
|
|
123
|
+
|
|
124
|
+
const currencySzep = getCurrencyFromMerchantId('testIdSzep')
|
|
125
|
+
expect(currencySzep).toBe('HUF')
|
|
112
126
|
})
|
|
113
127
|
})
|
|
114
128
|
})
|
package/src/utils.ts
CHANGED
|
@@ -16,7 +16,7 @@ export const getSimplePayConfig = (currency: Currency) => {
|
|
|
16
16
|
|
|
17
17
|
const SIMPLEPAY_API_URL = 'https://secure.simplepay.hu/payment/v2'
|
|
18
18
|
const SIMPLEPAY_SANDBOX_URL = 'https://sandbox.simplepay.hu/payment/v2'
|
|
19
|
-
const SDK_VERSION = '
|
|
19
|
+
const SDK_VERSION = 'SimplePay_Rrd_0.10.0'
|
|
20
20
|
const MERCHANT_KEY = process.env[`SIMPLEPAY_MERCHANT_KEY_${currency}`]
|
|
21
21
|
const MERCHANT_ID = process.env[`SIMPLEPAY_MERCHANT_ID_${currency}`]
|
|
22
22
|
|
|
@@ -54,10 +54,13 @@ export const getCurrencyFromMerchantId = (merchantId: string) => {
|
|
|
54
54
|
.find(([key, value]) =>
|
|
55
55
|
key.startsWith('SIMPLEPAY_MERCHANT_ID_') && value === merchantId
|
|
56
56
|
)?.[0]?.replace('SIMPLEPAY_MERCHANT_ID_', '') as Currency
|
|
57
|
+
|
|
57
58
|
if (!currency) {
|
|
58
59
|
throw new Error(`Merchant id not found in the environment: ${merchantId}`)
|
|
59
60
|
}
|
|
60
|
-
|
|
61
|
+
|
|
62
|
+
// if currency ends with _SZEP, remove it
|
|
63
|
+
return currency.replace('_SZEP', '')
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
export const makeSimplePayRequest = async (apiUrl: string, requestBody: SimplePayRequestBody, merchantKey: string) => {
|