cloudcommerce 2.11.2 → 2.12.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/ecomplus-stores/barradoce/functions/many/package.json +3 -3
  3. package/ecomplus-stores/barradoce/functions/ssr/content/pages/home.json +50 -86
  4. package/ecomplus-stores/barradoce/functions/ssr/package.json +6 -6
  5. package/ecomplus-stores/barradoce/functions/ssr/public/img/uploads/banner-pistache.jpg +0 -0
  6. package/ecomplus-stores/barradoce/functions/ssr/src/components/Banner.vue +7 -8
  7. package/ecomplus-stores/barradoce/functions/with-apps/package.json +3 -3
  8. package/ecomplus-stores/barradoce/package.json +2 -2
  9. package/package.json +2 -2
  10. package/packages/__skeleton/package.json +2 -1
  11. package/packages/api/package.json +2 -2
  12. package/packages/apps/affiliate-program/package.json +2 -2
  13. package/packages/apps/correios/package.json +2 -2
  14. package/packages/apps/custom-payment/package.json +2 -2
  15. package/packages/apps/custom-shipping/package.json +2 -2
  16. package/packages/apps/datafrete/package.json +2 -2
  17. package/packages/apps/discounts/package.json +2 -2
  18. package/packages/apps/emails/package.json +2 -2
  19. package/packages/apps/fb-conversions/package.json +2 -2
  20. package/packages/apps/flash-courier/package.json +2 -2
  21. package/packages/apps/frenet/package.json +2 -2
  22. package/packages/apps/galaxpay/package.json +3 -2
  23. package/packages/apps/google-analytics/package.json +2 -2
  24. package/packages/apps/jadlog/package.json +2 -2
  25. package/packages/apps/loyalty-points/package.json +2 -2
  26. package/packages/apps/mandae/package.json +2 -2
  27. package/packages/apps/melhor-envio/package.json +2 -2
  28. package/packages/apps/mercadopago/package.json +3 -2
  29. package/packages/apps/pagaleve/CHANGELOG.md +1 -0
  30. package/packages/apps/pagaleve/README.md +1 -0
  31. package/packages/apps/pagaleve/lib/index.d.ts +1 -0
  32. package/packages/apps/pagaleve/lib/index.js +3 -0
  33. package/packages/apps/pagaleve/lib/index.js.map +1 -0
  34. package/packages/apps/pagaleve/lib/pagaleve-constructor.d.ts +7 -0
  35. package/packages/apps/pagaleve/lib/pagaleve-constructor.js +78 -0
  36. package/packages/apps/pagaleve/lib/pagaleve-constructor.js.map +1 -0
  37. package/packages/apps/pagaleve/lib/pagaleve-create-transaction.d.ts +7 -0
  38. package/packages/apps/pagaleve/lib/pagaleve-create-transaction.js +148 -0
  39. package/packages/apps/pagaleve/lib/pagaleve-create-transaction.js.map +1 -0
  40. package/packages/apps/pagaleve/lib/pagaleve-list-payments.d.ts +7 -0
  41. package/packages/apps/pagaleve/lib/pagaleve-list-payments.js +113 -0
  42. package/packages/apps/pagaleve/lib/pagaleve-list-payments.js.map +1 -0
  43. package/packages/apps/pagaleve/lib/pagaleve-webhook.d.ts +4 -0
  44. package/packages/apps/pagaleve/lib/pagaleve-webhook.js +135 -0
  45. package/packages/apps/pagaleve/lib/pagaleve-webhook.js.map +1 -0
  46. package/packages/apps/pagaleve/lib/pagaleve.d.ts +12 -0
  47. package/packages/apps/pagaleve/lib/pagaleve.js +12 -0
  48. package/packages/apps/pagaleve/lib/pagaleve.js.map +1 -0
  49. package/packages/apps/pagaleve/package.json +43 -0
  50. package/packages/apps/pagaleve/src/index.ts +2 -0
  51. package/packages/apps/pagaleve/src/pagaleve-constructor.ts +85 -0
  52. package/packages/apps/pagaleve/src/pagaleve-create-transaction.ts +161 -0
  53. package/packages/apps/pagaleve/src/pagaleve-list-payments.ts +122 -0
  54. package/packages/apps/pagaleve/src/pagaleve-webhook.ts +150 -0
  55. package/packages/apps/pagaleve/src/pagaleve.ts +12 -0
  56. package/packages/apps/pagaleve/tsconfig.json +6 -0
  57. package/packages/apps/pagaleve/webhook.js +1 -0
  58. package/packages/apps/pagarme/package.json +3 -2
  59. package/packages/apps/pagarme-v5/package.json +3 -2
  60. package/packages/apps/paghiper/package.json +2 -2
  61. package/packages/apps/pix/package.json +2 -2
  62. package/packages/apps/tiny-erp/package.json +2 -2
  63. package/packages/apps/webhooks/package.json +2 -2
  64. package/packages/cli/package.json +2 -2
  65. package/packages/config/package.json +2 -2
  66. package/packages/emails/package.json +2 -2
  67. package/packages/eslint/package.json +2 -2
  68. package/packages/events/lib/firebase.js +2 -0
  69. package/packages/events/lib/firebase.js.map +1 -1
  70. package/packages/events/package.json +3 -2
  71. package/packages/events/src/firebase.ts +2 -0
  72. package/packages/feeds/package.json +2 -2
  73. package/packages/firebase/lib/config.d.ts +3 -0
  74. package/packages/firebase/lib/config.js +3 -0
  75. package/packages/firebase/lib/config.js.map +1 -1
  76. package/packages/firebase/package.json +2 -2
  77. package/packages/firebase/src/config.ts +3 -0
  78. package/packages/i18n/package.json +2 -2
  79. package/packages/modules/lib/firebase/call-app-module.js +12 -0
  80. package/packages/modules/lib/firebase/call-app-module.js.map +1 -1
  81. package/packages/modules/package.json +3 -2
  82. package/packages/modules/src/firebase/call-app-module.ts +12 -0
  83. package/packages/passport/lib/firebase.js +20 -22
  84. package/packages/passport/lib/firebase.js.map +1 -1
  85. package/packages/passport/package.json +2 -2
  86. package/packages/passport/src/firebase.ts +25 -25
  87. package/packages/ssr/package.json +2 -2
  88. package/packages/storefront/package.json +2 -2
  89. package/packages/test-base/package.json +2 -2
  90. package/packages/types/package.json +2 -2
  91. package/ecomplus-stores/barradoce/functions/ssr/public/img/uploads/banner-forma-decora.jpg +0 -0
