@cloudcommerce/app-pagarme-v5 2.40.9 → 2.40.11
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/assets/onload-expression.js +16 -11
- package/assets/onload-expression.min.js +1 -1
- package/lib-mjs/create-pagarme5-transaction.mjs +41 -24
- package/lib-mjs/events-to-pagarme5.mjs +1 -2
- package/lib-mjs/functions-lib/api-utils.mjs +0 -4
- package/lib-mjs/functions-lib/pagarme/handle-plans.mjs +1 -2
- package/lib-mjs/functions-lib/pagarme/payment-subscription.mjs +62 -45
- package/lib-mjs/functions-lib/payments/add-installments.mjs +7 -6
- package/lib-mjs/list-pagarme5-payments.mjs +43 -38
- package/lib-mjs/pagarme5-webhook.mjs +0 -7
- package/package.json +6 -6
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
1
2
|
(function pagarmeOnload() {
|
|
2
3
|
const apiKey = window._pagarmeKey;
|
|
3
4
|
window._pagarmeHash = function pagarmeHash(cardClient) {
|
|
@@ -22,19 +23,23 @@
|
|
|
22
23
|
}),
|
|
23
24
|
},
|
|
24
25
|
)
|
|
25
|
-
.then(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
reject(err);
|
|
26
|
+
.then((resp) => {
|
|
27
|
+
return resp.json().catch(() => {
|
|
28
|
+
return resp.text();
|
|
29
|
+
});
|
|
30
|
+
})
|
|
31
|
+
.then((data) => {
|
|
32
|
+
if (data && data.id) {
|
|
33
|
+
resolve(data.id);
|
|
34
|
+
return null;
|
|
35
35
|
}
|
|
36
|
+
console.log(data);
|
|
37
|
+
throw new Error('Credencial inválida');
|
|
36
38
|
})
|
|
37
|
-
.catch(
|
|
39
|
+
.catch((err) => {
|
|
40
|
+
console.log(err);
|
|
41
|
+
reject(err);
|
|
42
|
+
});
|
|
38
43
|
});
|
|
39
44
|
};
|
|
40
45
|
}());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{let
|
|
1
|
+
(()=>{let o=window._pagarmeKey;window._pagarmeHash=function(a){return new Promise((n,r)=>{var e={number:a.number,holder_name:a.name,exp_month:a.month,exp_year:a.year,cvv:a.cvc};fetch("https://api.pagar.me/core/v5/tokens?appId="+o,{headers:{"Content-Type":"application/json"},method:"POST",body:JSON.stringify({type:"card",card:e})}).then(e=>e.json().catch(()=>e.text())).then(e=>{if(e&&e.id)return n(e.id),null;throw console.log(e),new Error("Credencial inválida")}).catch(e=>{console.log(e),r(e)})})}})();
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import logger from 'firebase-functions/logger';
|
|
2
2
|
import config from '@cloudcommerce/firebase/lib/config';
|
|
3
3
|
import { getFirestore } from 'firebase-admin/firestore';
|
|
4
|
+
import addInstallments from './functions-lib/payments/add-installments.mjs';
|
|
4
5
|
import { createSubscription, createPayment } from './functions-lib/pagarme/payment-subscription.mjs';
|
|
5
6
|
import { getPlanInTransction } from './functions-lib/pagarme/handle-plans.mjs';
|
|
6
7
|
import { parserInvoiceStatusToEcom, parseAddress } from './functions-lib/pagarme/parses-utils.mjs';
|
|
7
8
|
import axios from './functions-lib/pagarme/create-axios.mjs';
|
|
8
9
|
|
|
9
|
-
export default async (
|
|
10
|
+
export default async (modBody) => {
|
|
10
11
|
const colletionFirebase = getFirestore().collection('pagarmeV5Subscriptions');
|
|
11
12
|
|
|
12
|
-
const { params, application } =
|
|
13
|
+
const { params, application } = modBody;
|
|
13
14
|
|
|
14
|
-
const
|
|
15
|
+
const appData = { ...application.data, ...application.hidden_data };
|
|
15
16
|
|
|
16
17
|
if (!process.env.PAGARMEV5_API_TOKEN) {
|
|
17
|
-
const pagarmeApiToken =
|
|
18
|
+
const pagarmeApiToken = appData.pagarme_api_token;
|
|
18
19
|
if (pagarmeApiToken && typeof pagarmeApiToken === 'string') {
|
|
19
20
|
process.env.PAGARMEV5_API_TOKEN = pagarmeApiToken;
|
|
20
21
|
} else {
|
|
@@ -28,8 +29,7 @@ export default async (appData) => {
|
|
|
28
29
|
const orderId = params.order_id;
|
|
29
30
|
|
|
30
31
|
const { amount, to, buyer } = params;
|
|
31
|
-
logger.
|
|
32
|
-
logger.log(`[PagarMe V5] Type transaction ${params.type}`);
|
|
32
|
+
logger.info(`Transaction ${orderId} ${params.type}`);
|
|
33
33
|
|
|
34
34
|
const paymentMethod = params.payment_method.code;
|
|
35
35
|
|
|
@@ -73,27 +73,22 @@ export default async (appData) => {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
if (isRecurrence) {
|
|
76
|
-
const methodConfigName = params.payment_method.code === 'credit_card' ?
|
|
76
|
+
const methodConfigName = params.payment_method.code === 'credit_card' ? appData.credit_card.label : appData.banking_billet.label;
|
|
77
77
|
let labelPaymentGateway = params.payment_method.name.replace('- Pagar.me', '');
|
|
78
78
|
labelPaymentGateway = labelPaymentGateway.replace(methodConfigName, '');
|
|
79
79
|
|
|
80
|
-
const plan = getPlanInTransction(labelPaymentGateway,
|
|
80
|
+
const plan = getPlanInTransction(labelPaymentGateway, appData.recurrence);
|
|
81
81
|
const { data: subcription } = await createSubscription(
|
|
82
82
|
params,
|
|
83
|
-
|
|
83
|
+
appData,
|
|
84
84
|
storeId,
|
|
85
85
|
plan,
|
|
86
86
|
pagarMeCustomer,
|
|
87
87
|
);
|
|
88
|
-
logger.log(`[PagarMe V5] Response: ${JSON.stringify(subcription)}`);
|
|
89
88
|
subscriptionPagarmeId = subcription.id;
|
|
90
|
-
|
|
89
|
+
logger.info(`Subscription ${subscriptionPagarmeId} for ${orderId}`, { subcription });
|
|
91
90
|
const { data: { data: invoices } } = await pagarmeAxios.get(`/invoices?subscription_id=${subscriptionPagarmeId}`);
|
|
92
|
-
logger.log(`[PagarMe V5] Invoices: ${JSON.stringify(invoices)}`);
|
|
93
|
-
|
|
94
91
|
const { data: charge } = await pagarmeAxios.get(`/charges/${invoices[0].charge.id}`);
|
|
95
|
-
|
|
96
|
-
logger.log(`[PagarMe V5] Charge: ${JSON.stringify(charge)}`);
|
|
97
92
|
const transactionPagarme = charge.last_transaction;
|
|
98
93
|
|
|
99
94
|
transaction.status = {
|
|
@@ -103,7 +98,7 @@ export default async (appData) => {
|
|
|
103
98
|
|
|
104
99
|
transaction.intermediator = {
|
|
105
100
|
transaction_id: invoices[0].id,
|
|
106
|
-
transaction_code: `${
|
|
101
|
+
transaction_code: `${subscriptionPagarmeId || ''}`,
|
|
107
102
|
transaction_reference: `${transactionPagarme.acquirer_tid || ''}`,
|
|
108
103
|
};
|
|
109
104
|
|
|
@@ -116,7 +111,6 @@ export default async (appData) => {
|
|
|
116
111
|
transaction.payment_link = charge.last_transaction.url;
|
|
117
112
|
redirectToPayment = true;
|
|
118
113
|
}
|
|
119
|
-
// console.log('>> transaction ', JSON.stringify(transaction))
|
|
120
114
|
await colletionFirebase.doc(orderId)
|
|
121
115
|
.set({
|
|
122
116
|
status: subcription.status,
|
|
@@ -130,12 +124,31 @@ export default async (appData) => {
|
|
|
130
124
|
amount,
|
|
131
125
|
})
|
|
132
126
|
.catch(logger.error);
|
|
133
|
-
|
|
134
|
-
// logger.log('[PagarMe V5] Save Firebase');
|
|
135
127
|
} else {
|
|
136
128
|
// type payment
|
|
137
|
-
|
|
138
|
-
|
|
129
|
+
let installmentsNumber = params.installments_number;
|
|
130
|
+
let finalAmount = amount.total;
|
|
131
|
+
if (installmentsNumber > 1 && appData.installments) {
|
|
132
|
+
// list all installment options
|
|
133
|
+
const { gateway } = addInstallments(amount, appData.installments);
|
|
134
|
+
const installmentOption = gateway.installment_options
|
|
135
|
+
&& gateway.installment_options.find(({ number }) => number === installmentsNumber);
|
|
136
|
+
if (installmentOption) {
|
|
137
|
+
transaction.installments = installmentOption;
|
|
138
|
+
transaction.installments.total = installmentOption.number * installmentOption.value;
|
|
139
|
+
finalAmount = transaction.installments.total;
|
|
140
|
+
} else {
|
|
141
|
+
installmentsNumber = 1;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const { data: payment } = await createPayment({
|
|
145
|
+
storeId,
|
|
146
|
+
params,
|
|
147
|
+
appData,
|
|
148
|
+
customer: pagarMeCustomer,
|
|
149
|
+
finalAmount,
|
|
150
|
+
installmentsNumber,
|
|
151
|
+
});
|
|
139
152
|
const [charge] = payment.charges;
|
|
140
153
|
|
|
141
154
|
const transactionPagarme = charge.last_transaction;
|
|
@@ -180,15 +193,20 @@ export default async (appData) => {
|
|
|
180
193
|
transaction,
|
|
181
194
|
};
|
|
182
195
|
} catch (error) {
|
|
196
|
+
logger.warn(`Failed transaction for ${orderId}`, {
|
|
197
|
+
params,
|
|
198
|
+
appData,
|
|
199
|
+
body: error.config?.data,
|
|
200
|
+
response: error.response?.data,
|
|
201
|
+
status: error.response?.status,
|
|
202
|
+
});
|
|
183
203
|
logger.error(error);
|
|
184
|
-
// try to debug request error
|
|
185
204
|
const errCode = isRecurrence ? 'PAGARMEV5_SUBSCRIPTION_ERR' : 'PAGARMEV5_TRANSACTION_ERR';
|
|
186
205
|
let { message } = error;
|
|
187
206
|
const err = new Error(`${errCode}- ${orderId} => ${message}`);
|
|
188
207
|
if (error.response) {
|
|
189
208
|
const { status, data } = error.response;
|
|
190
209
|
if (status !== 401 && status !== 403) {
|
|
191
|
-
// err.payment = JSON.stringify(pagarmeTransaction)
|
|
192
210
|
err.status = status;
|
|
193
211
|
if (typeof data === 'object' && data) {
|
|
194
212
|
err.response = JSON.stringify(data);
|
|
@@ -199,7 +217,6 @@ export default async (appData) => {
|
|
|
199
217
|
message = data.errors[0].message;
|
|
200
218
|
}
|
|
201
219
|
}
|
|
202
|
-
// logger.error(err);
|
|
203
220
|
return {
|
|
204
221
|
error: errCode,
|
|
205
222
|
message,
|
|
@@ -31,10 +31,9 @@ const eventOrderCancelled = async (
|
|
|
31
31
|
logger.log('>> SUCESSS');
|
|
32
32
|
return null;
|
|
33
33
|
} catch (err) {
|
|
34
|
-
logger.error(
|
|
34
|
+
logger.error(err);
|
|
35
35
|
await api.patch(order._id, { status: 'open' })
|
|
36
36
|
.catch(logger.error);
|
|
37
|
-
|
|
38
37
|
return null;
|
|
39
38
|
}
|
|
40
39
|
} else {
|
|
@@ -154,10 +154,6 @@ const createNewOrderBasedOld = (oldOrder, plan, status, charge, subscriptionPaga
|
|
|
154
154
|
return api.post('orders', body);
|
|
155
155
|
};
|
|
156
156
|
|
|
157
|
-
// const updateOrder = async (orderId, body) => {
|
|
158
|
-
// return api.patch(`orders/${orderId}`, body);
|
|
159
|
-
// };
|
|
160
|
-
|
|
161
157
|
const getOrderWithQueryString = async (query) => {
|
|
162
158
|
const { data } = await api.get(`orders?${query}`);
|
|
163
159
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
const discountPlanPayment = (planName, plan, amount) => {
|
|
2
2
|
let discount;
|
|
3
3
|
// console.log('>>Plan ', plan)
|
|
4
|
-
if (plan.discount_first_installment
|
|
5
|
-
&& !plan.discount_first_installment.disable) {
|
|
4
|
+
if (plan.discount_first_installment?.value) {
|
|
6
5
|
discount = plan.discount_first_installment;
|
|
7
6
|
} else {
|
|
8
7
|
discount = plan.discount;
|
|
@@ -41,20 +41,23 @@ const parseIntervalPlan = {
|
|
|
41
41
|
},
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
+
const partnerId = '63e4f99a3d1a0f00192bd247';
|
|
45
|
+
|
|
44
46
|
const createSubscription = async (params, appData, storeId, plan, customer) => {
|
|
45
47
|
const pagarmeAxios = axios(appData.pagarme_api_token);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
const {
|
|
49
|
+
order_id: orderId,
|
|
50
|
+
amount,
|
|
51
|
+
items,
|
|
52
|
+
} = params;
|
|
50
53
|
const paymentMethod = paymentMethods[params.payment_method.code] || 'credit_card';
|
|
51
|
-
|
|
52
54
|
const intervalPlan = parseIntervalPlan[plan.periodicity];
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
const statementDescriptor = appData.soft_descriptor?.replace(/[^\w\s]/g, '')
|
|
56
|
+
|| params?.domain
|
|
57
|
+
.replace('www.', '')
|
|
58
|
+
.replace('https://', '')
|
|
59
|
+
.split('.')[0]
|
|
60
|
+
|| '*';
|
|
58
61
|
|
|
59
62
|
const pagarmeSubscription = {
|
|
60
63
|
code: orderId,
|
|
@@ -64,22 +67,29 @@ const createSubscription = async (params, appData, storeId, plan, customer) => {
|
|
|
64
67
|
interval_count: intervalPlan.interval_count || 1,
|
|
65
68
|
billing_type: 'prepaid', //
|
|
66
69
|
customer,
|
|
67
|
-
statement_descriptor: (`
|
|
70
|
+
statement_descriptor: (`ASS ${statementDescriptor}`).substring(0, 13),
|
|
68
71
|
};
|
|
69
72
|
|
|
70
|
-
pagarmeSubscription.
|
|
71
|
-
order_number: params.order_number
|
|
72
|
-
store_id: storeId
|
|
73
|
+
pagarmeSubscription.metadata = {
|
|
74
|
+
order_number: `${params.order_number}`,
|
|
75
|
+
store_id: `${storeId}`,
|
|
73
76
|
order_id: orderId,
|
|
74
77
|
platform_integration: 'ecomplus',
|
|
75
78
|
};
|
|
76
79
|
|
|
77
80
|
if (paymentMethod === 'credit_card') {
|
|
78
|
-
pagarmeSubscription.card_token = params.credit_card
|
|
81
|
+
pagarmeSubscription.card_token = params.credit_card?.hash;
|
|
79
82
|
const address = parseAddress(params.to || params.billing_address);
|
|
80
83
|
pagarmeSubscription.card = {
|
|
81
84
|
billing_address: address,
|
|
82
85
|
};
|
|
86
|
+
if (plan.installment_period) {
|
|
87
|
+
if (intervalPlan.interval === 'year') {
|
|
88
|
+
pagarmeSubscription.installments = 12;
|
|
89
|
+
} else {
|
|
90
|
+
pagarmeSubscription.installments = intervalPlan.interval_count || 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
83
93
|
}
|
|
84
94
|
|
|
85
95
|
pagarmeSubscription.discounts = [];
|
|
@@ -132,12 +142,11 @@ const createSubscription = async (params, appData, storeId, plan, customer) => {
|
|
|
132
142
|
discount_type: 'flat',
|
|
133
143
|
cycles: 1,
|
|
134
144
|
};
|
|
135
|
-
|
|
136
145
|
if (discountSubscription) {
|
|
137
146
|
pagarmeSubscription.discounts.push(discountSubscription);
|
|
138
147
|
}
|
|
139
|
-
|
|
140
|
-
logger.
|
|
148
|
+
pagarmeSubscription.service_referer_name = partnerId;
|
|
149
|
+
logger.info('Pagar.me subscription:', { pagarmeSubscription });
|
|
141
150
|
|
|
142
151
|
return pagarmeAxios.post(
|
|
143
152
|
'/subscriptions',
|
|
@@ -145,29 +154,29 @@ const createSubscription = async (params, appData, storeId, plan, customer) => {
|
|
|
145
154
|
);
|
|
146
155
|
};
|
|
147
156
|
|
|
148
|
-
const createPayment = async (
|
|
157
|
+
const createPayment = async ({
|
|
158
|
+
storeId,
|
|
159
|
+
params,
|
|
160
|
+
appData,
|
|
161
|
+
customer,
|
|
162
|
+
finalAmount,
|
|
163
|
+
installmentsNumber,
|
|
164
|
+
}) => {
|
|
149
165
|
const pagarmeAxios = axios(appData.pagarme_api_token);
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
166
|
+
const {
|
|
167
|
+
order_id: orderId,
|
|
168
|
+
amount,
|
|
169
|
+
items,
|
|
170
|
+
} = params;
|
|
153
171
|
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
172
|
const paymentMethod = paymentMethods[params.payment_method.code] || 'credit_card';
|
|
165
173
|
const methodConfig = appData[params.payment_method.code];
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
const statementDescriptor = appData.soft_descriptor?.replace(/[^\w\s]/g, '')
|
|
175
|
+
|| params?.domain
|
|
176
|
+
.replace('www.', '')
|
|
177
|
+
.replace('https://', '')
|
|
178
|
+
.split('.')[0]
|
|
179
|
+
|| '*';
|
|
171
180
|
|
|
172
181
|
const pagarmeOrder = { customer };
|
|
173
182
|
|
|
@@ -193,8 +202,8 @@ const createPayment = async (params, appData, customer) => {
|
|
|
193
202
|
const itemOrder = {
|
|
194
203
|
quantity: item.quantity,
|
|
195
204
|
description: item.name || item.variation_id || item.product_id,
|
|
196
|
-
code: item.sku || item.variation_id || item.product_id,
|
|
197
|
-
amount: Math.floor((
|
|
205
|
+
code: item.sku?.substring(0, 52) || item.variation_id || item.product_id,
|
|
206
|
+
amount: Math.floor((item.final_price || item.price) * 100),
|
|
198
207
|
};
|
|
199
208
|
pagarmeOrder.items.push(itemOrder);
|
|
200
209
|
}
|
|
@@ -202,18 +211,20 @@ const createPayment = async (params, appData, customer) => {
|
|
|
202
211
|
|
|
203
212
|
const payment = {
|
|
204
213
|
payment_method: paymentMethod,
|
|
205
|
-
amount: Math.floor(
|
|
214
|
+
amount: Math.floor(finalAmount * 100),
|
|
206
215
|
};
|
|
207
216
|
|
|
208
217
|
if (paymentMethod === 'credit_card') {
|
|
209
218
|
payment.credit_card = {
|
|
210
219
|
operation_type: 'auth_and_capture', // auth_only
|
|
211
|
-
installments:
|
|
212
|
-
statement_descriptor: statementDescriptor.substring(13),
|
|
213
|
-
card_token: params.credit_card
|
|
220
|
+
installments: installmentsNumber || 1,
|
|
221
|
+
statement_descriptor: statementDescriptor.substring(0, 13),
|
|
222
|
+
card_token: params.credit_card?.hash,
|
|
214
223
|
card: {
|
|
215
224
|
billing_address: address,
|
|
216
225
|
},
|
|
226
|
+
recurrence_model: installmentsNumber > 1 ? 'installment' : 'standing_order',
|
|
227
|
+
initiated_type: 'partial_shipment',
|
|
217
228
|
};
|
|
218
229
|
} else if (paymentMethod === 'pix') {
|
|
219
230
|
payment.pix = {
|
|
@@ -228,9 +239,15 @@ const createPayment = async (params, appData, customer) => {
|
|
|
228
239
|
};
|
|
229
240
|
}
|
|
230
241
|
|
|
242
|
+
pagarmeOrder.metadata = {
|
|
243
|
+
order_number: `${params.order_number}`,
|
|
244
|
+
store_id: `${storeId}`,
|
|
245
|
+
order_id: orderId,
|
|
246
|
+
platform_integration: 'ecomplus',
|
|
247
|
+
};
|
|
231
248
|
pagarmeOrder.payments = [payment];
|
|
232
|
-
|
|
233
|
-
logger.
|
|
249
|
+
pagarmeOrder.service_referer_name = partnerId;
|
|
250
|
+
logger.info('Pagar.me order:', { pagarmeOrder });
|
|
234
251
|
|
|
235
252
|
return pagarmeAxios.post(
|
|
236
253
|
'/orders',
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export default (amount, response, installments = {}, gateway = {}) => {
|
|
2
|
+
const interestFreeMinAmount = installments.interest_free_min_amount || 5;
|
|
2
3
|
const maxInterestFree = installments.max_interest_free;
|
|
3
4
|
const minInstallment = installments.min_installment || 5;
|
|
4
5
|
const qtyPosssibleInstallment = Math.floor((amount.total / minInstallment));
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
let maxInstallments = installments.max_number || 12;
|
|
7
|
+
if (qtyPosssibleInstallment < maxInstallments) {
|
|
8
|
+
maxInstallments = qtyPosssibleInstallment;
|
|
9
|
+
}
|
|
7
10
|
const monthlyInterest = installments.monthly_interest || 0;
|
|
8
11
|
|
|
9
12
|
if (maxInstallments > 1) {
|
|
@@ -14,10 +17,8 @@ export default (amount, response, installments = {}, gateway = {}) => {
|
|
|
14
17
|
monthly_interest: maxInterestFree > 1 ? 0 : monthlyInterest,
|
|
15
18
|
};
|
|
16
19
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
&& amount.total >= (installments.interest_free_min_amount);
|
|
20
|
-
|
|
20
|
+
const isInterestFreeMinAmount = interestFreeMinAmount
|
|
21
|
+
&& amount.total >= interestFreeMinAmount;
|
|
21
22
|
// list installment options
|
|
22
23
|
gateway.installment_options = [];
|
|
23
24
|
for (let number = 2; number <= maxInstallments; number++) {
|
|
@@ -25,7 +25,6 @@ export default async (data) => {
|
|
|
25
25
|
logger.warn('Missing PAGARMEV5 PUBLIC KEY');
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
|
|
29
28
|
if (!process.env.PAGARMEV5_API_TOKEN) {
|
|
30
29
|
const pagarmeApiKey = configApp.pagarme_api_token;
|
|
31
30
|
if (pagarmeApiKey && typeof pagarmeApiKey === 'string') {
|
|
@@ -34,7 +33,6 @@ export default async (data) => {
|
|
|
34
33
|
logger.warn('Missing PAGARMEV5 API TOKEN');
|
|
35
34
|
}
|
|
36
35
|
}
|
|
37
|
-
|
|
38
36
|
if (!process.env.PAGARMEV5_API_TOKEN || !process.env.PAGARMEV5_PUBLIC_KEY) {
|
|
39
37
|
return {
|
|
40
38
|
error: 'NO_PAGARMEV5_KEYS',
|
|
@@ -46,7 +44,7 @@ export default async (data) => {
|
|
|
46
44
|
let hasRecurrence = false;
|
|
47
45
|
let isAllRecurring = true;
|
|
48
46
|
|
|
49
|
-
if (categoryIds
|
|
47
|
+
if (categoryIds?.length) {
|
|
50
48
|
try {
|
|
51
49
|
const { data: { result } } = await api.get('search/v1', {
|
|
52
50
|
limit: items.length,
|
|
@@ -55,7 +53,6 @@ export default async (data) => {
|
|
|
55
53
|
'categories._id': categoryIds,
|
|
56
54
|
},
|
|
57
55
|
});
|
|
58
|
-
|
|
59
56
|
hasRecurrence = result.length > 0;
|
|
60
57
|
isAllRecurring = result.length === items.length;
|
|
61
58
|
} catch (err) {
|
|
@@ -66,15 +63,15 @@ export default async (data) => {
|
|
|
66
63
|
const response = {
|
|
67
64
|
payment_gateways: [],
|
|
68
65
|
};
|
|
69
|
-
|
|
70
66
|
const paymentTypes = [];
|
|
71
|
-
if (
|
|
72
|
-
&& configApp.recurrence[0].label) {
|
|
67
|
+
if (configApp.recurrence?.[0]?.label && isAllRecurring) {
|
|
73
68
|
paymentTypes.push('recurrence');
|
|
74
69
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
if (
|
|
71
|
+
!hasRecurrence
|
|
72
|
+
&& (!configApp.credit_card.disable
|
|
73
|
+
|| !configApp.banking_billet.disable || !configApp.account_deposit.disable)
|
|
74
|
+
) {
|
|
78
75
|
paymentTypes.push('payment');
|
|
79
76
|
}
|
|
80
77
|
|
|
@@ -97,19 +94,18 @@ export default async (data) => {
|
|
|
97
94
|
const plans = isRecurrence ? configApp.recurrence : ['single_payment'];
|
|
98
95
|
plans.forEach((plan) => {
|
|
99
96
|
listPaymentMethod.forEach((paymentMethod) => {
|
|
100
|
-
// console.log('>> List Payments ', type, ' ', plan, ' ', paymentMethod)
|
|
101
97
|
const amount = { ...params.amount } || {};
|
|
102
98
|
const isCreditCard = paymentMethod === 'credit_card';
|
|
103
99
|
const isPix = paymentMethod === 'account_deposit';
|
|
104
100
|
const methodConfig = configApp[paymentMethod] || {};
|
|
105
|
-
let methodEnable =
|
|
106
|
-
|
|
101
|
+
let methodEnable = !methodConfig.disable;
|
|
102
|
+
if (isRecurrence) {
|
|
103
|
+
methodEnable = methodConfig.enable_recurrence;
|
|
104
|
+
}
|
|
107
105
|
// Pix not active in recurrence
|
|
108
106
|
methodEnable = isPix && isRecurrence ? false : methodEnable;
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
const validateAmount = amount.total
|
|
112
|
-
? (amount.total >= minAmount) : true; // Workaround for showcase
|
|
107
|
+
const minAmount = (isRecurrence ? plan?.min_amount : methodConfig?.min_amount) || 0;
|
|
108
|
+
const validateAmount = amount.subtotal ? (amount.subtotal >= minAmount) : true;
|
|
113
109
|
if (methodEnable && validateAmount) {
|
|
114
110
|
let label = isRecurrence ? plan.label : methodConfig.label;
|
|
115
111
|
if (!label) {
|
|
@@ -119,10 +115,10 @@ export default async (data) => {
|
|
|
119
115
|
label = !isPix ? 'Boleto bancário' : 'Pix';
|
|
120
116
|
}
|
|
121
117
|
}
|
|
118
|
+
|
|
122
119
|
const gateway = {
|
|
123
120
|
label,
|
|
124
121
|
icon: methodConfig.icon,
|
|
125
|
-
text: methodConfig.text,
|
|
126
122
|
payment_method: {
|
|
127
123
|
code: paymentMethod,
|
|
128
124
|
name: `${isRecurrence ? `Assinatura ${plan.periodicity} ` : ''}`
|
|
@@ -131,7 +127,9 @@ export default async (data) => {
|
|
|
131
127
|
type,
|
|
132
128
|
intermediator,
|
|
133
129
|
};
|
|
134
|
-
|
|
130
|
+
if (!isRecurrence && methodConfig.text) {
|
|
131
|
+
gateway.text = methodConfig.text;
|
|
132
|
+
}
|
|
135
133
|
let discount;
|
|
136
134
|
if (isRecurrence) {
|
|
137
135
|
discount = discountPlanPayment(label, plan, amount);
|
|
@@ -141,22 +139,33 @@ export default async (data) => {
|
|
|
141
139
|
|
|
142
140
|
if (discount) {
|
|
143
141
|
if (isRecurrence) {
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
if (plan.discount_first_installment?.value) {
|
|
143
|
+
gateway.discount = plan.discount_first_installment;
|
|
144
|
+
} else {
|
|
145
|
+
gateway.discount = plan.discount;
|
|
146
|
+
}
|
|
147
|
+
|
|
146
148
|
gateway.discount.type = discount.discountOption.type;
|
|
147
|
-
response.discount_option = discount.discountOption
|
|
149
|
+
// response.discount_option = discount.discountOption
|
|
148
150
|
} else if (discount[paymentMethod]) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
if (discount.apply_at !== 'freight') {
|
|
152
|
+
// default discount option
|
|
153
|
+
response.discount_option = {
|
|
154
|
+
label: configApp.discount_option_label || gateway.label,
|
|
155
|
+
min_amount: discount.min_amount,
|
|
156
|
+
apply_at: discount.apply_at,
|
|
157
|
+
type: discount.type,
|
|
158
|
+
value: discount.value,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
154
161
|
|
|
155
162
|
// check amount value to apply discount
|
|
156
|
-
if (amount.total <
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
if (!(amount.total < discount.min_amount)) {
|
|
164
|
+
gateway.discount = {
|
|
165
|
+
apply_at: discount.apply_at,
|
|
166
|
+
type: discount.type,
|
|
167
|
+
value: discount.value,
|
|
168
|
+
};
|
|
160
169
|
|
|
161
170
|
// fix local amount object
|
|
162
171
|
const applyDiscount = discount.apply_at;
|
|
@@ -164,14 +173,13 @@ export default async (data) => {
|
|
|
164
173
|
const maxDiscount = amount[applyDiscount || 'subtotal'];
|
|
165
174
|
let discountValue;
|
|
166
175
|
if (discount.type === 'percentage') {
|
|
167
|
-
discountValue =
|
|
176
|
+
discountValue = maxDiscount * (discount.value / 100);
|
|
168
177
|
} else {
|
|
169
178
|
discountValue = discount.value;
|
|
170
179
|
if (discountValue > maxDiscount) {
|
|
171
180
|
discountValue = maxDiscount;
|
|
172
181
|
}
|
|
173
182
|
}
|
|
174
|
-
|
|
175
183
|
if (discountValue) {
|
|
176
184
|
amount.discount = (amount.discount || 0) + discountValue;
|
|
177
185
|
amount.total -= discountValue;
|
|
@@ -180,15 +188,12 @@ export default async (data) => {
|
|
|
180
188
|
}
|
|
181
189
|
}
|
|
182
190
|
}
|
|
183
|
-
if (response.discount_option) {
|
|
184
|
-
response.discount_option.min_amount = discount.min_amount;
|
|
185
|
-
}
|
|
186
191
|
}
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
if (isCreditCard) {
|
|
190
195
|
if (!gateway.icon) {
|
|
191
|
-
|
|
196
|
+
gateway.icon = 'https://ecom-pagarme5.web.app/credit-card.png';
|
|
192
197
|
}
|
|
193
198
|
// https://github.com/pagarme/pagarme-js
|
|
194
199
|
gateway.js_client = {
|
|
@@ -204,7 +209,7 @@ export default async (data) => {
|
|
|
204
209
|
const { installments } = configApp;
|
|
205
210
|
if (installments) {
|
|
206
211
|
// list all installment options and default one
|
|
207
|
-
addInstallments(amount,
|
|
212
|
+
addInstallments(amount, installments, gateway, response);
|
|
208
213
|
}
|
|
209
214
|
}
|
|
210
215
|
}
|
|
@@ -165,12 +165,10 @@ const handleWehook = async (req, res) => {
|
|
|
165
165
|
return res.status(!subscription ? 404 : 400)
|
|
166
166
|
.send({ message: !subscription ? 'Not found subscription' : 'Subscription not canceled' });
|
|
167
167
|
} else if (type.startsWith('charge.')) {
|
|
168
|
-
// const statusChange = type.replace('charge.', '')
|
|
169
168
|
const { data: charge } = await pagarmeAxios.get(`/charges/${body.data.id}`);
|
|
170
169
|
logger.log('>> Charge ', JSON.stringify(charge));
|
|
171
170
|
if (charge.invoice) {
|
|
172
171
|
const { invoice, status } = charge;
|
|
173
|
-
logger.log('>>Parse status: ', parserChangeStatusToEcom(status));
|
|
174
172
|
const order = await getOrderIntermediatorTransactionId(invoice.id);
|
|
175
173
|
if (order) {
|
|
176
174
|
if (order.financial_status.current !== parserChangeStatusToEcom(status)) {
|
|
@@ -179,7 +177,6 @@ const handleWehook = async (req, res) => {
|
|
|
179
177
|
.find(
|
|
180
178
|
(transactionFind) => transactionFind.intermediator.transaction_id === invoice.id,
|
|
181
179
|
);
|
|
182
|
-
logger.log('>> Try add payment history');
|
|
183
180
|
const transactionPagarme = charge.last_transaction;
|
|
184
181
|
let notificationCode = `${type};${body.id};`;
|
|
185
182
|
if (transactionPagarme.transaction_type === 'credit_card') {
|
|
@@ -260,7 +257,6 @@ const handleWehook = async (req, res) => {
|
|
|
260
257
|
}
|
|
261
258
|
|
|
262
259
|
if (charge.order) {
|
|
263
|
-
// TODO:
|
|
264
260
|
// payment update (order in pagarme)
|
|
265
261
|
logger.log('>> Try update status order');
|
|
266
262
|
const { order: orderPagarme, status } = charge;
|
|
@@ -273,9 +269,7 @@ const handleWehook = async (req, res) => {
|
|
|
273
269
|
const transaction = order.transactions.find(
|
|
274
270
|
(transactionFind) => transactionFind.intermediator.transaction_id === orderPagarme.id,
|
|
275
271
|
);
|
|
276
|
-
// console.log('>> Try add payment history')
|
|
277
272
|
const transactionPagarme = charge.last_transaction;
|
|
278
|
-
// console.log('>>> TransactionPagarme ', JSON.stringify(transactionPagarme))
|
|
279
273
|
let notificationCode = `${type};${body.id};`;
|
|
280
274
|
if (transactionPagarme.transaction_type === 'credit_card') {
|
|
281
275
|
notificationCode += `${transactionPagarme.gateway_id || ''};`;
|
|
@@ -303,7 +297,6 @@ const handleWehook = async (req, res) => {
|
|
|
303
297
|
}
|
|
304
298
|
await addPaymentHistory(order._id, bodyPaymentHistory);
|
|
305
299
|
if (isUpdateTransaction && transaction._id) {
|
|
306
|
-
// console.log('>> Try Update transaction ')
|
|
307
300
|
await updateTransaction(order._id, transactionBody, transaction._id)
|
|
308
301
|
.catch(logger.error);
|
|
309
302
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/app-pagarme-v5",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.40.
|
|
4
|
+
"version": "2.40.11",
|
|
5
5
|
"description": "e-com.plus Cloud Commerce app to integrate Pagar.me API v5 with recurring payments",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"homepage": "https://github.com/ecomplus/cloud-commerce/tree/main/packages/apps/pagarme-v5#readme",
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@ecomplus/utils": "1.5.0-rc.6",
|
|
31
|
-
"axios": "^1.8.
|
|
31
|
+
"axios": "^1.8.4",
|
|
32
32
|
"firebase-admin": "^13.2.0",
|
|
33
33
|
"firebase-functions": "^6.3.2",
|
|
34
|
-
"@cloudcommerce/
|
|
35
|
-
"@cloudcommerce/
|
|
34
|
+
"@cloudcommerce/api": "2.40.11",
|
|
35
|
+
"@cloudcommerce/firebase": "2.40.11"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@cloudcommerce/test-base": "2.40.
|
|
39
|
-
"@cloudcommerce/types": "2.40.
|
|
38
|
+
"@cloudcommerce/test-base": "2.40.11",
|
|
39
|
+
"@cloudcommerce/types": "2.40.11"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "bash scripts/build.sh",
|