@cloudcommerce/app-pagarme-v5 0.32.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/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +230 -0
- package/README.md +1 -0
- package/assets/onload-expression.js +38 -0
- package/assets/onload-expression.min.js +1 -0
- package/events.js +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -0
- package/lib/pagarme-v5-events.d.ts +6 -0
- package/lib/pagarme-v5-events.js +21 -0
- package/lib/pagarme-v5-events.js.map +1 -0
- package/lib/pagarme-v5.d.ts +4 -0
- package/lib/pagarme-v5.js +12 -0
- package/lib/pagarme-v5.js.map +1 -0
- package/lib-mjs/create-pagarme5-transaction.mjs +208 -0
- package/lib-mjs/events-to-pagarme5.mjs +209 -0
- package/lib-mjs/functions-lib/api-utils.mjs +220 -0
- package/lib-mjs/functions-lib/firestore-utils.mjs +24 -0
- package/lib-mjs/functions-lib/pagarme/create-axios.mjs +12 -0
- package/lib-mjs/functions-lib/pagarme/handle-plans.mjs +69 -0
- package/lib-mjs/functions-lib/pagarme/parses-utils.mjs +61 -0
- package/lib-mjs/functions-lib/pagarme/payment-subscription.mjs +244 -0
- package/lib-mjs/functions-lib/payments/add-installments.mjs +45 -0
- package/lib-mjs/list-pagarme5-payments.mjs +218 -0
- package/lib-mjs/pagarme5-webhooks.mjs +343 -0
- package/package.json +38 -0
- package/scripts/build.sh +4 -0
- package/scripts/tests.sh +9 -0
- package/src/index.ts +1 -0
- package/src/pagarme-v5-events.ts +27 -0
- package/src/pagarme-v5.ts +12 -0
- package/tests/1-list-payments.test.mjs +37 -0
- package/tests/2-create-transaction.test.mjs +56 -0
- package/tsconfig.json +6 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import logger from 'firebase-functions/logger';
|
|
2
|
+
import axios from './create-axios.mjs';
|
|
3
|
+
import { parseAddress } from './parses-utils.mjs';
|
|
4
|
+
|
|
5
|
+
const paymentMethods = {
|
|
6
|
+
credit_card: 'credit_card',
|
|
7
|
+
banking_billet: 'boleto',
|
|
8
|
+
account_deposit: 'pix',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const parseIntervalPlan = {
|
|
12
|
+
// day, week, month ou year.
|
|
13
|
+
Diaria: {
|
|
14
|
+
interval: 'day',
|
|
15
|
+
interval_count: 1,
|
|
16
|
+
},
|
|
17
|
+
Semanal: {
|
|
18
|
+
interval: 'week',
|
|
19
|
+
interval_count: 1,
|
|
20
|
+
},
|
|
21
|
+
Mensal: {
|
|
22
|
+
interval: 'month',
|
|
23
|
+
interval_count: 1,
|
|
24
|
+
|
|
25
|
+
},
|
|
26
|
+
Bimestral: {
|
|
27
|
+
interval: 'month',
|
|
28
|
+
interval_count: 2,
|
|
29
|
+
},
|
|
30
|
+
Trimestral: {
|
|
31
|
+
interval: 'month',
|
|
32
|
+
interval_count: 3,
|
|
33
|
+
},
|
|
34
|
+
Semestral: {
|
|
35
|
+
interval: 'month',
|
|
36
|
+
interval_count: 6,
|
|
37
|
+
},
|
|
38
|
+
Anual: {
|
|
39
|
+
interval: 'year',
|
|
40
|
+
interval_count: 1,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const createSubscription = async (params, appData, storeId, plan, customer) => {
|
|
45
|
+
const pagarmeAxios = axios(appData.pagarme_api_token);
|
|
46
|
+
|
|
47
|
+
const orderId = params.order_id;
|
|
48
|
+
const { amount, items } = params;
|
|
49
|
+
|
|
50
|
+
const paymentMethod = paymentMethods[params.payment_method.code] || 'credit_card';
|
|
51
|
+
|
|
52
|
+
const intervalPlan = parseIntervalPlan[plan.periodicity];
|
|
53
|
+
|
|
54
|
+
const statementDescriptor = appData.soft_descriptor || params?.domain
|
|
55
|
+
.replace('www.', '')
|
|
56
|
+
.replace('https://', '')
|
|
57
|
+
.split('.')[0] || '*';
|
|
58
|
+
|
|
59
|
+
const pagarmeSubscription = {
|
|
60
|
+
code: orderId,
|
|
61
|
+
payment_method: paymentMethod,
|
|
62
|
+
currency: 'BRL',
|
|
63
|
+
interval: intervalPlan.interval || 'month',
|
|
64
|
+
interval_count: intervalPlan.interval_count || 1,
|
|
65
|
+
billing_type: 'prepaid', //
|
|
66
|
+
customer,
|
|
67
|
+
statement_descriptor: (`Assinatura ${statementDescriptor}`).substring(13),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
pagarmeSubscription.metada = {
|
|
71
|
+
order_number: params.order_number,
|
|
72
|
+
store_id: storeId,
|
|
73
|
+
order_id: orderId,
|
|
74
|
+
platform_integration: 'ecomplus',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
if (paymentMethod === 'credit_card') {
|
|
78
|
+
pagarmeSubscription.card_token = params.credit_card.hash;
|
|
79
|
+
const address = parseAddress(params.to || params.billing_address);
|
|
80
|
+
pagarmeSubscription.card = {
|
|
81
|
+
billing_address: address,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
pagarmeSubscription.discounts = [];
|
|
86
|
+
pagarmeSubscription.items = [];
|
|
87
|
+
|
|
88
|
+
items.forEach(async (item) => {
|
|
89
|
+
if (item.quantity > 0) {
|
|
90
|
+
const itemSubscription = {
|
|
91
|
+
name: item.name || item.variation_id || item.product_id,
|
|
92
|
+
quantity: item.quantity,
|
|
93
|
+
description: item.name || item.variation_id || item.product_id,
|
|
94
|
+
id: `pi_${item.sku}`,
|
|
95
|
+
status: 'active',
|
|
96
|
+
pricing_scheme: {
|
|
97
|
+
scheme_type: 'unit',
|
|
98
|
+
price: Math.floor((item.final_price || item.price) * 100),
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
// if the item is a bonus, create a discount for repeat one time
|
|
102
|
+
if (
|
|
103
|
+
item.flags && (item.flags.includes('freebie')
|
|
104
|
+
|| item.flags.includes('discount-set-free'))
|
|
105
|
+
) {
|
|
106
|
+
itemSubscription.cycles = 1;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
pagarmeSubscription.items.push(itemSubscription);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (amount.freight) {
|
|
114
|
+
const itemFreight = {
|
|
115
|
+
name: 'Frete',
|
|
116
|
+
quantity: 1,
|
|
117
|
+
description: 'Frete',
|
|
118
|
+
id: `pi_freight_${orderId}`,
|
|
119
|
+
status: 'active',
|
|
120
|
+
pricing_scheme: {
|
|
121
|
+
scheme_type: 'unit',
|
|
122
|
+
price: Math.floor((amount.freight).toFixed(2) * 1000) / 10,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
pagarmeSubscription.items.push(itemFreight);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// console.log('>> amount ', JSON.stringify(amount))
|
|
129
|
+
// Add once discont, but webhook invoce check discount plan
|
|
130
|
+
const discountSubscription = amount.discount && {
|
|
131
|
+
value: `${Math.floor((amount.discount).toFixed(2) * 1000) / 10}`,
|
|
132
|
+
discount_type: 'flat',
|
|
133
|
+
cycles: 1,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
if (discountSubscription) {
|
|
137
|
+
pagarmeSubscription.discounts.push(discountSubscription);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
logger.log('[PagarMe V5] Subscription: ', JSON.stringify(pagarmeSubscription));
|
|
141
|
+
|
|
142
|
+
return pagarmeAxios.post(
|
|
143
|
+
'/subscriptions',
|
|
144
|
+
pagarmeSubscription,
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const createPayment = async (params, appData, customer) => {
|
|
149
|
+
const pagarmeAxios = axios(appData.pagarme_api_token);
|
|
150
|
+
|
|
151
|
+
const { amount, items } = params;
|
|
152
|
+
|
|
153
|
+
const address = parseAddress(params.to || params.billing_address);
|
|
154
|
+
|
|
155
|
+
logger.log('[PagarMe V5] Try payment');
|
|
156
|
+
let discountEach;
|
|
157
|
+
if (amount.discount) {
|
|
158
|
+
const quantityItems = items.reduce((acumulador, item) => {
|
|
159
|
+
return acumulador + (item.quantity || 0);
|
|
160
|
+
}, 0);
|
|
161
|
+
discountEach = amount.discount / quantityItems;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const paymentMethod = paymentMethods[params.payment_method.code] || 'credit_card';
|
|
165
|
+
const methodConfig = appData[params.payment_method.code];
|
|
166
|
+
|
|
167
|
+
const statementDescriptor = appData.soft_descriptor || params?.domain
|
|
168
|
+
.replace('www.', '')
|
|
169
|
+
.replace('https://', '')
|
|
170
|
+
.split('.')[0] || '*';
|
|
171
|
+
|
|
172
|
+
const pagarmeOrder = { customer };
|
|
173
|
+
|
|
174
|
+
const phone = customer.phones[0];
|
|
175
|
+
if (amount.freight) {
|
|
176
|
+
pagarmeOrder.shipping = {
|
|
177
|
+
amount: Math.floor((amount.freight) * 100),
|
|
178
|
+
description: 'Frete',
|
|
179
|
+
recipient_name: customer.name,
|
|
180
|
+
recipient_phone: `${phone?.area_code || ''}${phone?.number}`,
|
|
181
|
+
address,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (params.browser_ip) {
|
|
186
|
+
pagarmeOrder.ip = params.browser_ip;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
pagarmeOrder.items = [];
|
|
190
|
+
|
|
191
|
+
items.forEach(async (item) => {
|
|
192
|
+
if (item.quantity > 0) {
|
|
193
|
+
const itemOrder = {
|
|
194
|
+
quantity: item.quantity,
|
|
195
|
+
description: item.name || item.variation_id || item.product_id,
|
|
196
|
+
code: item.sku || item.variation_id || item.product_id,
|
|
197
|
+
amount: Math.floor(((item.final_price || item.price) - (discountEach || 0)) * 100),
|
|
198
|
+
};
|
|
199
|
+
pagarmeOrder.items.push(itemOrder);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const payment = {
|
|
204
|
+
payment_method: paymentMethod,
|
|
205
|
+
amount: Math.floor((amount.total)) * 100,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
if (paymentMethod === 'credit_card') {
|
|
209
|
+
payment.credit_card = {
|
|
210
|
+
operation_type: 'auth_and_capture', // auth_only
|
|
211
|
+
installments: params.installments_number || 1,
|
|
212
|
+
statement_descriptor: statementDescriptor.substring(13),
|
|
213
|
+
card_token: params.credit_card.hash,
|
|
214
|
+
card: {
|
|
215
|
+
billing_address: address,
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
} else if (paymentMethod === 'pix') {
|
|
219
|
+
payment.pix = {
|
|
220
|
+
expires_in: (methodConfig.due_time || 60) * 60,
|
|
221
|
+
};
|
|
222
|
+
} else {
|
|
223
|
+
payment.boleto = {
|
|
224
|
+
due_at: new Date(new Date().getTime()
|
|
225
|
+
+ ((methodConfig.days_due_date || 1) * 24 * 60 * 60 * 1000)).toISOString(),
|
|
226
|
+
instructions: methodConfig.instructions || statementDescriptor,
|
|
227
|
+
billing_address: address,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
pagarmeOrder.payments = [payment];
|
|
232
|
+
|
|
233
|
+
logger.log('[PagarMe V5] Order PagarMe: ', JSON.stringify(pagarmeOrder));
|
|
234
|
+
|
|
235
|
+
return pagarmeAxios.post(
|
|
236
|
+
'/orders',
|
|
237
|
+
pagarmeOrder,
|
|
238
|
+
);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
export {
|
|
242
|
+
createSubscription,
|
|
243
|
+
createPayment,
|
|
244
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export default (amount, response, installments = {}, gateway = {}) => {
|
|
2
|
+
const maxInterestFree = installments.max_interest_free;
|
|
3
|
+
const minInstallment = installments.min_installment || 5;
|
|
4
|
+
const qtyPosssibleInstallment = Math.floor((amount.total / minInstallment));
|
|
5
|
+
const maxInstallments = installments.max_number
|
|
6
|
+
|| (qtyPosssibleInstallment < 12 ? qtyPosssibleInstallment : 12);
|
|
7
|
+
const monthlyInterest = installments.monthly_interest || 0;
|
|
8
|
+
|
|
9
|
+
if (maxInstallments > 1) {
|
|
10
|
+
if (response) {
|
|
11
|
+
response.installments_option = {
|
|
12
|
+
min_installment: minInstallment,
|
|
13
|
+
max_number: maxInterestFree > 1 ? maxInterestFree : maxInstallments,
|
|
14
|
+
monthly_interest: maxInterestFree > 1 ? 0 : monthlyInterest,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const isInterestFreeMinAmount = installments.interest_free_min_amount
|
|
19
|
+
&& amount.total >= (installments.interest_free_min_amount);
|
|
20
|
+
|
|
21
|
+
// list installment options
|
|
22
|
+
gateway.installment_options = [];
|
|
23
|
+
for (let number = 2; number <= maxInstallments; number++) {
|
|
24
|
+
const tax = !(maxInterestFree >= number);
|
|
25
|
+
let interest;
|
|
26
|
+
if (tax || !isInterestFreeMinAmount) {
|
|
27
|
+
interest = monthlyInterest / 100;
|
|
28
|
+
}
|
|
29
|
+
let value;
|
|
30
|
+
if ((!tax && isInterestFreeMinAmount) || !interest) {
|
|
31
|
+
value = amount.total / number;
|
|
32
|
+
} else {
|
|
33
|
+
value = amount.total * (interest / (1 - (1 + interest) ** -number));
|
|
34
|
+
}
|
|
35
|
+
if (value && value >= 1) {
|
|
36
|
+
gateway.installment_options.push({
|
|
37
|
+
number,
|
|
38
|
+
value,
|
|
39
|
+
tax: tax || !isInterestFreeMinAmount,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { response, gateway };
|
|
45
|
+
};
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import url from 'node:url';
|
|
4
|
+
import logger from 'firebase-functions/logger';
|
|
5
|
+
import api from '@cloudcommerce/api';
|
|
6
|
+
import addInstallments from './functions-lib/payments/add-installments.mjs';
|
|
7
|
+
import { discountPlanPayment } from './functions-lib/pagarme/handle-plans.mjs';
|
|
8
|
+
|
|
9
|
+
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
|
10
|
+
|
|
11
|
+
export default async (data) => {
|
|
12
|
+
const { application, params } = data;
|
|
13
|
+
const { items } = params;
|
|
14
|
+
|
|
15
|
+
const configApp = {
|
|
16
|
+
...application.data,
|
|
17
|
+
...application.hidden_data,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
if (!process.env.PAGARMEV5_PUBLIC_KEY) {
|
|
21
|
+
const pagarmePublicKey = configApp.pagarme_public_key;
|
|
22
|
+
if (pagarmePublicKey && typeof pagarmePublicKey === 'string') {
|
|
23
|
+
process.env.PAGARMEV5_PUBLIC_KEY = pagarmePublicKey;
|
|
24
|
+
} else {
|
|
25
|
+
logger.warn('Missing PAGARMEV5 PUBLIC KEY');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!process.env.PAGARMEV5_API_TOKEN) {
|
|
30
|
+
const pagarmeApiKey = configApp.pagarme_api_token;
|
|
31
|
+
if (pagarmeApiKey && typeof pagarmeApiKey === 'string') {
|
|
32
|
+
process.env.PAGARMEV5_API_TOKEN = pagarmeApiKey;
|
|
33
|
+
} else {
|
|
34
|
+
logger.warn('Missing PAGARMEV5 API TOKEN');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!process.env.PAGARMEV5_API_TOKEN || !process.env.PAGARMEV5_PUBLIC_KEY) {
|
|
39
|
+
return {
|
|
40
|
+
error: 'NO_PAGARMEV5_KEYS',
|
|
41
|
+
message: 'Chave de API e/ou criptografia não configurada (lojista deve configurar o aplicativo)',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const categoryIds = configApp.recurrency_category_ids;
|
|
46
|
+
let hasRecurrence = false;
|
|
47
|
+
let isAllRecurring = true;
|
|
48
|
+
|
|
49
|
+
if (categoryIds.length) {
|
|
50
|
+
try {
|
|
51
|
+
const { data: { result } } = await api.get('search/v1', {
|
|
52
|
+
limit: items.length,
|
|
53
|
+
params: {
|
|
54
|
+
_id: items.map((item) => item.product_id),
|
|
55
|
+
'categories._id': categoryIds,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
hasRecurrence = result.length > 0;
|
|
60
|
+
isAllRecurring = result.length === items.length;
|
|
61
|
+
} catch (err) {
|
|
62
|
+
logger.error(err);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const response = {
|
|
67
|
+
payment_gateways: [],
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const paymentTypes = [];
|
|
71
|
+
if ((isAllRecurring) && configApp.recurrence && configApp.recurrence.length
|
|
72
|
+
&& configApp.recurrence[0].label) {
|
|
73
|
+
paymentTypes.push('recurrence');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if ((!hasRecurrence) && (!configApp.credit_card.disable || !configApp.banking_billet.disable
|
|
77
|
+
|| !configApp.account_deposit.disable)) {
|
|
78
|
+
paymentTypes.push('payment');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// setup payment gateway objects
|
|
82
|
+
const intermediator = {
|
|
83
|
+
name: 'Pagar.me',
|
|
84
|
+
link: 'https://pagar.me/',
|
|
85
|
+
code: 'pagarme',
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const listPaymentMethod = ['credit_card', 'banking_billet'];
|
|
89
|
+
|
|
90
|
+
if (!configApp.account_deposit?.disable) {
|
|
91
|
+
listPaymentMethod.push('account_deposit');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
paymentTypes.forEach((type) => {
|
|
95
|
+
// At first the occurrence only with credit card
|
|
96
|
+
const isRecurrence = type === 'recurrence';
|
|
97
|
+
const plans = isRecurrence ? configApp.recurrence : ['single_payment'];
|
|
98
|
+
plans.forEach((plan) => {
|
|
99
|
+
listPaymentMethod.forEach((paymentMethod) => {
|
|
100
|
+
// console.log('>> List Payments ', type, ' ', plan, ' ', paymentMethod)
|
|
101
|
+
const amount = { ...params.amount } || {};
|
|
102
|
+
const isCreditCard = paymentMethod === 'credit_card';
|
|
103
|
+
const isPix = paymentMethod === 'account_deposit';
|
|
104
|
+
const methodConfig = configApp[paymentMethod] || {};
|
|
105
|
+
let methodEnable = isRecurrence ? methodConfig.enable_recurrence : !methodConfig.disable;
|
|
106
|
+
|
|
107
|
+
// Pix not active in recurrence
|
|
108
|
+
methodEnable = isPix && isRecurrence ? false : methodEnable;
|
|
109
|
+
|
|
110
|
+
const minAmount = methodConfig?.min_amount || 0;
|
|
111
|
+
const validateAmount = amount.total
|
|
112
|
+
? (amount.total >= minAmount) : true; // Workaround for showcase
|
|
113
|
+
if (methodEnable && validateAmount) {
|
|
114
|
+
let label = isRecurrence ? plan.label : methodConfig.label;
|
|
115
|
+
if (!label) {
|
|
116
|
+
if (isCreditCard) {
|
|
117
|
+
label = 'Cartão de crédito';
|
|
118
|
+
} else {
|
|
119
|
+
label = !isPix ? 'Boleto bancário' : 'Pix';
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const gateway = {
|
|
123
|
+
label,
|
|
124
|
+
icon: methodConfig.icon,
|
|
125
|
+
text: methodConfig.text,
|
|
126
|
+
payment_method: {
|
|
127
|
+
code: paymentMethod,
|
|
128
|
+
name: `${isRecurrence ? `Assinatura ${plan.periodicity} ` : ''}`
|
|
129
|
+
+ `${label} - ${intermediator.name}`,
|
|
130
|
+
},
|
|
131
|
+
type,
|
|
132
|
+
intermediator,
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
let discount;
|
|
136
|
+
if (isRecurrence) {
|
|
137
|
+
discount = discountPlanPayment(label, plan, amount);
|
|
138
|
+
} else {
|
|
139
|
+
discount = configApp.discount;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (discount) {
|
|
143
|
+
if (isRecurrence) {
|
|
144
|
+
gateway.discount = !plan.discount_first_installment?.disable
|
|
145
|
+
? plan.discount_first_installment : plan.discount;
|
|
146
|
+
gateway.discount.type = discount.discountOption.type;
|
|
147
|
+
response.discount_option = discount.discountOption;
|
|
148
|
+
} else if (discount[paymentMethod]) {
|
|
149
|
+
gateway.discount = {
|
|
150
|
+
apply_at: discount.apply_at,
|
|
151
|
+
type: discount.type,
|
|
152
|
+
value: discount.value,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// check amount value to apply discount
|
|
156
|
+
if (amount.total < (discount.min_amount || 0)) {
|
|
157
|
+
delete gateway.discount;
|
|
158
|
+
} else {
|
|
159
|
+
delete discount.min_amount;
|
|
160
|
+
|
|
161
|
+
// fix local amount object
|
|
162
|
+
const applyDiscount = discount.apply_at;
|
|
163
|
+
|
|
164
|
+
const maxDiscount = amount[applyDiscount || 'subtotal'];
|
|
165
|
+
let discountValue;
|
|
166
|
+
if (discount.type === 'percentage') {
|
|
167
|
+
discountValue = (maxDiscount * discount.value) / 100;
|
|
168
|
+
} else {
|
|
169
|
+
discountValue = discount.value;
|
|
170
|
+
if (discountValue > maxDiscount) {
|
|
171
|
+
discountValue = maxDiscount;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (discountValue) {
|
|
176
|
+
amount.discount = (amount.discount || 0) + discountValue;
|
|
177
|
+
amount.total -= discountValue;
|
|
178
|
+
if (amount.total < 0) {
|
|
179
|
+
amount.total = 0;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (response.discount_option) {
|
|
184
|
+
response.discount_option.min_amount = discount.min_amount;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (isCreditCard) {
|
|
190
|
+
if (!gateway.icon) {
|
|
191
|
+
// gateway.icon = `${hostingUri}/credit-card.png`;
|
|
192
|
+
}
|
|
193
|
+
// https://github.com/pagarme/pagarme-js
|
|
194
|
+
gateway.js_client = {
|
|
195
|
+
script_uri: 'https://checkout.pagar.me/v1/tokenizecard.js',
|
|
196
|
+
onload_expression: `window._pagarmeKey="${process.env.PAGARMEV5_PUBLIC_KEY}";`
|
|
197
|
+
+ fs.readFileSync(path.join(__dirname, '../assets/onload-expression.min.js'), 'utf8'),
|
|
198
|
+
cc_hash: {
|
|
199
|
+
function: '_pagarmeHash',
|
|
200
|
+
is_promise: true,
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
if (!isRecurrence) {
|
|
204
|
+
const { installments } = configApp;
|
|
205
|
+
if (installments) {
|
|
206
|
+
// list all installment options and default one
|
|
207
|
+
addInstallments(amount, response, installments, gateway);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
response.payment_gateways.push(gateway);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
return response;
|
|
218
|
+
};
|