@@ -0,0 +1,85 @@
1
+ import type { AxiosInstance } from 'axios';
2
+ import axios from 'axios';
3
+ import { getFirestore, Timestamp } from 'firebase-admin/firestore';
4
+ import logger from 'firebase-functions/logger';
5
+
6
+ const createAxios = (token?: string | null, isSandbox = false) => {
7
+ const headers = {
8
+ 'Content-Type': 'application/json',
9
+ 'Idempotency-Key': `${Date.now() + Math.random()}`,
10
+ Authorization: token,
11
+ };
12
+ const baseURL = isSandbox
13
+ ? 'https://sandbox-api.pagaleve.io'
14
+ : 'https://api.pagaleve.com.br';
15
+ return axios.create({
16
+ baseURL,
17
+ headers,
18
+ validateStatus(status) {
19
+ return status >= 200 && status <= 301;
20
+ },
21
+ });
22
+ };
23
+
24
+ const createToken = (username: string, password: string, isSandbox = false) => {
25
+ return new Promise((resolve, reject) => {
26
+ // https://api-docs.addi-staging-br.com/#/Authentication/createAuthToken
27
+ const pagaleveAxios = createAxios(null, isSandbox);
28
+ const request = (isRetry = false) => {
29
+ pagaleveAxios.post('/v1/authentication', { username, password })
30
+ .then(({ data }) => resolve(data))
31
+ .catch((err) => {
32
+ if (!isRetry && err.response && err.response.status >= 429) {
33
+ setTimeout(() => request(true), 7000);
34
+ }
35
+ reject(err);
36
+ });
37
+ };
38
+ request();
39
+ });
40
+ };
41
+
42
+ const Pagaleve = function newPagaleve(
43
+ this: { preparing: Promise<void>, axios: AxiosInstance },
44
+ username: string,
45
+ password: string,
46
+ isSandbox = false,
47
+ ) {
48
+ const self = this;
49
+ const documentRef = getFirestore().doc('pagaleve/token');
50
+ this.preparing = new Promise((resolve, reject) => {
51
+ const authenticate = (token: string) => {
52
+ self.axios = createAxios(token, isSandbox);
53
+ resolve();
54
+ };
55
+ const handleAuth = () => {
56
+ createToken(username, password, isSandbox)
57
+ .then((data: any) => {
58
+ authenticate(data.token);
59
+ if (documentRef) {
60
+ documentRef.set({
61
+ ...data,
62
+ isSandbox,
63
+ updatedAt: Timestamp.now(),
64
+ }).catch(logger.error);
65
+ }
66
+ })
67
+ .catch(reject);
68
+ };
69
+ documentRef.get()
70
+ .then((documentSnapshot) => {
71
+ const data = documentSnapshot.data();
72
+ if (data) {
73
+ const updatedAt = (data.updatedAt as Timestamp).toMillis();
74
+ if (updatedAt && Date.now() - updatedAt <= 50 * 60 * 1000) {
75
+ authenticate(data!.token);
76
+ return;
77
+ }
78
+ }
79
+ handleAuth();
80
+ })
81
+ .catch(logger.error);
82
+ });
83
+ };
84
+
85
+ export default Pagaleve;
@@ -0,0 +1,161 @@
1
+ import type {
2
+ AppModuleBody,
3
+ CreateTransactionResponse,
4
+ } from '@cloudcommerce/types';
5
+ import { createHmac } from 'node:crypto';
6
+ import logger from 'firebase-functions/logger';
7
+ import { img as getImg } from '@ecomplus/utils';
8
+ import config from '@cloudcommerce/firebase/lib/config';
9
+ import Pagaleve from './pagaleve-constructor';
10
+
11
+ const { region } = config.get().httpsFunctionOptions;
12
+ const baseUri = `https://${region}-${process.env.GCLOUD_PROJECT}.cloudfunctions.net`;
13
+
14
+ const pagaleveCreateTransaction = async (body: AppModuleBody<'create_transaction'>) => {
15
+ const { params, application } = body;
16
+ const appData = { ...application.data, ...application.hidden_data };
17
+ const {
18
+ PAGALEVE_USERNAME,
19
+ PAGALEVE_PASSWORD,
20
+ PAGALEVE_SANDBOX,
21
+ } = process.env;
22
+ if (PAGALEVE_USERNAME) appData.username = PAGALEVE_USERNAME;
23
+ if (PAGALEVE_PASSWORD) appData.password = PAGALEVE_PASSWORD;
24
+ const isSandbox = !!PAGALEVE_SANDBOX;
25
+ const pagaleve = new Pagaleve(appData.username, appData.password, isSandbox);
26
+
27
+ const orderId = params.order_id || '';
28
+ const orderNumber = params.order_number;
29
+ const { amount, buyer, items } = params;
30
+ const isPix = params.payment_method.code === 'account_deposit';
31
+ const transaction: CreateTransactionResponse['transaction'] = {
32
+ intermediator: {
33
+ payment_method: params.payment_method,
34
+ },
35
+ currency_id: params.currency_id,
36
+ currency_symbol: params.currency_symbol,
37
+ amount: amount.total,
38
+ status: {
39
+ current: 'pending',
40
+ },
41
+ };
42
+ const finalAmount = Math.floor(amount.total * 100);
43
+ const finalFreight = amount.freight ? Math.floor(amount.freight * 100) : 0;
44
+
45
+ const parseAddress = (_to: Exclude<(typeof params)['to'], undefined>) => ({
46
+ name: _to.name,
47
+ city: _to.city,
48
+ state: _to.province_code,
49
+ street: _to.street,
50
+ zip_code: _to.zip,
51
+ neighborhood: _to.borough,
52
+ number: String(_to.number) || 's/n',
53
+ complement: _to.complement || undefined,
54
+ });
55
+ const shippingAddr = params.to && parseAddress(params.to);
56
+ const billingAddr = params.billing_address
57
+ ? parseAddress(params.billing_address)
58
+ : shippingAddr;
59
+
60
+ const hash = createHmac('sha256', appData.password)
61
+ .update(orderId).digest('hex');
62
+ const pagaleveTransaction: Record<string, any> = {
63
+ cancel_url: `https://${params.domain}/app/#/order/${orderNumber}/${orderId}`,
64
+ approve_url: `https://${params.domain}/app/#/order/${orderNumber}/${orderId}`,
65
+ webhook_url: `${baseUri}/pagaleve-webhook?order_id=${orderId}&hash=${hash}`,
66
+ is_pix_upfront: !!isPix,
67
+ order: {
68
+ reference: orderId,
69
+ description: `Order from e-com.plus ${orderNumber}`,
70
+ shipping: {
71
+ amount: finalFreight || 0,
72
+ address: shippingAddr,
73
+ },
74
+ amount: finalAmount,
75
+ items: [],
76
+ timestamp: new Date().toISOString(),
77
+ type: 'ORDINARY',
78
+ },
79
+ shopper: {
80
+ cpf: String(buyer.doc_number),
81
+ first_name: buyer.fullname.replace(/\s.*/, ''),
82
+ last_name: buyer.fullname.replace(/[^\s]+\s/, ''),
83
+ email: buyer.email,
84
+ phone: buyer.phone.number,
85
+ billing_address: billingAddr,
86
+ },
87
+ };
88
+ let totalQuantity = 0;
89
+ items.forEach((item) => {
90
+ if (item.quantity > 0) {
91
+ totalQuantity += item.quantity;
92
+ const objImg = getImg(item);
93
+ pagaleveTransaction.order.items.push({
94
+ name: item.name || item.sku,
95
+ sku: item.sku,
96
+ quantity: item.quantity,
97
+ price: Math.floor((item.final_price || item.price) * 100),
98
+ url: `https://${params.domain}`,
99
+ reference: item.product_id,
100
+ image: objImg && objImg.url ? objImg.url : `https://${params.domain}`,
101
+ });
102
+ }
103
+ });
104
+ const birthDate = buyer.birth_date;
105
+ if (birthDate && birthDate.year && birthDate.month && birthDate.day) {
106
+ pagaleveTransaction.birth_date = `${birthDate.year}-`
107
+ + `${birthDate.month.toString().padStart(2, '0')}-`
108
+ + birthDate.day.toString().padStart(2, '0');
109
+ }
110
+
111
+ if (totalQuantity > 0) {
112
+ try {
113
+ await pagaleve.preparing;
114
+ const { data } = pagaleve.axios.post('/v1/checkouts', pagaleveTransaction, {
115
+ maxRedirects: 0,
116
+ });
117
+ transaction.payment_link = data.redirect_url || data.checkout_url;
118
+ if (isPix && data.timestamp) {
119
+ transaction.account_deposit = {
120
+ valid_thru: data.timestamp,
121
+ };
122
+ }
123
+ return {
124
+ redirect_to_payment: true,
125
+ transaction,
126
+ } as CreateTransactionResponse;
127
+ } catch (error: any) {
128
+ const errCode = 'PAGALEVE_TRANSACTION_ERR';
129
+ let { message } = error;
130
+ const err: any = new Error(`${errCode} #${orderId} => ${message}`);
131
+ if (error.response) {
132
+ const { status, data } = error.response;
133
+ if (status !== 401 && status !== 403) {
134
+ err.transaction = transaction;
135
+ err.status = status;
136
+ if (typeof data === 'object' && data) {
137
+ err.response = JSON.stringify(data);
138
+ } else {
139
+ err.response = data;
140
+ }
141
+ } else if (Array.isArray(data?.errors) && data.errors[0]?.message) {
142
+ message = data.errors[0].message;
143
+ }
144
+ }
145
+ logger.error(err);
146
+ return {
147
+ status: 409,
148
+ error: errCode,
149
+ message,
150
+ };
151
+ }
152
+ }
153
+
154
+ return {
155
+ status: 400,
156
+ error: 'PAGALEVE_TRANSACTION_INVALID',
157
+ message: 'Não há itens disponíveis no pedido',
158
+ };
159
+ };
160
+
161
+ export default pagaleveCreateTransaction;
@@ -0,0 +1,122 @@
1
+ import type { AppModuleBody, ListPaymentsResponse } from '@cloudcommerce/types';
2
+ import logger from 'firebase-functions/logger';
3
+
4
+ const pagaleveListPayments = (body: AppModuleBody<'list_payments'>) => {
5
+ const { application } = body;
6
+ const params = body.params;
7
+ const response: ListPaymentsResponse = {
8
+ payment_gateways: [],
9
+ };
10
+ const appData = { ...application.data, ...application.hidden_data };
11
+ const {
12
+ PAGALEVE_USERNAME,
13
+ PAGALEVE_PASSWORD,
14
+ } = process.env;
15
+ if (PAGALEVE_USERNAME) appData.username = PAGALEVE_USERNAME;
16
+ if (PAGALEVE_PASSWORD) appData.password = PAGALEVE_PASSWORD;
17
+
18
+ if (!appData.username || !appData.password) {
19
+ logger.warn('Missign Pagaleve username/password');
20
+ return {
21
+ status: 409,
22
+ error: 'NO_PAGALEVE_KEYS',
23
+ message: 'Usuário e/ou senha não configurados pelo lojista',
24
+ };
25
+ }
26
+
27
+ const amount = params.amount || {} as Exclude<(typeof params)['amount'], undefined>;
28
+ const intermediator = {
29
+ name: 'Pagaleve',
30
+ link: 'https://api.pagaleve.com.br',
31
+ code: 'pagaleve',
32
+ };
33
+ const { discount } = appData;
34
+ if (discount && discount.value) {
35
+ if (discount.apply_at !== 'freight') {
36
+ const { value } = discount;
37
+ response.discount_option = {
38
+ label: 'Pix',
39
+ value,
40
+ };
41
+ ['type', 'min_amount'].forEach((prop) => {
42
+ if (discount[prop]) {
43
+ response.discount_option![prop] = discount[prop];
44
+ }
45
+ });
46
+ }
47
+
48
+ if (amount.total) {
49
+ if (amount.total < discount.min_amount) {
50
+ discount.value = 0;
51
+ } else {
52
+ delete discount.min_amount;
53
+ const maxDiscount = amount[discount.apply_at || 'subtotal'];
54
+ let discountValue: number | undefined;
55
+ if (discount.type === 'percentage') {
56
+ discountValue = maxDiscount * (discount.value / 100);
57
+ } else {
58
+ discountValue = discount.value;
59
+ if (discountValue! > maxDiscount) {
60
+ discountValue = maxDiscount;
61
+ }
62
+ }
63
+ if (discountValue) {
64
+ amount.discount = (amount.discount || 0) + discountValue;
65
+ amount.total -= discountValue;
66
+ if (amount.total < 0) {
67
+ amount.total = 0;
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+
74
+ const listPaymentMethods = ['payment_link', 'account_deposit'] as const;
75
+ listPaymentMethods.forEach((paymentMethod) => {
76
+ const isLinkPayment = paymentMethod === 'payment_link';
77
+ const methodConfig = (appData[paymentMethod] || {});
78
+ const minAmount = Number(methodConfig.min_amount || 1);
79
+ let validateAmount = false;
80
+ if (amount.total && minAmount >= 0) {
81
+ validateAmount = amount.total >= minAmount;
82
+ }
83
+
84
+ // Workaround for showcase
85
+ const validatePayment = amount.total ? validateAmount : true;
86
+ const methodEnable = !methodConfig.disable;
87
+ if (validatePayment && methodEnable) {
88
+ const label = methodConfig.label || (isLinkPayment ? 'Pix Parcelado' : 'Pagar com Pix');
89
+ const gateway: ListPaymentsResponse['payment_gateways'][0] = {
90
+ label,
91
+ icon: methodConfig.icon,
92
+ text: methodConfig.text,
93
+ payment_method: {
94
+ code: isLinkPayment ? 'balance_on_intermediary' : paymentMethod,
95
+ name: `${label} - ${intermediator.name} `,
96
+ },
97
+ intermediator,
98
+ };
99
+ if (!gateway.icon) {
100
+ if (isLinkPayment) {
101
+ gateway.icon = 'https://ecom-pagaleve.web.app/pagaleve-parcelado.png';
102
+ } else {
103
+ gateway.icon = 'https://ecom-pagaleve.web.app/pagaleve-pix.png';
104
+ }
105
+ }
106
+ if ((discount && discount.value && discount[paymentMethod] !== false)) {
107
+ gateway.discount = {};
108
+ ['apply_at', 'type', 'value'].forEach((field) => {
109
+ gateway.discount![field] = discount[field];
110
+ });
111
+ if (response.discount_option && !response.discount_option.label) {
112
+ response.discount_option.label = label;
113
+ }
114
+ }
115
+ response.payment_gateways.push(gateway);
116
+ }
117
+ });
118
+
119
+ return response;
120
+ };
121
+
122
+ export default pagaleveListPayments;
@@ -0,0 +1,150 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ import { createHmac, timingSafeEqual } from 'node:crypto';
3
+ import functions from 'firebase-functions/v1';
4
+ import logger from 'firebase-functions/logger';
5
+ import api from '@cloudcommerce/api';
6
+ import config from '@cloudcommerce/firebase/lib/config';
7
+ import Pagaleve from './pagaleve-constructor';
8
+
9
+ const { httpsFunctionOptions } = config.get();
10
+
11
+ const getAppHiddenData = async () => {
12
+ const { appId } = config.get().apps.pagaleve;
13
+ const { data } = await api.get(`applications?app_id=${appId}&fields=hidden_data`);
14
+ return data.result[0]?.hidden_data;
15
+ };
16
+
17
+ const parseStatusToEcom = (pagaleveTransactionStatus: string) => {
18
+ switch (pagaleveTransactionStatus.toLowerCase()) {
19
+ case 'pending':
20
+ case 'new':
21
+ case 'accepted':
22
+ return 'pending';
23
+ case 'authorized':
24
+ case 'completed':
25
+ return 'paid';
26
+ case 'expired':
27
+ case 'DECLINED':
28
+ case 'ABANDONED':
29
+ case 'canceled':
30
+ return 'voided';
31
+ default:
32
+ }
33
+ return 'unknown';
34
+ };
35
+
36
+ export const pagarme = {
37
+ webhook: functions
38
+ .region(httpsFunctionOptions.region)
39
+ .runWith(httpsFunctionOptions)
40
+ .https.onRequest(async (req, res) => {
41
+ const { body, query: { hash } } = req;
42
+ if (typeof hash !== 'string') {
43
+ res.sendStatus(403);
44
+ return;
45
+ }
46
+ const {
47
+ id,
48
+ orderReference,
49
+ state,
50
+ amount,
51
+ } = (body || {}) as { [k: string]: any, orderReference?: string & { length: 24 } };
52
+ if (typeof orderReference !== 'string' || orderReference.length !== 24) {
53
+ res.sendStatus(400);
54
+ return;
55
+ }
56
+ let appData: Record<string, any> | undefined;
57
+ try {
58
+ appData = await getAppHiddenData();
59
+ } catch (err) {
60
+ logger.error(err);
61
+ res.sendStatus(500);
62
+ return;
63
+ }
64
+ if (!appData?.password) {
65
+ res.sendStatus(409);
66
+ return;
67
+ }
68
+ const {
69
+ PAGALEVE_USERNAME,
70
+ PAGALEVE_PASSWORD,
71
+ PAGALEVE_SANDBOX,
72
+ } = process.env;
73
+ if (PAGALEVE_USERNAME) appData.username = PAGALEVE_USERNAME;
74
+ if (PAGALEVE_PASSWORD) appData.password = PAGALEVE_PASSWORD;
75
+ const isSandbox = !!PAGALEVE_SANDBOX;
76
+
77
+ const validHash = createHmac('sha256', appData.password)
78
+ .update(orderReference).digest('hex');
79
+ if (
80
+ validHash.length !== hash.length
81
+ || !timingSafeEqual(Buffer.from(hash), Buffer.from(validHash))
82
+ ) {
83
+ res.sendStatus(401);
84
+ return;
85
+ }
86
+
87
+ const orderEndpoint = `orders/${orderReference}` as const;
88
+ try {
89
+ const { data: order } = await api.get(orderEndpoint);
90
+ if (order?.transactions) {
91
+ const transactionIndex = order.transactions.findIndex(({ app }) => {
92
+ return app?.intermediator?.code === 'pagaleve';
93
+ });
94
+ const transactionId = order.transactions[transactionIndex]?._id;
95
+ if (!transactionId) {
96
+ res.sendStatus(404);
97
+ return;
98
+ }
99
+
100
+ await api.post(`${orderEndpoint}/payments_history`, {
101
+ date_time: new Date().toISOString(),
102
+ status: parseStatusToEcom(state),
103
+ transaction_id: transactionId,
104
+ flags: ['pagaleve'],
105
+ } as Exclude<(typeof order)['payments_history'], undefined>[0]);
106
+
107
+ await api.patch(`${orderEndpoint}/transactions/${transactionId}`, {
108
+ intermediator: {
109
+ transaction_id: id || '',
110
+ transaction_code: id || '',
111
+ },
112
+ } as Partial<Exclude<(typeof order)['transactions'], undefined>[0]>);
113
+
114
+ if (state.toLowerCase() === 'authorized') {
115
+ const pagaleve = new Pagaleve(appData.username, appData.password, isSandbox);
116
+ await pagaleve.preparing;
117
+ const pagalevePayment = {
118
+ checkout_id: id,
119
+ currency: 'BRL',
120
+ amount,
121
+ intent: 'CAPTURE',
122
+ };
123
+ await pagaleve.axios.post('/v1/payments', pagalevePayment, {
124
+ maxRedirects: 0,
125
+ });
126
+ }
127
+ }
128
+ } catch (error: any) {
129
+ const { response } = error;
130
+ let status: number | undefined;
131
+ if (response) {
132
+ status = response.status;
133
+ const err: any = new Error(`Webhook failed with ${status} for #${orderReference}`);
134
+ err.url = error.config?.url;
135
+ err.body = error.config?.body;
136
+ err.status = status;
137
+ err.response = JSON.stringify(response.data);
138
+ logger.error(err);
139
+ } else {
140
+ logger.error(error);
141
+ }
142
+ if (!res.headersSent) {
143
+ res.send({
144
+ status: status || 500,
145
+ msg: `Pagaleve webhook error for ${orderReference}`,
146
+ });
147
+ }
148
+ }
149
+ }),
150
+ };
@@ -0,0 +1,12 @@
1
+ import '@cloudcommerce/firebase/lib/init';
2
+ import type { AppModuleBody } from '@cloudcommerce/types';
3
+ import handleListPayments from './pagaleve-list-payments';
4
+ import handleCreateTransaction from './pagaleve-create-transaction';
5
+
6
+ export const listPayments = async (modBody: AppModuleBody<'list_payments'>) => {
7
+ return handleListPayments(modBody);
8
+ };
9
+
10
+ export const createTransaction = async (modBody: AppModuleBody<'create_transaction'>) => {
11
+ return handleCreateTransaction(modBody);
12
+ };
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "../../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "declaration": true
5
+ }
6
+ }
@@ -0,0 +1 @@
1
+ export * from './lib/pagaleve-webhook';
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-pagarme",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce app to integrate Pagar.me",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce app to integrate Pagar.me",
6
6
  "main": "lib/pagarme.js",
7
7
  "exports": {
8
8
  ".": "./lib/pagarme.js",
@@ -11,6 +11,7 @@
11
11
  "files": [
12
12
  "/lib",
13
13
  "/lib-mjs",
14
+ "/assets",
14
15
  "/types",
15
16
  "/*.{js,mjs,ts}"
16
17
  ],
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-pagarme-v5",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce app to integrate Pagar.me API v5 with recurring payments",
4
+ "version": "2.12.0",
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": {
8
8
  ".": "./lib/index.js",
@@ -11,6 +11,7 @@
11
11
  "files": [
12
12
  "/lib",
13
13
  "/lib-mjs",
14
+ "/assets",
14
15
  "/types",
15
16
  "/*.{js,mjs,ts}"
16
17
  ],
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-paghiper",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce app to integrate PagHiper",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce app to integrate PagHiper",
6
6
  "main": "lib/paghiper.js",
7
7
  "exports": {
8
8
  ".": "./lib/paghiper.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-pix",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce app to integrate Pix API (Bacen)",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce app to integrate Pix API (Bacen)",
6
6
  "main": "lib/pix.js",
7
7
  "exports": {
8
8
  ".": "./lib/pix.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-tiny-erp",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce app for Tiny ERP",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce app for Tiny ERP",
6
6
  "main": "lib/tiny-erp.js",
7
7
  "files": [
8
8
  "/lib",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-webhooks",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce app for general order webhooks",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce app for general order webhooks",
6
6
  "main": "lib/index.js",
7
7
  "files": [
8
8
  "/lib",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/cli",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce CLI tools",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce CLI tools",
6
6
  "bin": {
7
7
  "cloudcommerce": "./bin/run.mjs"
8
8
  },
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/config",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce base config",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce base config",
6
6
  "main": "lib/config.js",
7
7
  "exports": {
8
8
  ".": "./lib/config.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/emails",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce email sender",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce email sender",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
8
8
  "files": [
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cloudcommerce/eslint",
3
3
  "type": "module",
4
- "version": "2.11.2",
5
- "description": "E-Com Plus Cloud Commerce ESLint config",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce ESLint config",
6
6
  "main": "lib/index.js",
7
7
  "files": [
8
8
  "/**/*.eslintrc.*"