simplepay-js-sdk 0.6.0 → 0.6.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/dist/index.js +16 -15
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
- package/src/index.spec.ts +8 -0
- package/src/index.ts +1 -2
package/dist/index.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
import P from "crypto";
|
|
2
|
+
const h = ["HUF", "EUR", "USD"], a = (...e) => {
|
|
2
3
|
process.env.SIMPLEPAY_LOGGER === "true" && console.log(...e);
|
|
3
4
|
}, R = (e, t) => {
|
|
4
5
|
const r = P.createHmac("sha384", t.trim());
|
|
5
6
|
return r.update(e, "utf8"), r.digest("base64");
|
|
6
|
-
}, _ = (e, t, r) => t === R(e, r),
|
|
7
|
-
if (!
|
|
7
|
+
}, _ = (e, t, r) => t === R(e, r), I = (e) => JSON.stringify(e).replace(/\//g, "\\/"), g = (e) => {
|
|
8
|
+
if (!h.includes(e))
|
|
8
9
|
throw new Error(`Unsupported currency: ${e}`);
|
|
9
|
-
const t = "https://secure.simplepay.hu/payment/v2", r = "https://sandbox.simplepay.hu/payment/v2/start", o = "SimplePayV2.1_Rrd_0.
|
|
10
|
+
const t = "https://secure.simplepay.hu/payment/v2", r = "https://sandbox.simplepay.hu/payment/v2/start", o = "SimplePayV2.1_Rrd_0.6.0", s = process.env[`SIMPLEPAY_MERCHANT_KEY_${e}`], c = process.env[`SIMPLEPAY_MERCHANT_ID_${e}`], n = process.env.SIMPLEPAY_PRODUCTION === "true" ? t : r;
|
|
10
11
|
return {
|
|
11
12
|
MERCHANT_KEY: s,
|
|
12
13
|
MERCHANT_ID: c,
|
|
13
14
|
API_URL: n,
|
|
14
15
|
SDK_VERSION: o
|
|
15
16
|
};
|
|
16
|
-
},
|
|
17
|
-
const t = e.currency || "HUF", { MERCHANT_KEY: r, MERCHANT_ID: o, API_URL: s, SDK_VERSION: c } =
|
|
17
|
+
}, A = async (e) => {
|
|
18
|
+
const t = e.currency || "HUF", { MERCHANT_KEY: r, MERCHANT_ID: o, API_URL: s, SDK_VERSION: c } = g(t);
|
|
18
19
|
if (a({ MERCHANT_KEY: r, MERCHANT_ID: o, API_URL: s }), !r || !o)
|
|
19
20
|
throw new Error("Missing SimplePay configuration");
|
|
20
21
|
const n = {
|
|
@@ -30,7 +31,7 @@ const P = {}, I = ["HUF", "EUR", "USD"], a = (...e) => {
|
|
|
30
31
|
timeout: new Date(Date.now() + 30 * 60 * 1e3).toISOString().replace(/\.\d{3}Z$/, "+00:00"),
|
|
31
32
|
url: process.env.SIMPLEPAY_REDIRECT_URL || "http://url.to.redirect",
|
|
32
33
|
invoice: e.invoice
|
|
33
|
-
}, p =
|
|
34
|
+
}, p = I(n), u = R(p, r);
|
|
34
35
|
a({ bodyString: p, signature: u });
|
|
35
36
|
try {
|
|
36
37
|
const i = await fetch(s, {
|
|
@@ -55,7 +56,7 @@ const P = {}, I = ["HUF", "EUR", "USD"], a = (...e) => {
|
|
|
55
56
|
} catch (i) {
|
|
56
57
|
throw i;
|
|
57
58
|
}
|
|
58
|
-
},
|
|
59
|
+
}, m = (e) => {
|
|
59
60
|
var r, o;
|
|
60
61
|
const t = (o = (r = Object.entries(process.env).find(
|
|
61
62
|
([s, c]) => s.startsWith("SIMPLEPAY_MERCHANT_ID_") && c === e
|
|
@@ -63,9 +64,9 @@ const P = {}, I = ["HUF", "EUR", "USD"], a = (...e) => {
|
|
|
63
64
|
if (!t)
|
|
64
65
|
throw new Error(`Merchant id not found in the environment: ${e}`);
|
|
65
66
|
return t;
|
|
66
|
-
},
|
|
67
|
-
t = decodeURIComponent(t)
|
|
68
|
-
const r = Buffer.from(e, "base64").toString("utf-8"), o = JSON.parse(r), s =
|
|
67
|
+
}, f = (e, t) => {
|
|
68
|
+
t = decodeURIComponent(t);
|
|
69
|
+
const r = Buffer.from(e, "base64").toString("utf-8"), o = JSON.parse(r), s = m(o.m), { MERCHANT_KEY: c } = g(s);
|
|
69
70
|
if (!_(r, t, c || ""))
|
|
70
71
|
throw a({ rDecoded: r, signature: t }), new Error("Invalid response signature");
|
|
71
72
|
const n = JSON.parse(r);
|
|
@@ -80,9 +81,9 @@ const P = {}, I = ["HUF", "EUR", "USD"], a = (...e) => {
|
|
|
80
81
|
export {
|
|
81
82
|
_ as checkSignature,
|
|
82
83
|
R as generateSignature,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
m as getCurrencyFromMerchantId,
|
|
85
|
+
f as getPaymentResponse,
|
|
86
|
+
g as getSimplePayConfig,
|
|
87
|
+
A as startPayment
|
|
87
88
|
};
|
|
88
89
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../__vite-browser-external","../src/types.ts","../src/index.ts"],"sourcesContent":["export default {}","type PaymentMethod = 'CARD' | 'WIRE'\n\nconst CURRENCIES = ['HUF', 'EUR', 'USD'] as const\ntype Currency = typeof CURRENCIES[number]\n\nconst 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\ntype Language = typeof LANGUAGES[number]\n\ninterface 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\ninterface 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\ninterface SimplePayResponse {\n salt: string\n merchant: string\n orderRef: string\n currency: Currency\n transactionId: string\n timeout: string\n total: string\n paymentUrl: string\n errorCodes?: string[]\n}\n\ninterface SimplepayResult {\n r: number // response code\n t: string // transaction id\n e: 'success' | 'fail' | 'timeout' | 'cancel' // event\n m: string // merchant id\n o: string // order id\n}\n\nexport { PaymentData, SimplePayRequestBody, SimplePayResponse, SimplepayResult, CURRENCIES, Currency, PaymentMethod, LANGUAGES, Language }","import crypto from 'crypto'\nimport { PaymentData, SimplePayRequestBody, SimplePayResponse, SimplepayResult, Currency, CURRENCIES } from './types'\n\n// Existing interfaces remain the same\n\nconst simplepayLogger = (...args: any[]) => {\n if (process.env.SIMPLEPAY_LOGGER !== 'true') {\n return\n }\n console.log(...args)\n}\n\nconst 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\nconst checkSignature = (responseText: string, signature: string, merchantKey: string) =>\n signature === generateSignature(responseText, merchantKey)\n\n// escaping slashes for the request body to prevent strange SimplePay API errors (eg Missing Signature)\nconst prepareRequestBody = (body: SimplePayRequestBody) =>\n JSON.stringify(body).replace(/\\//g, '\\\\/')\n\n\nconst 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.5.0'\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\n return {\n MERCHANT_KEY,\n MERCHANT_ID,\n API_URL,\n SDK_VERSION\n }\n}\n\nconst startPayment = async (paymentData: PaymentData) => {\n const currency = paymentData.currency || 'HUF'\n const { MERCHANT_KEY, MERCHANT_ID, API_URL, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ MERCHANT_KEY, MERCHANT_ID, API_URL })\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error('Missing SimplePay configuration')\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: new Date(Date.now() + 30 * 60 * 1000)\n .toISOString()\n .replace(/\\.\\d{3}Z$/, '+00:00'),\n url: process.env.SIMPLEPAY_REDIRECT_URL || 'http://url.to.redirect',\n invoice: paymentData.invoice,\n }\n\n const bodyString = prepareRequestBody(requestBody)\n const signature = generateSignature(bodyString, MERCHANT_KEY)\n simplepayLogger({ bodyString, signature })\n\n try {\n const response = await fetch(API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Signature': signature,\n },\n body: bodyString,\n })\n\n simplepayLogger({ 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({ 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 SimplePayResponse\n simplepayLogger({ responseText, responseJSON })\n\n if (responseJSON.errorCodes) {\n throw new Error(`SimplePay API error: ${responseJSON.errorCodes}`)\n }\n\n if (!checkSignature(responseText, responseSignature, MERCHANT_KEY)) {\n throw new Error('Invalid response signature')\n }\n\n return responseJSON\n\n } catch (error) {\n throw error\n }\n}\n\nconst 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\nconst getPaymentResponse = (r: string, signature: string) => {\n signature = decodeURIComponent(signature)\n signature = Buffer.from(signature, 'base64').toString('utf-8')\n const rDecoded = Buffer.from(r, 'base64').toString('utf-8')\n const rDecodedJSON = JSON.parse(rDecoded)\n const currency = getCurrencyFromMerchantId(rDecodedJSON.m)\n const { MERCHANT_KEY } = getSimplePayConfig(currency as Currency)\n\n if (!checkSignature(rDecoded, signature, MERCHANT_KEY || '')) {\n simplepayLogger({ rDecoded, signature })\n throw new Error('Invalid response signature')\n }\n\n const responseJson: SimplepayResult = JSON.parse(rDecoded)\n const response = {\n responseCode: responseJson.r,\n transactionId: responseJson.t,\n event: responseJson.e,\n merchantId: responseJson.m,\n orderRef: responseJson.o,\n }\n\n return response\n}\n\nexport {\n startPayment,\n getPaymentResponse,\n getSimplePayConfig,\n generateSignature,\n checkSignature,\n getCurrencyFromMerchantId\n}"],"names":["crypto","CURRENCIES","simplepayLogger","args","generateSignature","body","merchantKey","hmac","checkSignature","responseText","signature","prepareRequestBody","getSimplePayConfig","currency","SIMPLEPAY_API_URL","SIMPLEPAY_SANDBOX_URL","SDK_VERSION","MERCHANT_KEY","MERCHANT_ID","API_URL","startPayment","paymentData","requestBody","bodyString","response","responseSignature","responseJSON","error","getCurrencyFromMerchantId","merchantId","_a","_b","key","value","getPaymentResponse","r","rDecoded","rDecodedJSON","responseJson"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/types.ts","../src/index.ts"],"sourcesContent":["type PaymentMethod = 'CARD' | 'WIRE'\n\nconst CURRENCIES = ['HUF', 'EUR', 'USD'] as const\ntype Currency = typeof CURRENCIES[number]\n\nconst 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\ntype Language = typeof LANGUAGES[number]\n\ninterface 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\ninterface 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\ninterface SimplePayResponse {\n salt: string\n merchant: string\n orderRef: string\n currency: Currency\n transactionId: string\n timeout: string\n total: string\n paymentUrl: string\n errorCodes?: string[]\n}\n\ninterface SimplepayResult {\n r: number // response code\n t: string // transaction id\n e: 'success' | 'fail' | 'timeout' | 'cancel' // event\n m: string // merchant id\n o: string // order id\n}\n\nexport { PaymentData, SimplePayRequestBody, SimplePayResponse, SimplepayResult, CURRENCIES, Currency, PaymentMethod, LANGUAGES, Language }","import crypto from 'crypto'\nimport { PaymentData, SimplePayRequestBody, SimplePayResponse, SimplepayResult, Currency, CURRENCIES } from './types'\n\n// Existing interfaces remain the same\n\nconst simplepayLogger = (...args: any[]) => {\n if (process.env.SIMPLEPAY_LOGGER !== 'true') {\n return\n }\n console.log(...args)\n}\n\nconst 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\nconst checkSignature = (responseText: string, signature: string, merchantKey: string) =>\n signature === generateSignature(responseText, merchantKey)\n\n// escaping slashes for the request body to prevent strange SimplePay API errors (eg Missing Signature)\nconst prepareRequestBody = (body: SimplePayRequestBody) =>\n JSON.stringify(body).replace(/\\//g, '\\\\/')\n\n\nconst 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.0'\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\n return {\n MERCHANT_KEY,\n MERCHANT_ID,\n API_URL,\n SDK_VERSION\n }\n}\n\nconst startPayment = async (paymentData: PaymentData) => {\n const currency = paymentData.currency || 'HUF'\n const { MERCHANT_KEY, MERCHANT_ID, API_URL, SDK_VERSION } = getSimplePayConfig(currency)\n simplepayLogger({ MERCHANT_KEY, MERCHANT_ID, API_URL })\n\n if (!MERCHANT_KEY || !MERCHANT_ID) {\n throw new Error('Missing SimplePay configuration')\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: new Date(Date.now() + 30 * 60 * 1000)\n .toISOString()\n .replace(/\\.\\d{3}Z$/, '+00:00'),\n url: process.env.SIMPLEPAY_REDIRECT_URL || 'http://url.to.redirect',\n invoice: paymentData.invoice,\n }\n\n const bodyString = prepareRequestBody(requestBody)\n const signature = generateSignature(bodyString, MERCHANT_KEY)\n simplepayLogger({ bodyString, signature })\n\n try {\n const response = await fetch(API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Signature': signature,\n },\n body: bodyString,\n })\n\n simplepayLogger({ 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({ 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 SimplePayResponse\n simplepayLogger({ responseText, responseJSON })\n\n if (responseJSON.errorCodes) {\n throw new Error(`SimplePay API error: ${responseJSON.errorCodes}`)\n }\n\n if (!checkSignature(responseText, responseSignature, MERCHANT_KEY)) {\n throw new Error('Invalid response signature')\n }\n\n return responseJSON\n\n } catch (error) {\n throw error\n }\n}\n\nconst 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\nconst getPaymentResponse = (r: string, signature: string) => {\n signature = decodeURIComponent(signature)\n const rDecoded = Buffer.from(r, 'base64').toString('utf-8')\n const rDecodedJSON = JSON.parse(rDecoded)\n const currency = getCurrencyFromMerchantId(rDecodedJSON.m)\n const { MERCHANT_KEY } = getSimplePayConfig(currency as Currency)\n\n if (!checkSignature(rDecoded, signature, MERCHANT_KEY || '')) {\n simplepayLogger({ rDecoded, signature })\n throw new Error('Invalid response signature')\n }\n\n const responseJson: SimplepayResult = JSON.parse(rDecoded)\n const response = {\n responseCode: responseJson.r,\n transactionId: responseJson.t,\n event: responseJson.e,\n merchantId: responseJson.m,\n orderRef: responseJson.o,\n }\n\n return response\n}\n\nexport {\n startPayment,\n getPaymentResponse,\n getSimplePayConfig,\n generateSignature,\n checkSignature,\n getCurrencyFromMerchantId\n}"],"names":["CURRENCIES","simplepayLogger","args","generateSignature","body","merchantKey","hmac","crypto","checkSignature","responseText","signature","prepareRequestBody","getSimplePayConfig","currency","SIMPLEPAY_API_URL","SIMPLEPAY_SANDBOX_URL","SDK_VERSION","MERCHANT_KEY","MERCHANT_ID","API_URL","startPayment","paymentData","requestBody","bodyString","response","responseSignature","responseJSON","error","getCurrencyFromMerchantId","merchantId","_b","_a","key","value","getPaymentResponse","r","rDecoded","rDecodedJSON","responseJson"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simplepay-js-sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "A Node.js utility for SimplePay payment integration",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
13
13
|
"types": "./dist/index.d.ts",
|
|
14
|
-
"import": "./dist/index.js"
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"node": "./dist/index.js"
|
|
15
16
|
}
|
|
16
17
|
},
|
|
17
18
|
"types": "./dist/index.d.ts",
|
|
@@ -37,12 +38,13 @@
|
|
|
37
38
|
"license": "MIT",
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@types/node": "^22.0.0",
|
|
40
|
-
"typescript": "
|
|
41
|
+
"typescript": "~5.4.2",
|
|
41
42
|
"vite": "^6.0.3",
|
|
42
43
|
"vite-plugin-dts": "^4.3.0",
|
|
43
44
|
"vitest": "^2.1.6"
|
|
44
45
|
},
|
|
45
46
|
"engines": {
|
|
46
47
|
"node": ">=20.0.0"
|
|
47
|
-
}
|
|
48
|
+
},
|
|
49
|
+
"browser": false
|
|
48
50
|
}
|
package/src/index.spec.ts
CHANGED
|
@@ -112,6 +112,14 @@ describe('SimplePay SDK Tests', () => {
|
|
|
112
112
|
})
|
|
113
113
|
|
|
114
114
|
describe('getPaymentResponse', () => {
|
|
115
|
+
it.only('TODO: test for invalid response', () => {
|
|
116
|
+
process.env.SIMPLEPAY_MERCHANT_ID_HUF = 'P085602'
|
|
117
|
+
process.env.SIMPLEPAY_MERCHANT_KEY_HUF = 'QnJvDEEj51jdDEa1P125258p8g5gU383'
|
|
118
|
+
const r = 'eyJyIjowLCJ0Ijo1MDQyNDU5MDIsImUiOiJTVUNDRVNTIiwibSI6IlAwODU2MDIiLCJvIjoiMTczMzQ5MzQxMjA1NyJ9'
|
|
119
|
+
const s = 'apIUA%2B8cislIlgYUB7lSpoasi%2BCIRg1SMS5zVbEytnEnxcvdx%2BWDXkAznnseADiI'
|
|
120
|
+
const result = getPaymentResponse(r, s)
|
|
121
|
+
})
|
|
122
|
+
|
|
115
123
|
it('should correctly decode and parse valid response', () => {
|
|
116
124
|
setEnv()
|
|
117
125
|
const r = 'eyJyIjowLCJ0Ijo1MDQyMzM4ODEsImUiOiJTVUNDRVNTIiwibSI6Im1lcmNoYW50RXVyb0lkIiwibyI6ImMtMS1ldXIifQ=='
|
package/src/index.ts
CHANGED
|
@@ -31,7 +31,7 @@ const getSimplePayConfig = (currency: Currency) => {
|
|
|
31
31
|
|
|
32
32
|
const SIMPLEPAY_API_URL = 'https://secure.simplepay.hu/payment/v2'
|
|
33
33
|
const SIMPLEPAY_SANDBOX_URL = 'https://sandbox.simplepay.hu/payment/v2/start'
|
|
34
|
-
const SDK_VERSION = 'SimplePayV2.1_Rrd_0.6.
|
|
34
|
+
const SDK_VERSION = 'SimplePayV2.1_Rrd_0.6.1'
|
|
35
35
|
const MERCHANT_KEY = process.env[`SIMPLEPAY_MERCHANT_KEY_${currency}`]
|
|
36
36
|
const MERCHANT_ID = process.env[`SIMPLEPAY_MERCHANT_ID_${currency}`]
|
|
37
37
|
const API_URL = process.env.SIMPLEPAY_PRODUCTION === 'true' ? SIMPLEPAY_API_URL : SIMPLEPAY_SANDBOX_URL
|
|
@@ -128,7 +128,6 @@ const getCurrencyFromMerchantId = (merchantId: string) => {
|
|
|
128
128
|
|
|
129
129
|
const getPaymentResponse = (r: string, signature: string) => {
|
|
130
130
|
signature = decodeURIComponent(signature)
|
|
131
|
-
signature = Buffer.from(signature, 'base64').toString('utf-8')
|
|
132
131
|
const rDecoded = Buffer.from(r, 'base64').toString('utf-8')
|
|
133
132
|
const rDecodedJSON = JSON.parse(rDecoded)
|
|
134
133
|
const currency = getCurrencyFromMerchantId(rDecodedJSON.m)
|