cloudcommerce 2.10.7 → 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 (137) hide show
  1. package/.github/workflows/test-apps.yml +2 -2
  2. package/CHANGELOG.md +31 -0
  3. package/action.yml +2 -2
  4. package/ecomplus-stores/barradoce/functions/many/package.json +3 -3
  5. package/ecomplus-stores/barradoce/functions/ssr/content/extra-pages/promocoes.md +1 -1
  6. package/ecomplus-stores/barradoce/functions/ssr/content/pages/home.json +50 -86
  7. package/ecomplus-stores/barradoce/functions/ssr/package.json +6 -6
  8. package/ecomplus-stores/barradoce/functions/ssr/public/img/uploads/banner-pistache.jpg +0 -0
  9. package/ecomplus-stores/barradoce/functions/ssr/public/robots.txt +1 -0
  10. package/ecomplus-stores/barradoce/functions/ssr/src/components/Banner.vue +7 -8
  11. package/ecomplus-stores/barradoce/functions/ssr/src/state/midd-search-engine.ts +9 -1
  12. package/ecomplus-stores/barradoce/functions/ssr/tsconfig.json +6 -2
  13. package/ecomplus-stores/barradoce/functions/with-apps/package.json +3 -3
  14. package/ecomplus-stores/barradoce/package.json +2 -2
  15. package/package.json +2 -2
  16. package/packages/__skeleton/package.json +2 -1
  17. package/packages/api/lib/api.d.ts +8 -1
  18. package/packages/api/lib/api.js +12 -3
  19. package/packages/api/lib/api.js.map +1 -1
  20. package/packages/api/package.json +2 -2
  21. package/packages/api/src/api.ts +20 -5
  22. package/packages/apps/affiliate-program/package.json +2 -2
  23. package/packages/apps/correios/package.json +2 -2
  24. package/packages/apps/custom-payment/package.json +2 -2
  25. package/packages/apps/custom-shipping/package.json +2 -2
  26. package/packages/apps/datafrete/package.json +2 -2
  27. package/packages/apps/discounts/package.json +2 -2
  28. package/packages/apps/emails/package.json +2 -2
  29. package/packages/apps/fb-conversions/package.json +2 -2
  30. package/packages/apps/flash-courier/package.json +2 -2
  31. package/packages/apps/frenet/package.json +2 -2
  32. package/packages/apps/galaxpay/package.json +3 -2
  33. package/packages/apps/google-analytics/package.json +2 -2
  34. package/packages/apps/jadlog/package.json +2 -2
  35. package/packages/apps/loyalty-points/package.json +2 -2
  36. package/packages/apps/mandae/package.json +2 -2
  37. package/packages/apps/melhor-envio/package.json +2 -2
  38. package/packages/apps/mercadopago/package.json +3 -2
  39. package/packages/apps/pagaleve/CHANGELOG.md +1 -0
  40. package/packages/apps/pagaleve/README.md +1 -0
  41. package/packages/apps/pagaleve/lib/index.d.ts +1 -0
  42. package/packages/apps/pagaleve/lib/index.js +3 -0
  43. package/packages/apps/pagaleve/lib/index.js.map +1 -0
  44. package/packages/apps/pagaleve/lib/pagaleve-constructor.d.ts +7 -0
  45. package/packages/apps/pagaleve/lib/pagaleve-constructor.js +78 -0
  46. package/packages/apps/pagaleve/lib/pagaleve-constructor.js.map +1 -0
  47. package/packages/apps/pagaleve/lib/pagaleve-create-transaction.d.ts +7 -0
  48. package/packages/apps/pagaleve/lib/pagaleve-create-transaction.js +148 -0
  49. package/packages/apps/pagaleve/lib/pagaleve-create-transaction.js.map +1 -0
  50. package/packages/apps/pagaleve/lib/pagaleve-list-payments.d.ts +7 -0
  51. package/packages/apps/pagaleve/lib/pagaleve-list-payments.js +113 -0
  52. package/packages/apps/pagaleve/lib/pagaleve-list-payments.js.map +1 -0
  53. package/packages/apps/pagaleve/lib/pagaleve-webhook.d.ts +4 -0
  54. package/packages/apps/pagaleve/lib/pagaleve-webhook.js +135 -0
  55. package/packages/apps/pagaleve/lib/pagaleve-webhook.js.map +1 -0
  56. package/packages/apps/pagaleve/lib/pagaleve.d.ts +12 -0
  57. package/packages/apps/pagaleve/lib/pagaleve.js +12 -0
  58. package/packages/apps/pagaleve/lib/pagaleve.js.map +1 -0
  59. package/packages/apps/pagaleve/package.json +43 -0
  60. package/packages/apps/pagaleve/src/index.ts +2 -0
  61. package/packages/apps/pagaleve/src/pagaleve-constructor.ts +85 -0
  62. package/packages/apps/pagaleve/src/pagaleve-create-transaction.ts +161 -0
  63. package/packages/apps/pagaleve/src/pagaleve-list-payments.ts +122 -0
  64. package/packages/apps/pagaleve/src/pagaleve-webhook.ts +150 -0
  65. package/packages/apps/pagaleve/src/pagaleve.ts +12 -0
  66. package/packages/apps/pagaleve/tsconfig.json +6 -0
  67. package/packages/apps/pagaleve/webhook.js +1 -0
  68. package/packages/apps/pagarme/package.json +3 -2
  69. package/packages/apps/pagarme-v5/package.json +3 -2
  70. package/packages/apps/paghiper/package.json +2 -2
  71. package/packages/apps/pix/package.json +2 -2
  72. package/packages/apps/tiny-erp/package.json +2 -2
  73. package/packages/apps/webhooks/package.json +2 -2
  74. package/packages/cli/package.json +2 -2
  75. package/packages/config/package.json +2 -2
  76. package/packages/emails/package.json +2 -2
  77. package/packages/eslint/package.json +2 -2
  78. package/packages/events/lib/firebase.js +2 -0
  79. package/packages/events/lib/firebase.js.map +1 -1
  80. package/packages/events/package.json +3 -2
  81. package/packages/events/src/firebase.ts +2 -0
  82. package/packages/feeds/package.json +2 -2
  83. package/packages/firebase/lib/config.d.ts +3 -0
  84. package/packages/firebase/lib/config.js +3 -0
  85. package/packages/firebase/lib/config.js.map +1 -1
  86. package/packages/firebase/package.json +2 -2
  87. package/packages/firebase/src/config.ts +3 -0
  88. package/packages/i18n/package.json +2 -2
  89. package/packages/modules/lib/firebase/call-app-module.js +12 -0
  90. package/packages/modules/lib/firebase/call-app-module.js.map +1 -1
  91. package/packages/modules/package.json +3 -2
  92. package/packages/modules/src/firebase/call-app-module.ts +12 -0
  93. package/packages/passport/lib/firebase.js +20 -22
  94. package/packages/passport/lib/firebase.js.map +1 -1
  95. package/packages/passport/package.json +2 -2
  96. package/packages/passport/src/firebase.ts +25 -25
  97. package/packages/ssr/lib/lib/serve-storefront.js +3 -1
  98. package/packages/ssr/lib/lib/serve-storefront.js.map +1 -1
  99. package/packages/ssr/package.json +3 -3
  100. package/packages/ssr/src/lib/serve-storefront.ts +3 -1
  101. package/packages/storefront/dist/client/_astro/ProductDetails.BpZtnS8j.js +1 -7
  102. package/packages/storefront/dist/client/_astro/hoisted.-C0vLMXT.js +8 -0
  103. package/packages/storefront/dist/server/_astro-internal_middleware.mjs +2 -2
  104. package/packages/storefront/dist/server/chunks/{404_jTV5wvby.mjs → 404_BcY_5eJJ.mjs} +1 -1
  105. package/packages/storefront/dist/server/chunks/{CartSidebar_CV9qwGNE.mjs → CartSidebar_tmly-0ip.mjs} +2 -2
  106. package/packages/storefront/dist/server/chunks/{SearchModal_Cw1ECnXI.mjs → SearchModal_CGNQss2j.mjs} +2 -2
  107. package/packages/storefront/dist/server/chunks/{_.._k1NruPDv.mjs → _.._Bt6Uzpk2.mjs} +1 -1
  108. package/packages/storefront/dist/server/chunks/{_astro-internal_middleware_DIG56BhA.mjs → _astro-internal_middleware_CqUpziyW.mjs} +1 -1
  109. package/packages/storefront/dist/server/chunks/{_page__BKNX3RH7.mjs → _page__Dz-iZHMh.mjs} +1 -1
  110. package/packages/storefront/dist/server/chunks/{account_BZOa6Kmc.mjs → account_tfs9KFTy.mjs} +1 -1
  111. package/packages/storefront/dist/server/chunks/astro/{assets-service_MW85B416.mjs → assets-service_DSoC_W52.mjs} +2 -1
  112. package/packages/storefront/dist/server/chunks/{astro_8KdHu_Gf.mjs → astro_Cu3MZ9xv.mjs} +72 -33
  113. package/packages/storefront/dist/server/chunks/{index_D1o9pXka.mjs → index_BKS_40rA.mjs} +1 -1
  114. package/packages/storefront/dist/server/chunks/{index_CZ6FSUEb.mjs → index_CGzMgZTN.mjs} +1 -1
  115. package/packages/storefront/dist/server/chunks/{node_Khrf-0bH.mjs → node_lZaNT3E1.mjs} +1 -1
  116. package/packages/storefront/dist/server/chunks/pages/{404_BPSxJtl3.mjs → 404_CMwuVMu1.mjs} +9 -10
  117. package/packages/storefront/dist/server/chunks/pages/{__ByRpsTnC.mjs → __Dz53F-0T.mjs} +2 -2
  118. package/packages/storefront/dist/server/chunks/pages/{_page__BasreLue.mjs → _page__C1x19nYF.mjs} +3 -3
  119. package/packages/storefront/dist/server/chunks/pages/{account_MZBvNAyZ.mjs → account_B5Z6wDBy.mjs} +2 -2
  120. package/packages/storefront/dist/server/chunks/pages/{index_CV2ET14h.mjs → index_CqvjdvSg.mjs} +3 -3
  121. package/packages/storefront/dist/server/chunks/pages/{node_1tKTIKG-.mjs → node_mvX6Tssv.mjs} +4 -111
  122. package/packages/storefront/dist/server/chunks/pages/{~fallback_BVYzgZ5p.mjs → ~fallback_D2ugBVgc.mjs} +2 -2
  123. package/packages/storefront/dist/server/chunks/{~fallback_xH9bJF7E.mjs → ~fallback_CrFe__-f.mjs} +1 -1
  124. package/packages/storefront/dist/server/entry.mjs +15 -14
  125. package/packages/storefront/dist/server/{manifest_S9lE9v48.mjs → manifest_D4v8KX-D.mjs} +2 -2
  126. package/packages/storefront/dist/server/middleware.mjs +2 -2
  127. package/packages/storefront/dist/server/renderers.mjs +1 -1
  128. package/packages/storefront/package.json +4 -4
  129. package/packages/storefront/server.d.ts +2 -4
  130. package/packages/storefront/src/lib/$storefront.d.ts +4 -0
  131. package/packages/storefront/src/lib/ssr-context.ts +3 -3
  132. package/packages/storefront/tsconfig.base.json +16 -0
  133. package/packages/storefront/tsconfig.json +5 -13
  134. package/packages/test-base/package.json +2 -2
  135. package/packages/types/package.json +2 -2
  136. package/ecomplus-stores/barradoce/functions/ssr/public/img/uploads/banner-forma-decora.jpg +0 -0
  137. package/packages/storefront/dist/client/_astro/hoisted.CSjieYcR.js +0 -8
