@opengis/pay 1.3.3 → 2.0.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.md +45 -12
- package/module/pay/pt/marketplace-service-payment-client-template.html +5 -5
- package/package.json +38 -36
- package/plugin.js +2 -0
- package/server/migrations/7_transactions.sql +35 -0
- package/server/plugins/hook.js +27 -10
- package/server/plugins/payment/createPayment.js +29 -0
- package/server/plugins/payment/createTransaction.js +26 -0
- package/server/plugins/payment/liqpay.checkStatus.js +43 -0
- package/server/plugins/payment/liqpay.createTransaction.js +103 -0
- package/server/plugins/payment/monopay.checkStatus.js +48 -0
- package/server/plugins/payment/monopay.createTransaction.js +116 -0
- package/server/plugins/payment/paymentInfo.js +26 -0
- package/server/plugins/payment/portmone.checkStatus.js +51 -0
- package/server/plugins/payment/portmone.createTransaction.js +94 -0
- package/server/plugins/payment/processTransaction.js +73 -0
- package/server/routes/{portmone → core}/controllers/payment.info.js +32 -29
- package/server/routes/core/index.mjs +12 -0
- package/server/routes/liqpay/controllers/liqpay.redirect.js +25 -115
- package/server/routes/liqpay/controllers/liqpay.status.js +31 -150
- package/server/routes/monopay/controllers/monopay.redirect.js +25 -117
- package/server/routes/monopay/controllers/monopay.status.js +8 -56
- package/server/routes/portmone/controllers/portmone.redirect.js +27 -116
- package/server/routes/portmone/controllers/portmone.status.js +36 -136
- package/server/routes/portmone/index.mjs +5 -6
- package/utils.js +11 -0
- package/server/migrations/1_users.sql +0 -121
- package/server/migrations/2_accounts.sql +0 -59
- package/server/migrations/3_utils.sql +0 -74
- package/server/migrations/4_subscriptions.sql +0 -36
- package/server/migrations/5_payments.sql +0 -39
- package/server/migrations/6_invoices.sql +0 -55
- package/server/routes/liqpay/utils/check.status.js +0 -34
- package/server/routes/portmone/utils/portmone.check.status.js +0 -34
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import config from '../../../config.js';
|
|
2
|
+
import pgClients from '../pg/pgClients.js';
|
|
3
|
+
|
|
4
|
+
const { table = 'pay.transactions' } = config.integrations?.pay || {};
|
|
5
|
+
|
|
6
|
+
export default async function paymentInfo(id, pg = pgClients.client) {
|
|
7
|
+
if (!id) throw new Error('not enough params: id');
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
amount,
|
|
11
|
+
status,
|
|
12
|
+
service,
|
|
13
|
+
referer_url: referer,
|
|
14
|
+
user_id: userId,
|
|
15
|
+
} = id && pg.pk?.[table] ? await pg.query(`select ${pg.pk?.[table]} as id, * from ${table} where ${pg.pk?.[table]}=$1`, [id])
|
|
16
|
+
.then(el => el.rows?.[0] || {}) : {};
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
id, // id for existing transtaction
|
|
20
|
+
price: amount, // price for new transtaction as is, else - preCreated
|
|
21
|
+
status, // payment status
|
|
22
|
+
service, // service name
|
|
23
|
+
referer, // redirect user after finish of transaction
|
|
24
|
+
uid: userId,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import request from 'request-promise';
|
|
2
|
+
|
|
3
|
+
import config from '../../../config.js';
|
|
4
|
+
import pgClients from '../pg/pgClients.js';
|
|
5
|
+
|
|
6
|
+
const { table = 'pay.transactions' } = config.integrations?.pay || {};
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
host = 'https://www.portmone.com.ua',
|
|
10
|
+
login,
|
|
11
|
+
password,
|
|
12
|
+
payeeId,
|
|
13
|
+
} = config.integrations?.portmone || {};
|
|
14
|
+
|
|
15
|
+
export default async function portmoneCheckStatus(id, origin, pg = pgClients.client) {
|
|
16
|
+
if (!payeeId) throw new Error('empty integration params: payeeId');
|
|
17
|
+
if (!id) throw new Error('not enough params: id');
|
|
18
|
+
|
|
19
|
+
const data = pg.pk?.[table] && id ? await pg.query(`select ${pg.pk?.[table]} as id, * from ${table} where ${pg.pk?.[table]}=$1`, [id]).then(el => el.rows?.[0] || {}) : undefined;
|
|
20
|
+
if (!data?.id) throw new Error('transaction not found');
|
|
21
|
+
|
|
22
|
+
const formData = {
|
|
23
|
+
method: 'result',
|
|
24
|
+
login,
|
|
25
|
+
password,
|
|
26
|
+
payeeId,
|
|
27
|
+
shopOrderNumber: data.id,
|
|
28
|
+
// shopbillId,
|
|
29
|
+
id: data.id,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const isValidOrigin = origin && origin === host;
|
|
33
|
+
|
|
34
|
+
if (!(login && password) && !isValidOrigin) {
|
|
35
|
+
throw new Error('empty integration params: portmone 2');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ? likely cause timeout, skip be origin check or check credentials i.e.: login, password
|
|
39
|
+
const response = isValidOrigin ? { billAmount: data.amount, status: 'success' } : await request({
|
|
40
|
+
url: `${host}/gateway/`,
|
|
41
|
+
method: 'POST',
|
|
42
|
+
formData,
|
|
43
|
+
followAllRedirects: false,
|
|
44
|
+
jar: true,
|
|
45
|
+
timeout: 6000,
|
|
46
|
+
simple: false, // prevent not 2xx code trigger catch
|
|
47
|
+
resolveWithFullResponse: true,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return { ...response, status: response.status, amount: +response.billAmount };
|
|
51
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import request from 'request-promise';
|
|
2
|
+
|
|
3
|
+
import config from '../../../config.js';
|
|
4
|
+
import pgClients from '../pg/pgClients.js';
|
|
5
|
+
|
|
6
|
+
import createPayment from './createPayment.js';
|
|
7
|
+
|
|
8
|
+
const { prefix = '/api' } = config;
|
|
9
|
+
|
|
10
|
+
const { table = 'pay.transactions' } = config.integrations?.pay || {};
|
|
11
|
+
const { host = 'https://www.portmone.com.ua', payeeId } = config.integrations?.portmone || {};
|
|
12
|
+
|
|
13
|
+
export default async function portmoneCreateTransaction({
|
|
14
|
+
id, price, rootUrl, referer, uid, debug,
|
|
15
|
+
}, pg = pgClients.client) {
|
|
16
|
+
if (!host) {
|
|
17
|
+
throw new Error('empty integration host');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!payeeId) {
|
|
21
|
+
throw new Error('empty integration payeeId');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!id && !price) {
|
|
25
|
+
throw new Error('not enough params: id or price required');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!rootUrl) {
|
|
29
|
+
throw new Error('not enough params: rootUrl required');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!uid) {
|
|
33
|
+
throw new Error('not enough params: uid required');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const paymentId = !id ? await pg.query('select next_id()').then(el => el.rows?.[0]?.next_id) : id;
|
|
37
|
+
|
|
38
|
+
const paymentData = id && pg.pk?.[table]
|
|
39
|
+
? await pg.query(`select ${pg.pk?.[table]} as id, * from ${table} where ${pg.pk?.[table]}=$1`, [id]).then(el => el.rows?.[0])
|
|
40
|
+
: await createPayment({
|
|
41
|
+
paymentId,
|
|
42
|
+
price,
|
|
43
|
+
referer,
|
|
44
|
+
uid,
|
|
45
|
+
service: 'portmone',
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (!paymentData?.id) {
|
|
49
|
+
throw new Error('payment not found / creation failed');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const paymentAmount = id ? paymentData.amount : price;
|
|
53
|
+
|
|
54
|
+
if (!paymentAmount) {
|
|
55
|
+
throw new Error('invalid payment amount');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const formData = {
|
|
59
|
+
payee_id: payeeId,
|
|
60
|
+
description: `Послуга - поповнення рахунку на суму ${paymentAmount} грн`,
|
|
61
|
+
shop_order_number: paymentData.id,
|
|
62
|
+
bill_amount: paymentAmount,
|
|
63
|
+
success_url: `${rootUrl}${prefix}/portmone/${paymentData.id}/success`,
|
|
64
|
+
failure_url: `${rootUrl}${prefix}/portmone/${paymentData.id}/error`,
|
|
65
|
+
lang: 'ua',
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// portmone always returns error without simple: false options
|
|
69
|
+
const response = await request({
|
|
70
|
+
url: `${host}/gateway/`,
|
|
71
|
+
method: 'POST',
|
|
72
|
+
formData,
|
|
73
|
+
followAllRedirects: false,
|
|
74
|
+
jar: true,
|
|
75
|
+
timeout: 6000,
|
|
76
|
+
simple: false, // prevent not 2xx code trigger catch
|
|
77
|
+
resolveWithFullResponse: true,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (process.env.NODE_ENV !== 'test' && debug) {
|
|
81
|
+
return response;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// handle exceptions
|
|
85
|
+
if (response.statusCode !== 302 || !response.headers?.location) {
|
|
86
|
+
throw new Error(response);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (process.env.NODE_ENV === 'test' && debug) {
|
|
90
|
+
return { id: paymentData?.id, url: response.headers.location };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return response.headers.location;
|
|
94
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import config from '../../../config.js';
|
|
2
|
+
import pgClients from '../pg/pgClients.js';
|
|
3
|
+
import dataUpdate from '../crud/dataUpdate.js';
|
|
4
|
+
|
|
5
|
+
import liqpayCheckStatus from './liqpay.checkStatus.js';
|
|
6
|
+
import monopayCheckStatus from './monopay.checkStatus.js';
|
|
7
|
+
import portmoneCheckStatus from './portmone.checkStatus.js';
|
|
8
|
+
|
|
9
|
+
const controller = {
|
|
10
|
+
liqpay: liqpayCheckStatus,
|
|
11
|
+
monopay: monopayCheckStatus,
|
|
12
|
+
portmone: portmoneCheckStatus,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const newDate = () => {
|
|
16
|
+
const date = new Date();
|
|
17
|
+
const tzOffset = date.getTimezoneOffset();
|
|
18
|
+
const currentTimeWithTimezome = date - tzOffset * 60 * 1000;
|
|
19
|
+
return new Date(currentTimeWithTimezome).toISOString();
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const { table = 'pay.transactions' } = config.integrations?.liqpay || {};
|
|
23
|
+
|
|
24
|
+
export default async function processTransaction(id, origin, pg = pgClients.client) {
|
|
25
|
+
if (!id) throw new Error('not enough params: id');
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
id: paymentId, user_id: userId, status: trxStatus, service,
|
|
29
|
+
} = pg.pk?.[table] ? await pg.query(`select ${pg.pk?.[table]} as id, * from ${table} where ${pg.pk?.[table]}=$1`, [id]).then(el => el.rows?.[0] || {}) : {};
|
|
30
|
+
|
|
31
|
+
if (!paymentId) {
|
|
32
|
+
throw new Error('payment not found');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!service) throw new Error('invalid payment: service required');
|
|
36
|
+
if (!controller[service]) { throw new Error('invalid params: service'); }
|
|
37
|
+
|
|
38
|
+
if (trxStatus === 'success') {
|
|
39
|
+
throw new Error('Transaction was already processed');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const result = await controller[service](id, origin);
|
|
43
|
+
|
|
44
|
+
const { status = 'error', err_description: err } = result || {};
|
|
45
|
+
|
|
46
|
+
if (status !== 'success') {
|
|
47
|
+
throw new Error(err || 'Помилка перевірки статусу платежу');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const balance = await pg.query(`select balance from ${table}
|
|
51
|
+
where user_id=$1
|
|
52
|
+
and status in ('success', 'error')
|
|
53
|
+
and balance is not null
|
|
54
|
+
order by created_at desc limit 1`, [userId]).then(el => el.rows?.[0]?.balance || 0);
|
|
55
|
+
|
|
56
|
+
const row = await dataUpdate({
|
|
57
|
+
table,
|
|
58
|
+
data: {
|
|
59
|
+
data: result,
|
|
60
|
+
status,
|
|
61
|
+
balance: +result.amount + +balance,
|
|
62
|
+
success_date: newDate(),
|
|
63
|
+
},
|
|
64
|
+
id,
|
|
65
|
+
uid: userId,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (process.env.NODE_ENV === 'test') {
|
|
69
|
+
console.info(`id:${id}, status: ${result.status}, before: ${balance || 0}, sum: ${+result.amount}, after: ${+result.amount + +balance}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return { ...row, balance: +result.amount + +balance };
|
|
73
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import config from '../../../../config.js';
|
|
1
2
|
import pgClients from '../../../plugins/pg/pgClients.js';
|
|
2
3
|
import dataUpdate from '../../../plugins/crud/dataUpdate.js';
|
|
3
4
|
|
|
4
|
-
import liqpayCheckStatus from '
|
|
5
|
+
import liqpayCheckStatus from '../../../plugins/payment/liqpay.checkStatus.js';
|
|
6
|
+
import monopayCheckStatus from '../../../plugins/payment/monopay.checkStatus.js';
|
|
7
|
+
import portmoneCheckStatus from '../../../plugins/payment/portmone.checkStatus.js';
|
|
5
8
|
|
|
6
9
|
const newDate = (dateNum) => {
|
|
7
10
|
const date = dateNum ? new Date(dateNum) : new Date();
|
|
@@ -10,6 +13,8 @@ const newDate = (dateNum) => {
|
|
|
10
13
|
return new Date(currentTimeWithTimezome).toISOString();
|
|
11
14
|
};
|
|
12
15
|
|
|
16
|
+
const { table = 'pay.transactions' } = config.integrations?.pay || {};
|
|
17
|
+
|
|
13
18
|
/**
|
|
14
19
|
* Апі для отримання інформації за ID
|
|
15
20
|
*
|
|
@@ -33,58 +38,56 @@ export default async function paymentInfo({
|
|
|
33
38
|
return reply.status(400).send('not enough query params: id');
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
const { rows = [] } = await pg.query(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
payment_status,
|
|
41
|
-
total_balance,
|
|
42
|
-
payment_num,
|
|
43
|
-
payment_service,
|
|
44
|
-
payment_data,
|
|
45
|
-
subscription_id
|
|
46
|
-
from billing.payments
|
|
47
|
-
where payment_id = $1
|
|
48
|
-
and account_id in (select account_id from billing.account_user where user_id = $2)`, [params.id, user.uid]);
|
|
41
|
+
const { rows = [] } = await pg.query(
|
|
42
|
+
`select ${pg.pk?.[table]} as id, * from ${table} where ${pg.pk?.[table]} = $1 and user_id = $2`,
|
|
43
|
+
[params.id, user.uid],
|
|
44
|
+
);
|
|
49
45
|
|
|
50
46
|
if (!rows.length) {
|
|
51
47
|
return reply.status(404).send('payment not found');
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
const {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
user_id: userId,
|
|
52
|
+
service,
|
|
53
|
+
status,
|
|
58
54
|
} = rows[0];
|
|
59
55
|
|
|
60
56
|
if (status !== 'success' && service === 'liqpay') {
|
|
61
|
-
const result = await liqpayCheckStatus(params.id);
|
|
57
|
+
const result = await liqpayCheckStatus({ id: params.id });
|
|
62
58
|
const { amount = 0 } = result;
|
|
63
59
|
|
|
64
|
-
const
|
|
65
|
-
where
|
|
66
|
-
and
|
|
67
|
-
and
|
|
68
|
-
order by
|
|
60
|
+
const balance = await pg.query(`select balance from ${table}
|
|
61
|
+
where user_id=$1
|
|
62
|
+
and status = 'success'
|
|
63
|
+
and balance is not null
|
|
64
|
+
order by created_at desc limit 1`, [userId]).then(el => el.rows?.[0]?.balance || 0);
|
|
69
65
|
|
|
70
66
|
const res = await dataUpdate({
|
|
71
67
|
pg,
|
|
72
|
-
table
|
|
68
|
+
table,
|
|
73
69
|
id: params.id,
|
|
74
70
|
data: {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
71
|
+
data: result,
|
|
72
|
+
status: 'success',
|
|
73
|
+
balance: +amount + +balance,
|
|
78
74
|
success_date: newDate(result.end_date),
|
|
79
75
|
},
|
|
80
76
|
uid: user?.uid,
|
|
81
77
|
});
|
|
82
78
|
|
|
83
|
-
// const res1 = await metaFormat({ rows: [res].filter(el => el), cls: { account_id: 'billing.account_id', payment_status: 'billing.payment_status', subscription_id: 'billing.subscription_id' } });
|
|
84
79
|
return res;
|
|
85
80
|
}
|
|
86
81
|
|
|
87
|
-
|
|
82
|
+
if (status !== 'success' && service === 'portmone' && false) {
|
|
83
|
+
const result = await portmoneCheckStatus({ id: params.id });
|
|
84
|
+
return; // !test
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (status !== 'success' && service === 'monopay' && false) {
|
|
88
|
+
const result = await monopayCheckStatus({ id: params.id });
|
|
89
|
+
return; // !test
|
|
90
|
+
}
|
|
88
91
|
|
|
89
92
|
return rows[0];
|
|
90
93
|
}
|
|
@@ -1,137 +1,47 @@
|
|
|
1
|
-
import request from 'request-promise';
|
|
2
|
-
import LiqPay from 'liqpayjs-sdk';
|
|
3
|
-
|
|
4
1
|
import config from '../../../../config.js';
|
|
5
2
|
import pgClients from '../../../plugins/pg/pgClients.js';
|
|
6
|
-
import dataInsert from '../../../plugins/crud/dataInsert.js';
|
|
7
|
-
import dataUpdate from '../../../plugins/crud/dataUpdate.js';
|
|
8
|
-
|
|
9
|
-
const { prefix = '/api' } = config;
|
|
10
|
-
|
|
11
|
-
const { publicKey, privateKey, paymentRedirect } = config.integrations?.liqpay || {};
|
|
12
|
-
const liqpay = new LiqPay(publicKey, privateKey);
|
|
13
3
|
|
|
14
|
-
|
|
4
|
+
import paymentInfo from '../../../plugins/payment/paymentInfo.js';
|
|
5
|
+
import createTransaction from '../../../plugins/payment/liqpay.createTransaction.js';
|
|
15
6
|
|
|
16
7
|
export default async function liqpayRedirect(req, reply) {
|
|
17
8
|
const {
|
|
18
|
-
pg = pgClients.client, query = {}, user = {},
|
|
9
|
+
hostname, headers, pg = pgClients.client, query = {}, user = {}, protocol,
|
|
19
10
|
} = req;
|
|
20
11
|
|
|
21
|
-
if (!
|
|
22
|
-
return reply.status(
|
|
12
|
+
if (!user?.uid) {
|
|
13
|
+
return reply.status(401).send('unauthorized');
|
|
23
14
|
}
|
|
24
15
|
|
|
25
|
-
const domain =
|
|
26
|
-
|
|
27
|
-
const paymentData = query.id ? await pg.query('select payment_id, account_id, payment_amount, payment_status from billing.payments where payment_id=$1', [query.id])
|
|
28
|
-
.then(el => el.rows?.[0] || {}) : {};
|
|
29
|
-
|
|
30
|
-
if (paymentData.payment_status && paymentData.payment_status === 'success') {
|
|
31
|
-
return { message: 'already processed', status: 400 };
|
|
32
|
-
}
|
|
16
|
+
const domain = hostname?.split?.(':')?.shift?.();
|
|
17
|
+
const rootUrl = `${protocol || 'https'}://${domain}`;
|
|
33
18
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
19
|
+
const paymentData = query.id ? await paymentInfo(query.id) : {
|
|
20
|
+
price: query.price, // price for new transtaction as is, else - preCreated
|
|
21
|
+
service: 'portmone',
|
|
22
|
+
referer: headers?.referer, // redirect user after finish of transaction
|
|
23
|
+
uid: user.uid, // user id
|
|
24
|
+
};
|
|
39
25
|
|
|
40
|
-
|
|
41
|
-
|
|
26
|
+
// redirect back from payment service to API endpoint, provide protocol + domain
|
|
27
|
+
Object.assign(paymentData, { rootUrl });
|
|
42
28
|
|
|
43
|
-
if (
|
|
44
|
-
return
|
|
29
|
+
if (query.id && paymentData.status === 'success') {
|
|
30
|
+
return reply.status(400).send('already processed');
|
|
45
31
|
}
|
|
46
32
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
table: 'billing.payments',
|
|
50
|
-
data: {
|
|
51
|
-
payment_amount: paymentAmount,
|
|
52
|
-
account_id: accountId,
|
|
53
|
-
payment_service: 'liqpay',
|
|
54
|
-
payment_status: 'inprogress',
|
|
55
|
-
},
|
|
56
|
-
uid: user?.uid || '0',
|
|
57
|
-
}).then(el => el.rows?.[0] || {})
|
|
58
|
-
: { payment_id: paymentData.payment_id };
|
|
59
|
-
|
|
60
|
-
if (!paymentId) {
|
|
61
|
-
return { message: 'payment not found', status: 404 };
|
|
33
|
+
if (!paymentData?.price) {
|
|
34
|
+
return reply.status(400).send('price is required');
|
|
62
35
|
}
|
|
63
36
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
id: paymentId,
|
|
67
|
-
data: {
|
|
68
|
-
referer_url: paymentRedirect ? paymentRedirect.replace(/{{id}}/g, paymentId) : headers?.referer,
|
|
69
|
-
payment_status: 'inprogress',
|
|
70
|
-
},
|
|
71
|
-
uid: user?.uid || '0',
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const protocol = headers?.referer?.split?.('://')?.shift?.() || req.protocol || 'https';
|
|
75
|
-
const rootPageUrl = `${protocol || 'https'}://${domain}`;
|
|
76
|
-
|
|
77
|
-
// redirect to api to check payment status and redirect user to page afterwards
|
|
78
|
-
const serverUrl = `${rootPageUrl}${prefix}/liqpay/${paymentId}/success`;
|
|
79
|
-
|
|
80
|
-
const paymentOptions = {
|
|
81
|
-
action: 'pay',
|
|
82
|
-
amount: paymentAmount,
|
|
83
|
-
currency: 'UAH',
|
|
84
|
-
description: 'regular payment',
|
|
85
|
-
order_id: paymentId,
|
|
86
|
-
version: '3',
|
|
87
|
-
// server_url: serverUrl, // update payment info - api url, does not work on sdk package out of the box
|
|
88
|
-
result_url: serverUrl, // redirect user after payment - page url
|
|
89
|
-
};
|
|
90
|
-
const { data, signature } = liqpay.cnb_object(paymentOptions) || {};
|
|
91
|
-
|
|
92
|
-
const logObj = {
|
|
93
|
-
type: 'redirect',
|
|
94
|
-
paymentId,
|
|
95
|
-
accountId,
|
|
96
|
-
price: paymentAmount,
|
|
97
|
-
service: 'liqpay',
|
|
98
|
-
domain,
|
|
99
|
-
paymentRedirectUrl: serverUrl,
|
|
100
|
-
serverUrl,
|
|
101
|
-
uid: user?.uid || '0',
|
|
102
|
-
};
|
|
37
|
+
// create if not exists, then request to payment service
|
|
38
|
+
const result = await createTransaction({ ...paymentData, debug: config.debug && query.debug }, pg);
|
|
103
39
|
|
|
40
|
+
// html
|
|
104
41
|
if (config.debug && query?.debug) {
|
|
105
|
-
|
|
106
|
-
return reply.status(302).headers({ 'Content-Type': 'text/html' }).send(html);
|
|
42
|
+
return reply.status(302).headers({ 'Content-Type': 'text/html' }).send(result);
|
|
107
43
|
}
|
|
108
44
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
url: `${host}/api/3/checkout`,
|
|
112
|
-
method: 'POST',
|
|
113
|
-
form: { data, signature },
|
|
114
|
-
followAllRedirects: false,
|
|
115
|
-
jar: true,
|
|
116
|
-
timeout: 6000,
|
|
117
|
-
simple: false, // prevent not 2xx code trigger catch
|
|
118
|
-
resolveWithFullResponse: true,
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
if (response.statusCode !== 302 || !response.headers?.location) {
|
|
122
|
-
throw new Error(response);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (response.headers?.location?.includes?.('throw_error')) {
|
|
126
|
-
throw new Error(response.headers?.location);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
Object.assign(logObj, { paymentId, redirect: response.headers?.location, status: 302 });
|
|
130
|
-
console.log('payments/info', JSON.stringify(logObj));
|
|
131
|
-
return reply.redirect(response.headers.location);
|
|
132
|
-
}
|
|
133
|
-
catch (err) {
|
|
134
|
-
console.error('payments/error', JSON.stringify(logObj), err.toString(), err.stack);
|
|
135
|
-
return reply.status(500).send(err.toString());
|
|
136
|
-
}
|
|
45
|
+
// link to payment service
|
|
46
|
+
return reply.redirect(result);
|
|
137
47
|
}
|