simplepay-js-sdk 0.7.0 → 0.8.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.
package/README-ENG.md ADDED
@@ -0,0 +1,203 @@
1
+ # SimplePay JS SDK
2
+
3
+ [Magyar README](README.md)
4
+
5
+ A lightweight utility for integrating Hungary's SimplePay payments in Node.js applications.
6
+
7
+ ![SimplePay Logo](simplepay_logo.jpg)
8
+
9
+ Please read the [SimplePay documentation](https://simplepay.hu/fejlesztoknek) for more information.
10
+
11
+ > 🫵 If this package is useful to you, please star it on GitHub.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ # npm
17
+ npm install simplepay-js-sdk
18
+
19
+ # yarn
20
+ yarn add simplepay-js-sdk
21
+
22
+ # pnpm
23
+ pnpm add simplepay-js-sdk
24
+ ```
25
+
26
+ ## Configuration
27
+
28
+ Set the following environment variables in your `.env` file:
29
+
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.
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.
35
+
36
+ ## Usage
37
+
38
+ You should create 3 endpoints, to start the payment, get the payment response and handle the IPN.
39
+
40
+ ### One Time Payment
41
+
42
+ #### Start Payment Endpoint
43
+
44
+ ```typescript
45
+ import { startPayment } from 'simplepay-js-sdk'
46
+
47
+ try {
48
+ const response = await startPayment({
49
+ orderRef: 'order-12',
50
+ total: 1212,
51
+ currency: 'HUF', // optional, HUF | EUR | USD, defaults to HUF
52
+ customerEmail: 'rrd@webmania.cc',
53
+ language: 'HU', // optional, AR | BG | CS | DE | EN | ES | FR | IT | HR | HU | PL | RO | RU | SK | TR | ZH, defaults to HU
54
+ method: 'CARD', // optional, CARD | WIRE, defaults to CARD
55
+ invoice: {
56
+ name: 'Radharadhya Dasa',
57
+ country: 'HU',
58
+ state: 'Budapest',
59
+ city: 'Budapest',
60
+ zip: '1234',
61
+ address: 'Sehol u. 0',
62
+ },
63
+ })
64
+ return response
65
+ } catch (error) {
66
+ console.error('Payment initiation failed:', error)
67
+ return error
68
+ }
69
+ ```
70
+
71
+ `response.paymentUrl` will contain the Simplepay payment URL, which you can redirect the customer to.
72
+
73
+ #### Get Payment Response Endpoint
74
+
75
+ When the customer returns from the Simplepay payment page, you need to get the payment response at your `SIMPLEPAY_REDIRECT_URL`. The url will contain 2 parameters: `r` and `s`.
76
+
77
+ ```typescript
78
+ import { getPaymentResponse } from 'simplepay-js-sdk'
79
+
80
+ // get "r" and "s" from the url the way you do it on your app and framework
81
+
82
+ const response = getPaymentResponse(r, s)
83
+ ```
84
+
85
+ `response` will have the following properties:
86
+
87
+ - `responseCode`: `0` on success, or an error code
88
+ - `transactionId`: the transaction id
89
+ - `event`: the event type: `success` | `fail` | `timeout` | `cancel`
90
+ - `merchantId`: the merchant id
91
+ - `orderRef`: the order id
92
+
93
+ #### IPN Endpoint
94
+
95
+ Simplepay will send a `POST` request to the IPN url and you should send a response back.
96
+ At this endpoint you should
97
+
98
+ - check if the signature is valid - use `checkSignature(ipnBody, signatureHeader, SIMPLEPAY_MERCHANT_KEY_HUF)`
99
+ - add a `receiveDate` property to the received JSON
100
+ - calculate the new signature - use `generateSignature(responseText, SIMPLEPAY_MERCHANT_KEY_HUF)`
101
+ - send the `response` with the new `signature`
102
+
103
+
104
+ ### Recurring Payment
105
+
106
+ #### Start Recurring Payment Endpoint
107
+
108
+ Here you have to use the `startRecurringPayment()` function what works the same way as the `startPayment()` function. The only difference is that you have to pass 2 additional properties: `customer` and `recurring`.
109
+
110
+ ```typescript
111
+ try {
112
+ const response = await startRecurringPayment({
113
+ // ... other preoperties
114
+ customer: 'Radharadhya Dasa',
115
+ recurring: {
116
+ times: 3, // how many times the payment will be made, number of tokens
117
+ until: '2025-12-31T18:00:00+02:00', // the end date of the recurring payment - use the toISO8601DateString() helper function
118
+ maxAmount: 100000 // the maximum amount of the recurring payment
119
+ }
120
+ })
121
+ }
122
+ ```
123
+
124
+ The response will have an additional `tokens` property, what will contain the tokens of the registered cards.
125
+ You are responsible to save the tokens to your database, so you can use them later to make a payment.
126
+
127
+
128
+ #### Get Recurring Payment Response Endpoint
129
+
130
+ Use the same enpoint as the one time payment.
131
+
132
+ #### IPN Endpoint on card registration
133
+
134
+ It works the same as the `IPN` endpoint of the one time payment.
135
+ The response will have the same properties, and 2 additional properties:
136
+
137
+ - `cardMask`: xxxx-xxxx-xxxx-1234 - the masked card number what is registered
138
+ - `expiry`: 2025-01-31T00:00:00+02:00 - the expiry date of the registered card
139
+
140
+ #### Token Payment Endpoint
141
+
142
+ After a card is registered you can use the tokens to make a payment without any user intercation for example by a daily `cron`
143
+
144
+ ```typescript
145
+ import { startTokenPayment } from 'simplepay-js-sdk'
146
+
147
+ // TODO: get payment data from your database, where you saved the tokens
148
+
149
+ const payment = {
150
+ token: '1234567890123456',
151
+ total: 1212,
152
+ currency: 'HUF' as Currency,
153
+ customer: 'Radharadhya Dasa',
154
+ customerEmail: 'rrd@webmania.cc',
155
+ invoice: {
156
+ name: 'Radharadhya Dasa',
157
+ country: 'HU',
158
+ state: 'Budapest',
159
+ city: 'Budapest',
160
+ zip: '1234',
161
+ address: 'Sehol u. 0',
162
+ },
163
+ }
164
+
165
+ try {
166
+ const response = await startTokenPayment({
167
+ orderRef: Date.now().toString(),
168
+ language: 'HU',
169
+ method: 'CARD', // must be CARD
170
+ ...payment,
171
+ })
172
+ return response
173
+ } catch (error) {
174
+ console.error('Token payment initiation failed:', error)
175
+ return error
176
+ }
177
+ ```
178
+
179
+ #### Card Cancelation
180
+
181
+ Paying customers should be able to delete their registered card on the website.
182
+ To do this, use the `cancelCard` function. Use SimplePay transaction id of the card registration transaction as `cardId`.
183
+
184
+ ```typescript
185
+ import { cancelCard } from 'simplepay-js-sdk'
186
+
187
+ try {
188
+ const response = await cancelCard(cardId)
189
+
190
+ if (response.status == 'DISABLED') {
191
+ // The card has been successfully deleted
192
+ // TODO: delete the unused tokens and the card from the database
193
+ }
194
+ return response
195
+ } catch (error) {
196
+ console.error('Card deletion failed:', error)
197
+ return error
198
+ }
199
+ ```
200
+
201
+ ## License
202
+
203
+ MIT
package/README.md CHANGED
@@ -1,12 +1,16 @@
1
1
  # SimplePay JS SDK
2
2
 
3
- A lightweight utility for integrating Hungary's SimplePay payments in Node.js applications.
3
+ [English README](README-ENG.md)
4
+
5
+ Egy pehelysúlyú segédprogram a magyarországi SimplePay fizetések integrálásához Node.js alkalmazásokban.
4
6
 
5
7
  ![SimplePay Logo](simplepay_logo.jpg)
6
8
 
7
- Please read the [SimplePay documentation](https://simplepay.hu/fejlesztoknek) for more information.
9
+ További információkért kérlek, olvasd el a [SimplePay dokumentációt](https://simplepay.hu/fejlesztoknek).
10
+
11
+ > 🫵 Ha a csomag hasznos a számodra, akkor ne feletjs el rányomni a star-ra GitHub-on.
8
12
 
9
- ## Installation
13
+ ## Telepítés
10
14
 
11
15
  ```bash
12
16
  # npm
@@ -19,23 +23,23 @@ yarn add simplepay-js-sdk
19
23
  pnpm add simplepay-js-sdk
20
24
  ```
21
25
 
22
- ## Configuration
26
+ ## Konfiguráció
23
27
 
24
- Set the following environment variables in your `.env` file:
28
+ Állítsd be a következő környezeti változókat a `.env` fájlban:
25
29
 
26
- - `SIMPLEPAY_LOGGER` If it set to `true`, it will log varibles - useful only for debugging.
27
- - `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.
28
- - `SIMPLEPAY_MERCHANT_ID_HUF` Your Simplepay merchant id. Set `SIMPLEPAY_MERCHANT_ID_EUR` and `SIMPLEPAY_MERCHANT_ID_USD` for accepting EUR and USD payments.
29
- - `SIMPLEPAY_PRODUCTION` If it set to `true`, it will use production environment, otherwise it will use sandbox environment.
30
- - `SIMPLEPAY_REDIRECT_URL` The URL of your site, where the customer will be redirected after the payment.
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.
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.
31
35
 
32
- ## Usage
36
+ ## Használat
33
37
 
34
- You should create 3 endpoints, to start the payment, get the payment response and handle the IPN.
38
+ Három végpontot kell létrehoznia: egyet a fizetés indításához, egyet a fizetési válasz fogadásához és egyet az IPN kezeléséhez.
35
39
 
36
- ### One Time Payment
40
+ ### Egyszeri fizetés
37
41
 
38
- #### Start Payment Endpoint
42
+ #### Fizetés indítása végpont
39
43
 
40
44
  ```typescript
41
45
  import { startPayment } from 'simplepay-js-sdk'
@@ -44,10 +48,10 @@ try {
44
48
  const response = await startPayment({
45
49
  orderRef: 'order-12',
46
50
  total: 1212,
47
- currency: 'HUF', // optional, HUF | EUR | USD, defaults to HUF
51
+ currency: 'HUF', // opcionális, HUF | EUR | USD, alapértelmezett: HUF
48
52
  customerEmail: 'rrd@webmania.cc',
49
- language: 'HU', // optional, AR | BG | CS | DE | EN | ES | FR | IT | HR | HU | PL | RO | RU | SK | TR | ZH, defaults to HU
50
- method: 'CARD', // optional, CARD | WIRE, defaults to CARD
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
+ method: 'CARD', // opcionális, CARD | WIRE, alapértelmezett: CARD
51
55
  invoice: {
52
56
  name: 'Radharadhya Dasa',
53
57
  country: 'HU',
@@ -59,88 +63,86 @@ try {
59
63
  })
60
64
  return response
61
65
  } catch (error) {
62
- console.error('Payment initiation failed:', error)
66
+ console.error('Fizetés indítása sikertelen:', error)
63
67
  return error
64
68
  }
65
69
  ```
66
70
 
67
- `response.paymentUrl` will contain the Simplepay payment URL, which you can redirect the customer to.
71
+ A `response.paymentUrl` tartalmazza a SimplePay fizetési URL-t, ahova a vásárlót átirányíthatja.
68
72
 
69
- #### Get Payment Response Endpoint
73
+ #### Fizetési válasz fogadása végpont
70
74
 
71
- When the customer returns from the Simplepay payment page, you need to get the payment response at your `SIMPLEPAY_REDIRECT_URL`. The url will contain 2 parameters: `r` and `s`.
75
+ Amikor a vásárló visszatér a SimplePay fizetési oldalról, a fizetési választ a `SIMPLEPAY_REDIRECT_URL` címen kell fogadni. Az URL két paramétert tartalmaz: `r` és `s`.
72
76
 
73
77
  ```typescript
74
78
  import { getPaymentResponse } from 'simplepay-js-sdk'
75
79
 
76
- // get "r" and "s" from the url the way you do it on your app and framework
80
+ // az "r" és "s" paraméterek kinyerése az URL-ből az alkalmazásod és keretrendszerének megfelelően
77
81
 
78
82
  const response = getPaymentResponse(r, s)
79
83
  ```
80
84
 
81
- `response` will have the following properties:
85
+ A `response` a következő tulajdonságokkal rendelkezik:
82
86
 
83
- - `responseCode`: `0` on success, or an error code
84
- - `transactionId`: the transaction id
85
- - `event`: the event type: `success` | `fail` | `timeout` | `cancel`
86
- - `merchantId`: the merchant id
87
- - `orderRef`: the order id
87
+ - `responseCode`: `0` siker esetén, vagy hibakód
88
+ - `transactionId`: a tranzakció azonosítója
89
+ - `event`: az esemény típusa: `success` | `fail` | `timeout` | `cancel`
90
+ - `merchantId`: a kereskedő azonosítója
91
+ - `orderRef`: a rendelés azonosítója
88
92
 
89
- #### IPN Endpoint
93
+ #### IPN végpont
90
94
 
91
- Simplepay will send a `POST` request to the IPN url and you should send a response back.
92
- At this endpoint you should
95
+ A SimplePay `POST` kérést küld az IPN URL-re, és válaszolnunk kell rá.
96
+ Ennél a végpontnál a következőket kell tenned:
93
97
 
94
- - check if the signature is valid - use `checkSignature(ipnBody, signatureHeader, SIMPLEPAY_MERCHANT_KEY_HUF)`
95
- - add a `receiveDate` property to the received JSON
96
- - calculate the new signature - use `generateSignature(responseText, SIMPLEPAY_MERCHANT_KEY_HUF)`
97
- - send the `response` with the new `signature`
98
+ - ellenőrizd az aláírás érvényességét - használd a `checkSignature(ipnBody, signatureHeader, SIMPLEPAY_MERCHANT_KEY_HUF)` függvényt
99
+ - adj hozzá egy `receiveDate` tulajdonságot a kapott JSON-hoz
100
+ - számítsa ki az új aláírást - használd a `generateSignature(responseText, SIMPLEPAY_MERCHANT_KEY_HUF)` függvényt
101
+ - küldd el a `response`-t az új `signature`-rel
98
102
 
103
+ ### Ismétlődő fizetés
99
104
 
100
- ### Recurring Payment
105
+ #### Ismétlődő fizetés indítása végpont
101
106
 
102
- #### Start Recurring Payment Endpoint
103
-
104
- Here you have to use the `startRecurringPayment()` function what works the same way as the `startPayment()` function. The only difference is that you have to pass 2 additional properties: `customer` and `recurring`.
107
+ Itt a `startRecurringPayment()` függvényt kell használnod, ami ugyanúgy működik, mint a `startPayment()`. Az egyetlen különbség, hogy két további tulajdonságot kell megadni: `customer` és `recurring`.
105
108
 
106
109
  ```typescript
107
110
  try {
108
111
  const response = await startRecurringPayment({
109
- // ... other preoperties
112
+ // ... egyéb tulajdonságok
110
113
  customer: 'Radharadhya Dasa',
111
114
  recurring: {
112
- times: 3, // how many times the payment will be made, number of tokens
113
- until: '2025-12-31T18:00:00+02:00', // the end date of the recurring payment - use the toISO8601DateString() helper function
114
- maxAmount: 100000 // the maximum amount of the recurring payment
115
+ times: 3, // hányszor történik meg a fizetés, tokenek száma
116
+ until: '2025-12-31T18:00:00+02:00', // az ismétlődő fizetés végdátuma - használd a toISO8601DateString() segédfüggvényt
117
+ maxAmount: 100000 // az ismétlődő fizetés maximális összege
115
118
  }
116
119
  })
117
120
  }
118
121
  ```
119
122
 
120
- The response will have an additional `tokens` property, what will contain the tokens of the registered cards.
121
- You are responsible to save the tokens to your database, so you can use them later to make a payment.
122
-
123
+ A válasz egy további `tokens` tulajdonsággal rendelkezik, ami tartalmazza a regisztrált kártyák tokenjeit.
124
+ A te dolgod a tokenek mentése az adatbázisba, hogy később használhasd őket fizetéshez.
123
125
 
124
- #### Get Recurring Payment Response Endpoint
126
+ #### Ismétlődő fizetési válasz fogadása végpont
125
127
 
126
- Use the same enpoint as the one time payment.
128
+ Használd ugyanazt a végpontot, mint az egyszeri fizetésnél.
127
129
 
128
- #### IPN Endpoint on card registration
130
+ #### IPN végpont kártyaregisztrációnál
129
131
 
130
- It works the same as the `IPN` endpoint of the one time payment.
131
- The response will have the same properties, and 2 additional properties:
132
+ Ugyanúgy működik, mint az egyszeri fizetés `IPN` végpontja.
133
+ A válasz ugyanazokkal a tulajdonságokkal rendelkezik, és 2 további tulajdonsággal:
132
134
 
133
- - `cardMask`: xxxx-xxxx-xxxx-1234 - the masked card number what is registered
134
- - `expiry`: 2025-01-31T00:00:00+02:00 - the expiry date of the registered card
135
+ - `cardMask`: xxxx-xxxx-xxxx-1234 - a regisztrált kártya maszkolt száma
136
+ - `expiry`: 2025-01-31T00:00:00+02:00 - a regisztrált kártya lejárati dátuma
135
137
 
136
- #### Token Payment Endpoint
138
+ #### Tokenes fizetés
137
139
 
138
- After a card is registered you can use the tokens to make a payment without any user intercation for example by a daily `cron`
140
+ Miután egy kártya regisztrálva van, használhatod a tokeneket fizetéshez felhasználói interakció nélkül, például napi `cron` feladattal
139
141
 
140
142
  ```typescript
141
143
  import { startTokenPayment } from 'simplepay-js-sdk'
142
144
 
143
- // TODO: get payment data from your database, where you saved the tokens
145
+ // TODO: fizetési adatok lekérése az adatbázisból, ahol a tokeneket tárolod
144
146
 
145
147
  const payment = {
146
148
  token: '1234567890123456',
@@ -162,16 +164,38 @@ try {
162
164
  const response = await startTokenPayment({
163
165
  orderRef: Date.now().toString(),
164
166
  language: 'HU',
165
- method: 'CARD', // must be CARD
167
+ method: 'CARD', // kötelezően CARD
166
168
  ...payment,
167
169
  })
168
170
  return response
169
171
  } catch (error) {
170
- console.error('Token payment initiation failed:', error)
172
+ console.error('Token fizetés indítása sikertelen:', error)
173
+ return error
174
+ }
175
+ ```
176
+
177
+ #### Kártya törlése
178
+
179
+ A fizető ügyfelek számára lehetővé kell tenni, hogy a honlapodon belépve törölni tudja a regisztrált kártyáját.
180
+ Ehhez használd a `cancelCard` függvényt. `cardId`-ként a kártya regisztrációs tranzakció SimplePay azonosítóját kell megadnod.
181
+
182
+ ```typescript
183
+ import { cancelCard } from 'simplepay-js-sdk'
184
+
185
+ try {
186
+ const response = await cancelCard(cardId)
187
+
188
+ if (response.status == 'DISABLED') {
189
+ // A kártya sikeresen törölve
190
+ // TODO: a fel nem használt tokenek és a kártya törlése az adatbázisból
191
+ }
192
+ return response
193
+ } catch (error) {
194
+ console.error('Kártya törlése sikertelen:', error)
171
195
  return error
172
196
  }
173
197
  ```
174
198
 
175
- ## License
199
+ ## Licenc
176
200
 
177
- MIT
201
+ MIT
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export declare const cardCancel: (cardId: string) => Promise<SimplePayCardCancelResponse>;
2
+
1
3
  export declare const checkSignature: (responseText: string, signature: string, merchantKey: string) => boolean;
2
4
 
3
5
  declare const CURRENCIES: readonly ["HUF", "EUR", "USD"];
@@ -46,6 +48,14 @@ declare interface RecurringPaymentData extends PaymentData {
46
48
  recurring: Recurring;
47
49
  }
48
50
 
51
+ declare interface SimplePayCardCancelResponse {
52
+ salt: string;
53
+ merchant: string;
54
+ cardId: string;
55
+ status: 'DISABLED';
56
+ expiry: string;
57
+ }
58
+
49
59
  declare type SimplePayEvents = 'SUCCESS' | 'FAIL' | 'TIMEOUT' | 'CANCEL';
50
60
 
51
61
  declare interface SimplePayRecurringResponse extends SimplePayResponse {
package/dist/index.js CHANGED
@@ -1,31 +1,32 @@
1
1
  import S from "crypto";
2
- const d = ["HUF", "EUR", "USD"], i = (...e) => {
2
+ const g = ["HUF", "EUR", "USD"], i = (...e) => {
3
3
  process.env.SIMPLEPAY_LOGGER === "true" && console.log("👉 ", ...e);
4
- }, m = (e) => {
5
- if (!d.includes(e))
4
+ }, E = (e) => {
5
+ if (!g.includes(e))
6
6
  throw new Error(`Unsupported currency: ${e}`);
7
- const r = "https://secure.simplepay.hu/payment/v2", t = "https://sandbox.simplepay.hu/payment/v2/start", n = "SimplePayV2.1_Rrd_0.6.1", s = process.env[`SIMPLEPAY_MERCHANT_KEY_${e}`], c = process.env[`SIMPLEPAY_MERCHANT_ID_${e}`], o = process.env.SIMPLEPAY_PRODUCTION === "true" ? r : t, u = process.env.SIMPLEPAY_PRODUCTION === "true" ? r : "https://sandbox.simplepay.hu/payment/v2/dorecurring";
7
+ const n = "https://secure.simplepay.hu/payment/v2", r = "https://sandbox.simplepay.hu/payment/v2", t = "SimplePayV2.1_Rrd_0.8.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 + "/cancelcard";
8
8
  return {
9
9
  MERCHANT_KEY: s,
10
10
  MERCHANT_ID: c,
11
- API_URL: o,
12
- API_URL_RECURRING: u,
13
- SDK_VERSION: n
11
+ API_URL_PAYMENT: u,
12
+ API_URL_RECURRING: R,
13
+ API_URL_CARD_CANCEL: a,
14
+ SDK_VERSION: t
14
15
  };
15
- }, p = (e) => JSON.stringify(e).replace(/\//g, "\\/"), l = (e, r) => {
16
- const t = S.createHmac("sha384", r.trim());
17
- return t.update(e, "utf8"), t.digest("base64");
18
- }, g = (e, r, t) => r === l(e, t), R = (e) => e.toISOString().replace(/\.\d{3}Z$/, "+00:00"), _ = (e) => {
19
- var t, n;
20
- const r = (n = (t = Object.entries(process.env).find(
16
+ }, d = (e) => JSON.stringify(e).replace(/\//g, "\\/"), l = (e, n) => {
17
+ const r = S.createHmac("sha384", n.trim());
18
+ return r.update(e, "utf8"), r.digest("base64");
19
+ }, _ = (e, n, r) => n === l(e, r), m = (e) => e.toISOString().replace(/\.\d{3}Z$/, "+00:00"), A = (e) => {
20
+ var r, t;
21
+ const n = (t = (r = Object.entries(process.env).find(
21
22
  ([s, c]) => s.startsWith("SIMPLEPAY_MERCHANT_ID_") && c === e
22
- )) == null ? void 0 : t[0]) == null ? void 0 : n.replace("SIMPLEPAY_MERCHANT_ID_", "");
23
- if (!r)
23
+ )) == null ? void 0 : r[0]) == null ? void 0 : t.replace("SIMPLEPAY_MERCHANT_ID_", "");
24
+ if (!n)
24
25
  throw new Error(`Merchant id not found in the environment: ${e}`);
25
- return r;
26
- }, I = async (e, r, t) => E(e, r, t, "oneTime"), f = async (e, r, t) => E(e, r, t, "recurring"), h = async (e, r, t) => E(e, r, t, "token"), E = async (e, r, t, n) => {
27
- const s = p(r), c = l(s, t);
28
- i({ function: `SimplePay/makeRequest/${n}`, bodyString: s, signature: c });
26
+ return n;
27
+ }, I = async (e, n, r) => P(e, n, r, "oneTime"), f = async (e, n, r) => P(e, n, r, "recurring"), p = async (e, n, r) => P(e, n, r, "token"), h = async (e, n, r) => P(e, n, r, "cardCancel"), P = async (e, n, r, t) => {
28
+ const s = d(n), c = l(s, r);
29
+ i({ function: `SimplePay/makeRequest/${t}`, bodyString: s, signature: c });
29
30
  try {
30
31
  const o = await fetch(e, {
31
32
  method: "POST",
@@ -35,26 +36,26 @@ const d = ["HUF", "EUR", "USD"], i = (...e) => {
35
36
  },
36
37
  body: s
37
38
  });
38
- if (i({ function: `SimplePay/makeRequest/${n}`, response: o }), !o.ok)
39
+ if (i({ function: `SimplePay/makeRequest/${t}`, response: o }), !o.ok)
39
40
  throw new Error(`SimplePay API error: ${o.status}`);
40
41
  const u = o.headers.get("Signature");
41
- if (i({ function: `SimplePay/makeRequest/${n}`, responseSignature: u }), !u)
42
+ if (i({ function: `SimplePay/makeRequest/${t}`, responseSignature: u }), !u)
42
43
  throw new Error("Missing response signature");
43
- const P = await o.text(), a = JSON.parse(P);
44
- if (i({ function: `SimplePay/makeRequest/${n}`, responseText: P, responseJSON: a }), a.errorCodes)
44
+ const R = await o.text(), a = JSON.parse(R);
45
+ if (i({ function: `SimplePay/makeRequest/${t}`, responseText: R, responseJSON: a }), a.errorCodes)
45
46
  throw new Error(`SimplePay API error: ${a.errorCodes}`);
46
- if (!g(P, u, t))
47
+ if (!_(R, u, r))
47
48
  throw new Error("Invalid response signature");
48
49
  return a;
49
50
  } catch (o) {
50
51
  throw o;
51
52
  }
52
- }, C = (e, r) => {
53
- i({ function: "SimplePay/getPaymentResponse", r: e, signature: r }), r = decodeURIComponent(r);
54
- const t = Buffer.from(e, "base64").toString("utf-8"), n = JSON.parse(t), s = _(n.m), { MERCHANT_KEY: c } = m(s);
55
- if (!g(t, r, c || ""))
56
- throw i({ function: "SimplePay/getPaymentResponse", rDecoded: t, signature: r }), new Error("Invalid response signature");
57
- const o = JSON.parse(t);
53
+ }, U = (e, n) => {
54
+ i({ function: "SimplePay/getPaymentResponse", r: e, signature: n }), n = decodeURIComponent(n);
55
+ const r = Buffer.from(e, "base64").toString("utf-8"), t = JSON.parse(r), s = A(t.m), { MERCHANT_KEY: c } = E(s);
56
+ if (!_(r, n, c || ""))
57
+ throw i({ function: "SimplePay/getPaymentResponse", rDecoded: r, signature: n }), new Error("Invalid response signature");
58
+ const o = JSON.parse(r);
58
59
  return {
59
60
  responseCode: o.r,
60
61
  transactionId: o.t,
@@ -65,61 +66,61 @@ const d = ["HUF", "EUR", "USD"], i = (...e) => {
65
66
  };
66
67
  }, w = async (e) => {
67
68
  i({ function: "SimplePay/startPayment", paymentData: e });
68
- const r = e.currency || "HUF", { MERCHANT_KEY: t, MERCHANT_ID: n, API_URL: s, SDK_VERSION: c } = m(r);
69
- if (i({ function: "SimplePay/startPayment", MERCHANT_KEY: t, MERCHANT_ID: n, API_URL: s }), !t || !n)
70
- throw new Error(`Missing SimplePay configuration for ${r}`);
69
+ const n = e.currency || "HUF", { MERCHANT_KEY: r, MERCHANT_ID: t, API_URL_PAYMENT: s, SDK_VERSION: c } = E(n);
70
+ if (i({ function: "SimplePay/startPayment", MERCHANT_KEY: r, MERCHANT_ID: t, API_URL_PAYMENT: s }), !r || !t)
71
+ throw new Error(`Missing SimplePay configuration for ${n}`);
71
72
  const o = {
72
73
  salt: S.randomBytes(16).toString("hex"),
73
- merchant: n,
74
+ merchant: t,
74
75
  orderRef: e.orderRef,
75
- currency: r,
76
+ currency: n,
76
77
  customerEmail: e.customerEmail,
77
78
  language: e.language || "HU",
78
79
  sdkVersion: c,
79
80
  methods: [e.method || "CARD"],
80
81
  total: String(e.total),
81
- timeout: R(new Date(Date.now() + 30 * 60 * 1e3)),
82
+ timeout: m(new Date(Date.now() + 30 * 60 * 1e3)),
82
83
  url: process.env.SIMPLEPAY_REDIRECT_URL || "http://url.to.redirect",
83
84
  invoice: e.invoice
84
85
  };
85
- return I(s, o, t);
86
- }, A = 6, y = new Date(Date.now() + A * 30 * 24 * 60 * 60 * 1e3), M = 12e3, T = 3, U = async (e) => {
86
+ return I(s, o, r);
87
+ }, y = 6, C = new Date(Date.now() + y * 30 * 24 * 60 * 60 * 1e3), M = 12e3, N = 3, L = async (e) => {
87
88
  i({ function: "SimplePay/startRecurringPayment", paymentData: e });
88
- const r = e.currency || "HUF", { MERCHANT_KEY: t, MERCHANT_ID: n, API_URL: s, SDK_VERSION: c } = m(r);
89
- if (i({ function: "SimplePay/startRecurringPayment", MERCHANT_KEY: t, MERCHANT_ID: n, API_URL: s }), !t || !n)
90
- throw new Error(`Missing SimplePay configuration for ${r}`);
89
+ const n = e.currency || "HUF", { MERCHANT_KEY: r, MERCHANT_ID: t, API_URL_PAYMENT: s, SDK_VERSION: c } = E(n);
90
+ if (i({ function: "SimplePay/startRecurringPayment", MERCHANT_KEY: r, MERCHANT_ID: t, API_URL_PAYMENT: s }), !r || !t)
91
+ throw new Error(`Missing SimplePay configuration for ${n}`);
91
92
  const o = {
92
93
  salt: S.randomBytes(16).toString("hex"),
93
- merchant: n,
94
+ merchant: t,
94
95
  orderRef: e.orderRef,
95
- currency: r,
96
+ currency: n,
96
97
  customer: e.customer,
97
98
  customerEmail: e.customerEmail,
98
99
  language: e.language || "HU",
99
100
  sdkVersion: c,
100
101
  methods: ["CARD"],
101
102
  recurring: {
102
- times: e.recurring.times || T,
103
- until: e.recurring.until || R(y),
103
+ times: e.recurring.times || N,
104
+ until: e.recurring.until || m(C),
104
105
  maxAmount: e.recurring.maxAmount || M
105
106
  },
106
107
  threeDSReqAuthMethod: "02",
107
108
  total: String(e.total),
108
- timeout: R(new Date(Date.now() + 30 * 60 * 1e3)),
109
+ timeout: m(new Date(Date.now() + 30 * 60 * 1e3)),
109
110
  url: process.env.SIMPLEPAY_REDIRECT_URL || "http://url.to.redirect",
110
111
  invoice: e.invoice
111
112
  };
112
- return f(s, o, t);
113
- }, L = async (e) => {
113
+ return f(s, o, r);
114
+ }, H = async (e) => {
114
115
  i({ function: "SimplePay/startTokenPayment", paymentData: e });
115
- const r = e.currency || "HUF", { MERCHANT_KEY: t, MERCHANT_ID: n, API_URL_RECURRING: s, SDK_VERSION: c } = m(r);
116
- if (i({ function: "SimplePay/startTokenPayment", MERCHANT_KEY: t, MERCHANT_ID: n, API_URL_RECURRING: s }), !t || !n)
117
- throw new Error(`Missing SimplePay configuration for ${r}`);
116
+ const n = e.currency || "HUF", { MERCHANT_KEY: r, MERCHANT_ID: t, API_URL_RECURRING: s, SDK_VERSION: c } = E(n);
117
+ if (i({ function: "SimplePay/startTokenPayment", MERCHANT_KEY: r, MERCHANT_ID: t, API_URL_RECURRING: s }), !r || !t)
118
+ throw new Error(`Missing SimplePay configuration for ${n}`);
118
119
  const o = {
119
120
  salt: S.randomBytes(16).toString("hex"),
120
- merchant: n,
121
+ merchant: t,
121
122
  orderRef: e.orderRef,
122
- currency: r,
123
+ currency: n,
123
124
  customer: e.customer,
124
125
  customerEmail: e.customerEmail,
125
126
  language: e.language || "HU",
@@ -129,19 +130,32 @@ const d = ["HUF", "EUR", "USD"], i = (...e) => {
129
130
  type: "MIT",
130
131
  threeDSReqAuthMethod: "02",
131
132
  total: String(e.total),
132
- timeout: R(new Date(Date.now() + 30 * 60 * 1e3)),
133
+ timeout: m(new Date(Date.now() + 30 * 60 * 1e3)),
133
134
  url: process.env.SIMPLEPAY_REDIRECT_URL || "http://recurring.url.to.redirect",
134
135
  invoice: e.invoice
135
136
  };
136
- return h(s, o, t);
137
+ return p(s, o, r);
138
+ }, k = async (e) => {
139
+ i({ function: "SimplePay/cardCancel", cardId: e });
140
+ const { API_URL_CARD_CANCEL: n, MERCHANT_KEY: r, MERCHANT_ID: t, SDK_VERSION: s } = E("HUF");
141
+ if (!r || !t)
142
+ throw new Error("Missing SimplePay configuration for HUF");
143
+ const c = {
144
+ salt: S.randomBytes(16).toString("hex"),
145
+ cardId: e,
146
+ merchant: t,
147
+ sdkVersion: s
148
+ };
149
+ return h(n, c, r);
137
150
  };
138
151
  export {
139
- g as checkSignature,
152
+ k as cardCancel,
153
+ _ as checkSignature,
140
154
  l as generateSignature,
141
- C as getPaymentResponse,
155
+ U as getPaymentResponse,
142
156
  w as startPayment,
143
- U as startRecurringPayment,
144
- L as startTokenPayment,
145
- R as toISO8601DateString
157
+ L as startRecurringPayment,
158
+ H as startTokenPayment,
159
+ m as toISO8601DateString
146
160
  };
147
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 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 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, 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/start'\n const SDK_VERSION = 'SimplePayV2.1_Rrd_0.6.1'\n const MERCHANT_KEY = process.env[`SIMPLEPAY_MERCHANT_KEY_${currency}`]\n const MERCHANT_ID = process.env[`SIMPLEPAY_MERCHANT_ID_${currency}`]\n const API_URL = process.env.SIMPLEPAY_PRODUCTION === 'true' ? SIMPLEPAY_API_URL : SIMPLEPAY_SANDBOX_URL\n const API_URL_RECURRING = process.env.SIMPLEPAY_PRODUCTION === 'true' ? SIMPLEPAY_API_URL : 'https://sandbox.simplepay.hu/payment/v2/dorecurring'\n\n return {\n MERCHANT_KEY,\n MERCHANT_ID,\n API_URL,\n API_URL_RECURRING,\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\nconst makeRequest = async (apiUrl: string, requestBody: SimplePayRequestBody | SimplePayRecurringRequestBody | SimplePayTokenRequestBody, merchantKey: string, type: 'oneTime' | 'recurring' | 'token') => {\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, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ function: 'SimplePay/startPayment', MERCHANT_KEY, MERCHANT_ID, API_URL })\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, requestBody, MERCHANT_KEY)\n}\n\nexport { startPayment }\n","import crypto from 'crypto'\nimport { SimplePayRecurringRequestBody, RecurringPaymentData, TokenPaymentData, SimplePayTokenRequestBody} from './types'\nimport { getSimplePayConfig, simplepayLogger, toISO8601DateString, makeSimplePayTokenRequest, makeSimplePayRecurringRequest} 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, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ function: 'SimplePay/startRecurringPayment', MERCHANT_KEY, MERCHANT_ID, API_URL })\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, 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\nexport { startRecurringPayment, startTokenPayment }"],"names":["CURRENCIES","simplepayLogger","args","getSimplePayConfig","currency","SIMPLEPAY_API_URL","SIMPLEPAY_SANDBOX_URL","SDK_VERSION","MERCHANT_KEY","MERCHANT_ID","API_URL","API_URL_RECURRING","prepareRequestBody","body","generateSignature","merchantKey","hmac","crypto","checkSignature","responseText","signature","toISO8601DateString","date","getCurrencyFromMerchantId","merchantId","_b","_a","key","value","makeSimplePayRequest","apiUrl","requestBody","makeRequest","makeSimplePayRecurringRequest","makeSimplePayTokenRequest","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"],"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', '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 SimplePayCardCancelRequestBody {\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 SimplePayCardCancelResponse {\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, SimplePayCardCancelRequestBody, SimplePayCardCancelResponse, 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.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 + '/cancelcard'\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 makeSimplePayCardCancelRequest = async (apiUrl: string, requestBody: SimplePayCardCancelRequestBody, merchantKey: string) => {\n return makeRequest(apiUrl, requestBody, merchantKey, 'cardCancel') as Promise<SimplePayCardCancelResponse>\n}\n\nconst makeRequest = async (apiUrl: string, requestBody: SimplePayRequestBody | SimplePayRecurringRequestBody | SimplePayTokenRequestBody | SimplePayCardCancelRequestBody, merchantKey: string, type: 'oneTime' | 'recurring' | 'token' | 'cardCancel') => {\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, SimplePayCardCancelRequestBody} from './types'\nimport { getSimplePayConfig, simplepayLogger, toISO8601DateString, makeSimplePayTokenRequest, makeSimplePayRecurringRequest, makeSimplePayRequest, makeSimplePayCardCancelRequest} 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 cardCancel = async (cardId: string) => {\n simplepayLogger({ function: 'SimplePay/cardCancel', 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: SimplePayCardCancelRequestBody = {\n salt: crypto.randomBytes(16).toString('hex'),\n cardId,\n merchant: MERCHANT_ID,\n sdkVersion: SDK_VERSION,\n }\n return makeSimplePayCardCancelRequest(API_URL_CARD_CANCEL, requestBody, MERCHANT_KEY)\n}\n\nexport { startRecurringPayment, startTokenPayment , cardCancel}\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","makeSimplePayCardCancelRequest","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","cardCancel","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.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "A Node.js utility for SimplePay payment integration",
5
5
  "repository": {
6
6
  "type": "git",
@@ -38,7 +38,7 @@
38
38
  "license": "MIT",
39
39
  "devDependencies": {
40
40
  "@types/node": "^22.0.0",
41
- "typescript": "~5.4.2",
41
+ "typescript": "~5.7.0",
42
42
  "vite": "^6.0.3",
43
43
  "vite-plugin-dts": "^4.3.0",
44
44
  "vitest": "^2.1.6"
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { startPayment } from './oneTime'
2
- import { startRecurringPayment, startTokenPayment} from './recurring'
2
+ import { startRecurringPayment, startTokenPayment, cardCancel} from './recurring'
3
3
  import type { Currency, Language, PaymentMethod } from './types'
4
4
  import { checkSignature, generateSignature, getPaymentResponse, toISO8601DateString } from './utils'
5
5
 
@@ -7,5 +7,5 @@ export {
7
7
  Currency, Language, PaymentMethod,
8
8
  checkSignature, generateSignature, toISO8601DateString, getPaymentResponse,
9
9
  startPayment,
10
- startRecurringPayment, startTokenPayment,
10
+ startRecurringPayment, startTokenPayment, cardCancel
11
11
  }
package/src/oneTime.ts CHANGED
@@ -5,8 +5,8 @@ import { simplepayLogger, getSimplePayConfig, toISO8601DateString, makeSimplePay
5
5
  const startPayment = async (paymentData: PaymentData) => {
6
6
  simplepayLogger({ function: 'SimplePay/startPayment', paymentData })
7
7
  const currency = paymentData.currency || 'HUF'
8
- const { MERCHANT_KEY, MERCHANT_ID, API_URL, SDK_VERSION } = getSimplePayConfig(currency)
9
- simplepayLogger({ function: 'SimplePay/startPayment', MERCHANT_KEY, MERCHANT_ID, API_URL })
8
+ const { MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT, SDK_VERSION } = getSimplePayConfig(currency)
9
+ simplepayLogger({ function: 'SimplePay/startPayment', MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT })
10
10
 
11
11
  if (!MERCHANT_KEY || !MERCHANT_ID) {
12
12
  throw new Error(`Missing SimplePay configuration for ${currency}`)
@@ -27,7 +27,7 @@ const startPayment = async (paymentData: PaymentData) => {
27
27
  invoice: paymentData.invoice,
28
28
  }
29
29
 
30
- return makeSimplePayRequest(API_URL, requestBody, MERCHANT_KEY)
30
+ return makeSimplePayRequest(API_URL_PAYMENT, requestBody, MERCHANT_KEY)
31
31
  }
32
32
 
33
33
  export { startPayment }
package/src/recurring.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import crypto from 'crypto'
2
- import { SimplePayRecurringRequestBody, RecurringPaymentData, TokenPaymentData, SimplePayTokenRequestBody} from './types'
3
- import { getSimplePayConfig, simplepayLogger, toISO8601DateString, makeSimplePayTokenRequest, makeSimplePayRecurringRequest} from './utils'
2
+ import { SimplePayRecurringRequestBody, RecurringPaymentData, TokenPaymentData, SimplePayTokenRequestBody, SimplePayCardCancelRequestBody} from './types'
3
+ import { getSimplePayConfig, simplepayLogger, toISO8601DateString, makeSimplePayTokenRequest, makeSimplePayRecurringRequest, makeSimplePayRequest, makeSimplePayCardCancelRequest} from './utils'
4
4
 
5
5
  const INTERVAL_IN_MONTHS = 6
6
6
  const DEFAULT_UNTIL = new Date(Date.now() + INTERVAL_IN_MONTHS * 30 * 24 * 60 * 60 * 1000)
@@ -10,8 +10,8 @@ const DEFAULT_TIMES = 3
10
10
  const startRecurringPayment = async (paymentData: RecurringPaymentData) => {
11
11
  simplepayLogger({ function: 'SimplePay/startRecurringPayment', paymentData })
12
12
  const currency = paymentData.currency || 'HUF'
13
- const { MERCHANT_KEY, MERCHANT_ID, API_URL, SDK_VERSION } = getSimplePayConfig(currency)
14
- simplepayLogger({ function: 'SimplePay/startRecurringPayment', MERCHANT_KEY, MERCHANT_ID, API_URL })
13
+ const { MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT, SDK_VERSION } = getSimplePayConfig(currency)
14
+ simplepayLogger({ function: 'SimplePay/startRecurringPayment', MERCHANT_KEY, MERCHANT_ID, API_URL_PAYMENT })
15
15
 
16
16
  if (!MERCHANT_KEY || !MERCHANT_ID) {
17
17
  throw new Error(`Missing SimplePay configuration for ${currency}`)
@@ -39,7 +39,7 @@ const startRecurringPayment = async (paymentData: RecurringPaymentData) => {
39
39
  invoice: paymentData.invoice,
40
40
  }
41
41
 
42
- return makeSimplePayRecurringRequest(API_URL, requestBody, MERCHANT_KEY)
42
+ return makeSimplePayRecurringRequest(API_URL_PAYMENT, requestBody, MERCHANT_KEY)
43
43
  }
44
44
 
45
45
  const startTokenPayment = async (paymentData: TokenPaymentData) => {
@@ -74,4 +74,21 @@ const startTokenPayment = async (paymentData: TokenPaymentData) => {
74
74
  return makeSimplePayTokenRequest(API_URL_RECURRING, requestBody, MERCHANT_KEY)
75
75
  }
76
76
 
77
- export { startRecurringPayment, startTokenPayment }
77
+ const cardCancel = async (cardId: string) => {
78
+ simplepayLogger({ function: 'SimplePay/cardCancel', cardId })
79
+ const {API_URL_CARD_CANCEL, MERCHANT_KEY, MERCHANT_ID, SDK_VERSION} = getSimplePayConfig('HUF')
80
+
81
+ if (!MERCHANT_KEY || !MERCHANT_ID) {
82
+ throw new Error(`Missing SimplePay configuration for HUF`)
83
+ }
84
+
85
+ const requestBody: SimplePayCardCancelRequestBody = {
86
+ salt: crypto.randomBytes(16).toString('hex'),
87
+ cardId,
88
+ merchant: MERCHANT_ID,
89
+ sdkVersion: SDK_VERSION,
90
+ }
91
+ return makeSimplePayCardCancelRequest(API_URL_CARD_CANCEL, requestBody, MERCHANT_KEY)
92
+ }
93
+
94
+ export { startRecurringPayment, startTokenPayment , cardCancel}
package/src/types.ts CHANGED
@@ -82,6 +82,13 @@ export interface SimplePayTokenRequestBody extends SimplePayRequestBody {
82
82
  type: 'MIT' // Merchant Initiated Transaction
83
83
  }
84
84
 
85
+ export interface SimplePayCardCancelRequestBody {
86
+ salt: string
87
+ cardId: string
88
+ merchant: string
89
+ sdkVersion: string
90
+ }
91
+
85
92
  export interface SimplePayResponse {
86
93
  salt: string
87
94
  merchant: string
@@ -100,6 +107,14 @@ export interface SimplePayRecurringResponse extends SimplePayResponse {
100
107
 
101
108
  export interface SimplePayTokenResponse extends Omit<SimplePayResponse, 'paymentUrl' | 'timeout'> { }
102
109
 
110
+ export interface SimplePayCardCancelResponse {
111
+ salt: string
112
+ merchant: string
113
+ cardId: string
114
+ status: 'DISABLED'
115
+ expiry: string
116
+ }
117
+
103
118
  export type SimplePayEvents = 'SUCCESS' | 'FAIL' | 'TIMEOUT' | 'CANCEL'
104
119
 
105
120
  export interface SimplePayAPIResult {
package/src/utils.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import crypto from 'crypto'
2
- import { CURRENCIES, Currency, ISO8601DateString, SimplePayAPIResult, SimplePayRecurringRequestBody, SimplePayRecurringResponse, SimplePayRequestBody, SimplePayResponse, SimplePayResult, SimplePayTokenRequestBody, SimplePayTokenResponse } from "./types"
2
+ import { CURRENCIES, Currency, ISO8601DateString, SimplePayAPIResult, SimplePayCardCancelRequestBody, SimplePayCardCancelResponse, SimplePayRecurringRequestBody, SimplePayRecurringResponse, SimplePayRequestBody, SimplePayResponse, SimplePayResult, SimplePayTokenRequestBody, SimplePayTokenResponse } from "./types"
3
3
 
4
4
  export const simplepayLogger = (...args: any[]) => {
5
5
  if (process.env.SIMPLEPAY_LOGGER !== 'true') {
@@ -15,18 +15,21 @@ export const getSimplePayConfig = (currency: Currency) => {
15
15
  }
16
16
 
17
17
  const SIMPLEPAY_API_URL = 'https://secure.simplepay.hu/payment/v2'
18
- const SIMPLEPAY_SANDBOX_URL = 'https://sandbox.simplepay.hu/payment/v2/start'
19
- const SDK_VERSION = 'SimplePayV2.1_Rrd_0.6.1'
18
+ const SIMPLEPAY_SANDBOX_URL = 'https://sandbox.simplepay.hu/payment/v2'
19
+ const SDK_VERSION = 'SimplePayV2.1_Rrd_0.8.0'
20
20
  const MERCHANT_KEY = process.env[`SIMPLEPAY_MERCHANT_KEY_${currency}`]
21
21
  const MERCHANT_ID = process.env[`SIMPLEPAY_MERCHANT_ID_${currency}`]
22
- const API_URL = process.env.SIMPLEPAY_PRODUCTION === 'true' ? SIMPLEPAY_API_URL : SIMPLEPAY_SANDBOX_URL
23
- const API_URL_RECURRING = process.env.SIMPLEPAY_PRODUCTION === 'true' ? SIMPLEPAY_API_URL : 'https://sandbox.simplepay.hu/payment/v2/dorecurring'
24
22
 
23
+ const API_URL = process.env.SIMPLEPAY_PRODUCTION === 'true' ? SIMPLEPAY_API_URL : SIMPLEPAY_SANDBOX_URL
24
+ const API_URL_PAYMENT = API_URL + '/start'
25
+ const API_URL_RECURRING = API_URL + '/dorecurring'
26
+ const API_URL_CARD_CANCEL = API_URL + '/cancelcard'
25
27
  return {
26
28
  MERCHANT_KEY,
27
29
  MERCHANT_ID,
28
- API_URL,
30
+ API_URL_PAYMENT,
29
31
  API_URL_RECURRING,
32
+ API_URL_CARD_CANCEL,
30
33
  SDK_VERSION
31
34
  }
32
35
  }
@@ -69,7 +72,11 @@ export const makeSimplePayTokenRequest = async (apiUrl: string, requestBody: Sim
69
72
  return makeRequest(apiUrl, requestBody, merchantKey, 'token') as Promise<SimplePayTokenResponse>
70
73
  }
71
74
 
72
- const makeRequest = async (apiUrl: string, requestBody: SimplePayRequestBody | SimplePayRecurringRequestBody | SimplePayTokenRequestBody, merchantKey: string, type: 'oneTime' | 'recurring' | 'token') => {
75
+ export const makeSimplePayCardCancelRequest = async (apiUrl: string, requestBody: SimplePayCardCancelRequestBody, merchantKey: string) => {
76
+ return makeRequest(apiUrl, requestBody, merchantKey, 'cardCancel') as Promise<SimplePayCardCancelResponse>
77
+ }
78
+
79
+ const makeRequest = async (apiUrl: string, requestBody: SimplePayRequestBody | SimplePayRecurringRequestBody | SimplePayTokenRequestBody | SimplePayCardCancelRequestBody, merchantKey: string, type: 'oneTime' | 'recurring' | 'token' | 'cardCancel') => {
73
80
  const bodyString = prepareRequestBody(requestBody)
74
81
  const signature = generateSignature(bodyString, merchantKey)
75
82
  simplepayLogger({ function: `SimplePay/makeRequest/${type}`, bodyString, signature })