@@ -0,0 +1,135 @@
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.js';
8
+
9
+ const { httpsFunctionOptions } = config.get();
10
+ const getAppHiddenData = async () => {
11
+ const { appId } = config.get().apps.pagaleve;
12
+ const { data } = await api.get(`applications?app_id=${appId}&fields=hidden_data`);
13
+ return data.result[0]?.hidden_data;
14
+ };
15
+ const parseStatusToEcom = (pagaleveTransactionStatus) => {
16
+ switch (pagaleveTransactionStatus.toLowerCase()) {
17
+ case 'pending':
18
+ case 'new':
19
+ case 'accepted':
20
+ return 'pending';
21
+ case 'authorized':
22
+ case 'completed':
23
+ return 'paid';
24
+ case 'expired':
25
+ case 'DECLINED':
26
+ case 'ABANDONED':
27
+ case 'canceled':
28
+ return 'voided';
29
+ default:
30
+ }
31
+ return 'unknown';
32
+ };
33
+
34
+ export const pagarme = {
35
+ webhook: functions
36
+ .region(httpsFunctionOptions.region)
37
+ .runWith(httpsFunctionOptions)
38
+ .https.onRequest(async (req, res) => {
39
+ const { body, query: { hash } } = req;
40
+ if (typeof hash !== 'string') {
41
+ res.sendStatus(403);
42
+ return;
43
+ }
44
+ const {
45
+ id, orderReference, state, amount,
46
+ } = (body || {});
47
+ if (typeof orderReference !== 'string' || orderReference.length !== 24) {
48
+ res.sendStatus(400);
49
+ return;
50
+ }
51
+ let appData;
52
+ try {
53
+ appData = await getAppHiddenData();
54
+ } catch (err) {
55
+ logger.error(err);
56
+ res.sendStatus(500);
57
+ return;
58
+ }
59
+ if (!appData?.password) {
60
+ res.sendStatus(409);
61
+ return;
62
+ }
63
+ const { PAGALEVE_USERNAME, PAGALEVE_PASSWORD, PAGALEVE_SANDBOX } = process.env;
64
+ if (PAGALEVE_USERNAME) appData.username = PAGALEVE_USERNAME;
65
+ if (PAGALEVE_PASSWORD) appData.password = PAGALEVE_PASSWORD;
66
+ const isSandbox = !!PAGALEVE_SANDBOX;
67
+ const validHash = createHmac('sha256', appData.password)
68
+ .update(orderReference).digest('hex');
69
+ if (validHash.length !== hash.length
70
+ || !timingSafeEqual(Buffer.from(hash), Buffer.from(validHash))) {
71
+ res.sendStatus(401);
72
+ return;
73
+ }
74
+ const orderEndpoint = `orders/${orderReference}`;
75
+ try {
76
+ const { data: order } = await api.get(orderEndpoint);
77
+ if (order?.transactions) {
78
+ const transactionIndex = order.transactions.findIndex(({ app }) => {
79
+ return app?.intermediator?.code === 'pagaleve';
80
+ });
81
+ const transactionId = order.transactions[transactionIndex]?._id;
82
+ if (!transactionId) {
83
+ res.sendStatus(404);
84
+ return;
85
+ }
86
+ await api.post(`${orderEndpoint}/payments_history`, {
87
+ date_time: new Date().toISOString(),
88
+ status: parseStatusToEcom(state),
89
+ transaction_id: transactionId,
90
+ flags: ['pagaleve'],
91
+ });
92
+ await api.patch(`${orderEndpoint}/transactions/${transactionId}`, {
93
+ intermediator: {
94
+ transaction_id: id || '',
95
+ transaction_code: id || '',
96
+ },
97
+ });
98
+ if (state.toLowerCase() === 'authorized') {
99
+ const pagaleve = new Pagaleve(appData.username, appData.password, isSandbox);
100
+ await pagaleve.preparing;
101
+ const pagalevePayment = {
102
+ checkout_id: id,
103
+ currency: 'BRL',
104
+ amount,
105
+ intent: 'CAPTURE',
106
+ };
107
+ await pagaleve.axios.post('/v1/payments', pagalevePayment, {
108
+ maxRedirects: 0,
109
+ });
110
+ }
111
+ }
112
+ } catch (error) {
113
+ const { response } = error;
114
+ let status;
115
+ if (response) {
116
+ status = response.status;
117
+ const err = new Error(`Webhook failed with ${status} for #${orderReference}`);
118
+ err.url = error.config?.url;
119
+ err.body = error.config?.body;
120
+ err.status = status;
121
+ err.response = JSON.stringify(response.data);
122
+ logger.error(err);
123
+ } else {
124
+ logger.error(error);
125
+ }
126
+ if (!res.headersSent) {
127
+ res.send({
128
+ status: status || 500,
129
+ msg: `Pagaleve webhook error for ${orderReference}`,
130
+ });
131
+ }
132
+ }
133
+ }),
134
+ };
135
+ // # sourceMappingURL=pagaleve-webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagaleve-webhook.js","sourceRoot":"","sources":["../src/pagaleve-webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import '@cloudcommerce/firebase/lib/init';
2
+ import type { AppModuleBody } from '@cloudcommerce/types';
3
+ export declare const listPayments: (modBody: AppModuleBody<'list_payments'>) => Promise<import("@cloudcommerce/types").ListPaymentsResponse | {
4
+ status: number;
5
+ error: string;
6
+ message: string;
7
+ }>;
8
+ export declare const createTransaction: (modBody: AppModuleBody<'create_transaction'>) => Promise<import("@cloudcommerce/types").CreateTransactionResponse | {
9
+ status: number;
10
+ error: string;
11
+ message: any;
12
+ }>;
@@ -0,0 +1,12 @@
1
+ import '@cloudcommerce/firebase/lib/init';
2
+ import handleListPayments from './pagaleve-list-payments.js';
3
+ import handleCreateTransaction from './pagaleve-create-transaction.js';
4
+
5
+ export const listPayments = async (modBody) => {
6
+ return handleListPayments(modBody);
7
+ };
8
+
9
+ export const createTransaction = async (modBody) => {
10
+ return handleCreateTransaction(modBody);
11
+ };
12
+ // # sourceMappingURL=pagaleve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagaleve.js","sourceRoot":"","sources":["../src/pagaleve.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC;AAE1C,OAAO,kBAAkB,MAAM,0BAA0B,CAAC;AAC1D,OAAO,uBAAuB,MAAM,+BAA+B,CAAC;AAEpE,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,OAAuC,EAAE,EAAE;IAC5E,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,OAA4C,EAAE,EAAE;IACtF,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC,CAAC"}
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@cloudcommerce/app-pagaleve",
3
+ "type": "module",
4
+ "version": "2.12.0",
5
+ "description": "e-com.plus Cloud Commerce app to integrate Pagaleve",
6
+ "main": "lib/pagaleve.js",
7
+ "exports": {
8
+ ".": "./lib/pagaleve.js",
9
+ "./webhook": "./lib/pagaleve-webhook.js"
10
+ },
11
+ "files": [
12
+ "/lib",
13
+ "/lib-mjs",
14
+ "/assets",
15
+ "/types",
16
+ "/*.{js,mjs,ts}"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/ecomplus/cloud-commerce.git",
21
+ "directory": "packages/apps/pagaleve"
22
+ },
23
+ "author": "E-Com Club Softwares para E-commerce <ti@e-com.club>",
24
+ "license": "MIT",
25
+ "bugs": {
26
+ "url": "https://github.com/ecomplus/cloud-commerce/issues"
27
+ },
28
+ "homepage": "https://github.com/ecomplus/cloud-commerce/tree/main/packages/apps/pagaleve#readme",
29
+ "scripts": {
30
+ "build": "bash ../../../scripts/build-lib.sh"
31
+ },
32
+ "dependencies": {
33
+ "@cloudcommerce/api": "workspace:*",
34
+ "@cloudcommerce/firebase": "workspace:*",
35
+ "@ecomplus/utils": "1.5.0-rc.6",
36
+ "axios": "^1.6.8",
37
+ "firebase-admin": "^12.0.0",
38
+ "firebase-functions": "^4.8.2"
39
+ },
40
+ "devDependencies": {
41
+ "@cloudcommerce/types": "workspace:*"
42
+ }
43
+ }
@@ -0,0 +1,2 @@
1
+ // eslint-disable-next-line import/prefer-default-export
2
+ export * from './pagaleve';
@@ -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;