@npmtapi/embed 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,279 @@
1
+ # @npmtapi/embed
2
+
3
+ SDK para integrar el widget de pago de TapiPay en cualquier sitio web o aplicación.
4
+
5
+ <!-- Docs: próximamente en https://docs.tapipay.com/embed -->
6
+
7
+ ---
8
+
9
+ ## Instalación
10
+
11
+ ```bash
12
+ # npm
13
+ npm install @npmtapi/embed
14
+
15
+ # pnpm
16
+ pnpm add @npmtapi/embed
17
+
18
+ # yarn
19
+ yarn add @npmtapi/embed
20
+ ```
21
+
22
+ ### Entrypoints
23
+
24
+ | Import | Contenido |
25
+ |--------|-----------|
26
+ | `@npmtapi/embed` | `loadTapipay()` + tipos TypeScript |
27
+ | `@npmtapi/embed/react` | `<TapipayWidget>` + `useTapipay()` |
28
+
29
+ Los tipos están incluidos — no necesitas `@types/tapipay`.
30
+
31
+ ---
32
+
33
+ ## Uso rápido
34
+
35
+ ### Script tag (sin bundler)
36
+
37
+ ```html
38
+ <script src="https://app.tapipay.la/embed.js"></script>
39
+ <div id="widget"></div>
40
+ <script>
41
+ tapipay.initialize({
42
+ container: "#widget",
43
+ organization: "acme",
44
+ identifier: "CLI-001"
45
+ });
46
+
47
+ tapipay.on("paymentPending", function(data) {
48
+ console.log("Pago en proceso:", data);
49
+ });
50
+ </script>
51
+ ```
52
+
53
+ ### Data-attrs (cero JavaScript)
54
+
55
+ ```html
56
+ <script src="https://app.tapipay.la/embed.js"></script>
57
+
58
+ <div
59
+ data-tapipay-widget
60
+ data-organization="acme"
61
+ data-identifier="CLI-001"
62
+ ></div>
63
+ ```
64
+
65
+ ---
66
+
67
+ ## React
68
+
69
+ ```tsx
70
+ import { TapipayWidget } from "@npmtapi/embed/react";
71
+
72
+ export function PagoPage({ clienteId }: { clienteId: string }) {
73
+ return (
74
+ <TapipayWidget
75
+ organization="acme"
76
+ identifier={clienteId}
77
+ onPending={(data) => console.log("Pago en proceso:", data)}
78
+ onCancelled={() => console.log("Pago cancelado por el usuario")}
79
+ />
80
+ );
81
+ }
82
+ ```
83
+
84
+ ### Props
85
+
86
+ | Prop | Tipo | Requerido | Descripción |
87
+ |------|------|-----------|-------------|
88
+ | `organization` | `string` | Sí | Alias de la organización en TapiPay |
89
+ | `identifier` | `string` | Sí | Identificador del cliente |
90
+ | `externalRequestId` | `string` | No | ID de deuda a preseleccionar |
91
+ | `selectionStrategy` | `"oldestCreated"` | No | Selecciona automáticamente la deuda pendiente más antigua |
92
+ | `environment` | `'production' \| 'homo'` | No | Entorno del SDK. Por defecto `'production'` |
93
+ | `onPending` | `(data) => void` | No | Callback cuando Yuno redirige al callback (pago en proceso) |
94
+ | `onCancelled` | `() => void` | No | Callback cuando el usuario cierra el popup sin completar el pago |
95
+ | `className` | `string` | No | Clases CSS del contenedor |
96
+ | `style` | `CSSProperties` | No | Estilos inline del contenedor |
97
+
98
+ ### Next.js App Router
99
+
100
+ ```tsx
101
+ "use client";
102
+
103
+ import { TapipayWidget } from "@npmtapi/embed/react";
104
+ import { useRouter } from "next/navigation";
105
+
106
+ export default function PagarPage() {
107
+ const router = useRouter();
108
+
109
+ return (
110
+ <TapipayWidget
111
+ organization={process.env.NEXT_PUBLIC_TAPIPAY_ORGANIZATION!}
112
+ identifier="CLI-001"
113
+ onPending={() => router.push("/procesando")}
114
+ />
115
+ );
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Vue 3
122
+
123
+ ```vue
124
+ <template>
125
+ <div ref="widgetRef"></div>
126
+ </template>
127
+
128
+ <script setup>
129
+ import { loadTapipay } from "@npmtapi/embed";
130
+ import { onMounted, onUnmounted, ref } from "vue";
131
+
132
+ const props = defineProps({ organization: String, identifier: String });
133
+ const widgetRef = ref(null);
134
+ let tapipay = null;
135
+
136
+ onMounted(async () => {
137
+ tapipay = await loadTapipay();
138
+ tapipay.initialize({
139
+ container: widgetRef.value,
140
+ organization: props.organization,
141
+ identifier: props.identifier,
142
+ });
143
+ tapipay.on("paymentPending", (data) => console.log("Pago en proceso:", data));
144
+ });
145
+
146
+ onUnmounted(() => tapipay?.destroy(widgetRef.value));
147
+ </script>
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Angular
153
+
154
+ ```typescript
155
+ import { loadTapipay, TapipayInstance } from "@npmtapi/embed";
156
+ import { Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from "@angular/core";
157
+
158
+ @Component({
159
+ selector: "app-tapipay-widget",
160
+ template: `<div #container></div>`,
161
+ })
162
+ export class TapipayWidgetComponent implements OnInit, OnDestroy {
163
+ @Input() organization!: string;
164
+ @Input() identifier!: string;
165
+ @ViewChild("container", { static: true }) containerRef!: ElementRef<HTMLDivElement>;
166
+
167
+ private tapipay: TapipayInstance | null = null;
168
+
169
+ async ngOnInit() {
170
+ this.tapipay = await loadTapipay();
171
+ this.tapipay.initialize({
172
+ container: this.containerRef.nativeElement,
173
+ organization: this.organization,
174
+ identifier: this.identifier,
175
+ });
176
+ }
177
+
178
+ ngOnDestroy() {
179
+ this.tapipay?.destroy(this.containerRef.nativeElement);
180
+ }
181
+ }
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Opciones
187
+
188
+ ### `loadTapipay(options?)`
189
+
190
+ | Parámetro | Tipo | Requerido | Descripción |
191
+ |-----------|------|-----------|-------------|
192
+ | `environment` | `'production' \| 'homo'` | No | Entorno del SDK a cargar. Por defecto `'production'`. |
193
+
194
+ ### `initialize(options)`
195
+
196
+ | Parámetro | Tipo | Requerido | Descripción |
197
+ |-----------|------|-----------|-------------|
198
+ | `container` | `string \| HTMLElement` | Sí | Selector CSS o referencia DOM. Solo para `initialize()`. |
199
+ | `organization` | `string` | Sí | Alias de la organización en TapiPay. |
200
+ | `identifier` | `string` | Sí | Identificador del cliente (DNI, número de cuenta, etc.). |
201
+ | `externalRequestId` | `string` | No | ID externo de una deuda específica a preseleccionar. |
202
+ | `selectionStrategy` | `"oldestCreated"` | No | Selección automática: `"oldestCreated"` elige la deuda pendiente más antigua. |
203
+
204
+ ---
205
+
206
+ ## Eventos
207
+
208
+ ```js
209
+ // Yuno redirigió al callback (pago en proceso)
210
+ tapipay.on("paymentPending", function(data) {
211
+ console.log("Pago en proceso:", data);
212
+ // Mostrar pantalla de "procesando" y esperar webhook
213
+ });
214
+
215
+ // El usuario cerró el popup sin completar el pago
216
+ tapipay.on("paymentCancelled", function() {
217
+ console.log("Pago cancelado por el usuario");
218
+ });
219
+
220
+ // Remover un listener
221
+ tapipay.off("paymentPending", handler);
222
+ ```
223
+
224
+ ### `TapipayPaymentPendingEvent`
225
+
226
+ ```ts
227
+ interface TapipayPaymentPendingEvent {
228
+ type: string; // "TAPIPAY_CALLBACK"
229
+ status: "pending";
230
+ data: Record<string, string>; // Parámetros que Yuno haya enviado (pueden estar vacíos)
231
+ }
232
+ ```
233
+
234
+ ### `TapipayPaymentCancelledEvent`
235
+
236
+ ```ts
237
+ interface TapipayPaymentCancelledEvent {
238
+ // sin campos adicionales
239
+ }
240
+ ```
241
+
242
+ ---
243
+
244
+ ## Entorno de homologación
245
+
246
+ Para apuntar al entorno de homologación en lugar de producción:
247
+
248
+ ### Vía npm (`loadTapipay`)
249
+
250
+ ```ts
251
+ import { loadTapipay } from "@npmtapi/embed";
252
+
253
+ const tapipay = await loadTapipay({ environment: "homo" });
254
+ tapipay.initialize({ container: "#widget", organization: "acme", identifier: "CLI-001" });
255
+ ```
256
+
257
+ ### Vía React
258
+
259
+ ```tsx
260
+ <TapipayWidget
261
+ environment="homo"
262
+ organization="acme"
263
+ identifier="CLI-001"
264
+ />
265
+ ```
266
+
267
+ ### Vía script tag
268
+
269
+ Apunta directamente al script del entorno deseado:
270
+
271
+ ```html
272
+ <!-- Homologación -->
273
+ <script src="https://homo.tapipay.la/embed.js"></script>
274
+
275
+ <!-- Producción -->
276
+ <script src="https://app.tapipay.la/embed.js"></script>
277
+ ```
278
+
279
+ > **Nota:** No se soporta cargar dos entornos distintos en la misma página, ya que `window.tapipay` es un objeto global compartido.
@@ -0,0 +1,61 @@
1
+ // src/loader.ts
2
+ var SDK_URLS = {
3
+ production: "https://app.tapipay.la/embed.js",
4
+ homo: "https://homo.tapipay.la/embed.js"
5
+ };
6
+ var loadPromises = /* @__PURE__ */ new Map();
7
+ function loadTapipay(options) {
8
+ var _a;
9
+ const env = (_a = options == null ? void 0 : options.environment) != null ? _a : "production";
10
+ const SDK_URL = SDK_URLS[env];
11
+ const SCRIPT_ID = `tapipay-embed-sdk-${env}`;
12
+ if (typeof window === "undefined") {
13
+ return Promise.reject(
14
+ new Error("[TapiPay] loadTapipay() requires a browser environment.")
15
+ );
16
+ }
17
+ if (window.tapipay && !window.tapipay._q) {
18
+ return Promise.resolve(window.tapipay);
19
+ }
20
+ const existing = loadPromises.get(env);
21
+ if (existing) return existing;
22
+ const promise = new Promise((resolve, reject) => {
23
+ const existingScript = document.getElementById(
24
+ SCRIPT_ID
25
+ );
26
+ const onLoad = () => {
27
+ if (window.tapipay) {
28
+ resolve(window.tapipay);
29
+ } else {
30
+ reject(
31
+ new Error(
32
+ "[TapiPay] El script carg\xF3 pero window.tapipay no est\xE1 definido."
33
+ )
34
+ );
35
+ }
36
+ };
37
+ const onError = () => {
38
+ loadPromises.delete(env);
39
+ reject(new Error(`[TapiPay] Error al cargar el SDK desde ${SDK_URL}`));
40
+ };
41
+ if (existingScript) {
42
+ existingScript.addEventListener("load", onLoad);
43
+ existingScript.addEventListener("error", onError);
44
+ return;
45
+ }
46
+ const script = document.createElement("script");
47
+ script.id = SCRIPT_ID;
48
+ script.src = SDK_URL;
49
+ script.async = true;
50
+ script.addEventListener("load", onLoad);
51
+ script.addEventListener("error", onError);
52
+ document.head.appendChild(script);
53
+ });
54
+ loadPromises.set(env, promise);
55
+ return promise;
56
+ }
57
+
58
+ export {
59
+ loadTapipay
60
+ };
61
+ //# sourceMappingURL=chunk-2WNQZXMS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/loader.ts"],"sourcesContent":["import type {\n\tLoadTapipayOptions,\n\tTapipayEnvironment,\n\tTapipayInstance,\n} from \"./types\";\n\nconst SDK_URLS: Record<TapipayEnvironment, string> = {\n\tproduction: \"https://app.tapipay.la/embed.js\",\n\thomo: \"https://homo.tapipay.la/embed.js\",\n};\n\n// Idempotencia por entorno\nconst loadPromises = new Map<TapipayEnvironment, Promise<TapipayInstance>>();\n\n/**\n * Carga el SDK de TapiPay de forma asíncrona inyectando el script en el DOM.\n *\n * - Idempotente por entorno: múltiples llamadas con el mismo `environment` retornan la misma Promise.\n * - Si window.tapipay ya existe (script cargado sync), resuelve inmediatamente.\n * - Compatible con React Strict Mode (doble mount/unmount).\n *\n * @example\n * // Producción (default)\n * const tapipay = await loadTapipay();\n *\n * // Homologación\n * const tapipay = await loadTapipay({ environment: 'homo' });\n *\n * tapipay.initialize({ container: \"#widget\", organization: \"acme\", identifier: \"CLI-001\" });\n */\nexport function loadTapipay(\n\toptions?: LoadTapipayOptions,\n): Promise<TapipayInstance> {\n\tconst env: TapipayEnvironment = options?.environment ?? \"production\";\n\tconst SDK_URL = SDK_URLS[env];\n\tconst SCRIPT_ID = `tapipay-embed-sdk-${env}`;\n\n\t// SSR guard\n\tif (typeof window === \"undefined\") {\n\t\treturn Promise.reject(\n\t\t\tnew Error(\"[TapiPay] loadTapipay() requires a browser environment.\"),\n\t\t);\n\t}\n\n\t// Ya cargado de forma síncrona (script tag directo)\n\tif (window.tapipay && !window.tapipay._q) {\n\t\treturn Promise.resolve(window.tapipay);\n\t}\n\n\t// Reutilizar promise existente (idempotencia por entorno)\n\tconst existing = loadPromises.get(env);\n\tif (existing) return existing;\n\n\tconst promise = new Promise<TapipayInstance>((resolve, reject) => {\n\t\t// Si ya hay un script inyectado, esperar a que cargue\n\t\tconst existingScript = document.getElementById(\n\t\t\tSCRIPT_ID,\n\t\t) as HTMLScriptElement | null;\n\n\t\tconst onLoad = () => {\n\t\t\tif (window.tapipay) {\n\t\t\t\tresolve(window.tapipay);\n\t\t\t} else {\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\"[TapiPay] El script cargó pero window.tapipay no está definido.\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onError = () => {\n\t\t\tloadPromises.delete(env);\n\t\t\treject(new Error(`[TapiPay] Error al cargar el SDK desde ${SDK_URL}`));\n\t\t};\n\n\t\tif (existingScript) {\n\t\t\texistingScript.addEventListener(\"load\", onLoad);\n\t\t\texistingScript.addEventListener(\"error\", onError);\n\t\t\treturn;\n\t\t}\n\n\t\tconst script = document.createElement(\"script\");\n\t\tscript.id = SCRIPT_ID;\n\t\tscript.src = SDK_URL;\n\t\tscript.async = true;\n\t\tscript.addEventListener(\"load\", onLoad);\n\t\tscript.addEventListener(\"error\", onError);\n\t\tdocument.head.appendChild(script);\n\t});\n\n\tloadPromises.set(env, promise);\n\treturn promise;\n}\n"],"mappings":";AAMA,IAAM,WAA+C;AAAA,EACpD,YAAY;AAAA,EACZ,MAAM;AACP;AAGA,IAAM,eAAe,oBAAI,IAAkD;AAkBpE,SAAS,YACf,SAC2B;AAhC5B;AAiCC,QAAM,OAA0B,wCAAS,gBAAT,YAAwB;AACxD,QAAM,UAAU,SAAS,GAAG;AAC5B,QAAM,YAAY,qBAAqB,GAAG;AAG1C,MAAI,OAAO,WAAW,aAAa;AAClC,WAAO,QAAQ;AAAA,MACd,IAAI,MAAM,yDAAyD;AAAA,IACpE;AAAA,EACD;AAGA,MAAI,OAAO,WAAW,CAAC,OAAO,QAAQ,IAAI;AACzC,WAAO,QAAQ,QAAQ,OAAO,OAAO;AAAA,EACtC;AAGA,QAAM,WAAW,aAAa,IAAI,GAAG;AACrC,MAAI,SAAU,QAAO;AAErB,QAAM,UAAU,IAAI,QAAyB,CAAC,SAAS,WAAW;AAEjE,UAAM,iBAAiB,SAAS;AAAA,MAC/B;AAAA,IACD;AAEA,UAAM,SAAS,MAAM;AACpB,UAAI,OAAO,SAAS;AACnB,gBAAQ,OAAO,OAAO;AAAA,MACvB,OAAO;AACN;AAAA,UACC,IAAI;AAAA,YACH;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,UAAU,MAAM;AACrB,mBAAa,OAAO,GAAG;AACvB,aAAO,IAAI,MAAM,0CAA0C,OAAO,EAAE,CAAC;AAAA,IACtE;AAEA,QAAI,gBAAgB;AACnB,qBAAe,iBAAiB,QAAQ,MAAM;AAC9C,qBAAe,iBAAiB,SAAS,OAAO;AAChD;AAAA,IACD;AAEA,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,KAAK;AACZ,WAAO,MAAM;AACb,WAAO,QAAQ;AACf,WAAO,iBAAiB,QAAQ,MAAM;AACtC,WAAO,iBAAiB,SAAS,OAAO;AACxC,aAAS,KAAK,YAAY,MAAM;AAAA,EACjC,CAAC;AAED,eAAa,IAAI,KAAK,OAAO;AAC7B,SAAO;AACR;","names":[]}
package/dist/index.cjs ADDED
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ loadTapipay: () => loadTapipay
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // src/loader.ts
28
+ var SDK_URLS = {
29
+ production: "https://app.tapipay.la/embed.js",
30
+ homo: "https://homo.tapipay.la/embed.js"
31
+ };
32
+ var loadPromises = /* @__PURE__ */ new Map();
33
+ function loadTapipay(options) {
34
+ var _a;
35
+ const env = (_a = options == null ? void 0 : options.environment) != null ? _a : "production";
36
+ const SDK_URL = SDK_URLS[env];
37
+ const SCRIPT_ID = `tapipay-embed-sdk-${env}`;
38
+ if (typeof window === "undefined") {
39
+ return Promise.reject(
40
+ new Error("[TapiPay] loadTapipay() requires a browser environment.")
41
+ );
42
+ }
43
+ if (window.tapipay && !window.tapipay._q) {
44
+ return Promise.resolve(window.tapipay);
45
+ }
46
+ const existing = loadPromises.get(env);
47
+ if (existing) return existing;
48
+ const promise = new Promise((resolve, reject) => {
49
+ const existingScript = document.getElementById(
50
+ SCRIPT_ID
51
+ );
52
+ const onLoad = () => {
53
+ if (window.tapipay) {
54
+ resolve(window.tapipay);
55
+ } else {
56
+ reject(
57
+ new Error(
58
+ "[TapiPay] El script carg\xF3 pero window.tapipay no est\xE1 definido."
59
+ )
60
+ );
61
+ }
62
+ };
63
+ const onError = () => {
64
+ loadPromises.delete(env);
65
+ reject(new Error(`[TapiPay] Error al cargar el SDK desde ${SDK_URL}`));
66
+ };
67
+ if (existingScript) {
68
+ existingScript.addEventListener("load", onLoad);
69
+ existingScript.addEventListener("error", onError);
70
+ return;
71
+ }
72
+ const script = document.createElement("script");
73
+ script.id = SCRIPT_ID;
74
+ script.src = SDK_URL;
75
+ script.async = true;
76
+ script.addEventListener("load", onLoad);
77
+ script.addEventListener("error", onError);
78
+ document.head.appendChild(script);
79
+ });
80
+ loadPromises.set(env, promise);
81
+ return promise;
82
+ }
83
+ // Annotate the CommonJS export names for ESM import in node:
84
+ 0 && (module.exports = {
85
+ loadTapipay
86
+ });
87
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/loader.ts"],"sourcesContent":["export { loadTapipay } from \"./loader\";\nexport type {\n\tLoadTapipayOptions,\n\tTapipayEnvironment,\n\tTapipayInstance,\n\tTapipayOptions,\n\tTapipayPaymentCancelledEvent,\n\tTapipayPaymentPendingEvent,\n} from \"./types\";\n","import type {\n\tLoadTapipayOptions,\n\tTapipayEnvironment,\n\tTapipayInstance,\n} from \"./types\";\n\nconst SDK_URLS: Record<TapipayEnvironment, string> = {\n\tproduction: \"https://app.tapipay.la/embed.js\",\n\thomo: \"https://homo.tapipay.la/embed.js\",\n};\n\n// Idempotencia por entorno\nconst loadPromises = new Map<TapipayEnvironment, Promise<TapipayInstance>>();\n\n/**\n * Carga el SDK de TapiPay de forma asíncrona inyectando el script en el DOM.\n *\n * - Idempotente por entorno: múltiples llamadas con el mismo `environment` retornan la misma Promise.\n * - Si window.tapipay ya existe (script cargado sync), resuelve inmediatamente.\n * - Compatible con React Strict Mode (doble mount/unmount).\n *\n * @example\n * // Producción (default)\n * const tapipay = await loadTapipay();\n *\n * // Homologación\n * const tapipay = await loadTapipay({ environment: 'homo' });\n *\n * tapipay.initialize({ container: \"#widget\", organization: \"acme\", identifier: \"CLI-001\" });\n */\nexport function loadTapipay(\n\toptions?: LoadTapipayOptions,\n): Promise<TapipayInstance> {\n\tconst env: TapipayEnvironment = options?.environment ?? \"production\";\n\tconst SDK_URL = SDK_URLS[env];\n\tconst SCRIPT_ID = `tapipay-embed-sdk-${env}`;\n\n\t// SSR guard\n\tif (typeof window === \"undefined\") {\n\t\treturn Promise.reject(\n\t\t\tnew Error(\"[TapiPay] loadTapipay() requires a browser environment.\"),\n\t\t);\n\t}\n\n\t// Ya cargado de forma síncrona (script tag directo)\n\tif (window.tapipay && !window.tapipay._q) {\n\t\treturn Promise.resolve(window.tapipay);\n\t}\n\n\t// Reutilizar promise existente (idempotencia por entorno)\n\tconst existing = loadPromises.get(env);\n\tif (existing) return existing;\n\n\tconst promise = new Promise<TapipayInstance>((resolve, reject) => {\n\t\t// Si ya hay un script inyectado, esperar a que cargue\n\t\tconst existingScript = document.getElementById(\n\t\t\tSCRIPT_ID,\n\t\t) as HTMLScriptElement | null;\n\n\t\tconst onLoad = () => {\n\t\t\tif (window.tapipay) {\n\t\t\t\tresolve(window.tapipay);\n\t\t\t} else {\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\"[TapiPay] El script cargó pero window.tapipay no está definido.\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onError = () => {\n\t\t\tloadPromises.delete(env);\n\t\t\treject(new Error(`[TapiPay] Error al cargar el SDK desde ${SDK_URL}`));\n\t\t};\n\n\t\tif (existingScript) {\n\t\t\texistingScript.addEventListener(\"load\", onLoad);\n\t\t\texistingScript.addEventListener(\"error\", onError);\n\t\t\treturn;\n\t\t}\n\n\t\tconst script = document.createElement(\"script\");\n\t\tscript.id = SCRIPT_ID;\n\t\tscript.src = SDK_URL;\n\t\tscript.async = true;\n\t\tscript.addEventListener(\"load\", onLoad);\n\t\tscript.addEventListener(\"error\", onError);\n\t\tdocument.head.appendChild(script);\n\t});\n\n\tloadPromises.set(env, promise);\n\treturn promise;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMA,IAAM,WAA+C;AAAA,EACpD,YAAY;AAAA,EACZ,MAAM;AACP;AAGA,IAAM,eAAe,oBAAI,IAAkD;AAkBpE,SAAS,YACf,SAC2B;AAhC5B;AAiCC,QAAM,OAA0B,wCAAS,gBAAT,YAAwB;AACxD,QAAM,UAAU,SAAS,GAAG;AAC5B,QAAM,YAAY,qBAAqB,GAAG;AAG1C,MAAI,OAAO,WAAW,aAAa;AAClC,WAAO,QAAQ;AAAA,MACd,IAAI,MAAM,yDAAyD;AAAA,IACpE;AAAA,EACD;AAGA,MAAI,OAAO,WAAW,CAAC,OAAO,QAAQ,IAAI;AACzC,WAAO,QAAQ,QAAQ,OAAO,OAAO;AAAA,EACtC;AAGA,QAAM,WAAW,aAAa,IAAI,GAAG;AACrC,MAAI,SAAU,QAAO;AAErB,QAAM,UAAU,IAAI,QAAyB,CAAC,SAAS,WAAW;AAEjE,UAAM,iBAAiB,SAAS;AAAA,MAC/B;AAAA,IACD;AAEA,UAAM,SAAS,MAAM;AACpB,UAAI,OAAO,SAAS;AACnB,gBAAQ,OAAO,OAAO;AAAA,MACvB,OAAO;AACN;AAAA,UACC,IAAI;AAAA,YACH;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,UAAU,MAAM;AACrB,mBAAa,OAAO,GAAG;AACvB,aAAO,IAAI,MAAM,0CAA0C,OAAO,EAAE,CAAC;AAAA,IACtE;AAEA,QAAI,gBAAgB;AACnB,qBAAe,iBAAiB,QAAQ,MAAM;AAC9C,qBAAe,iBAAiB,SAAS,OAAO;AAChD;AAAA,IACD;AAEA,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,KAAK;AACZ,WAAO,MAAM;AACb,WAAO,QAAQ;AACf,WAAO,iBAAiB,QAAQ,MAAM;AACtC,WAAO,iBAAiB,SAAS,OAAO;AACxC,aAAS,KAAK,YAAY,MAAM;AAAA,EACjC,CAAC;AAED,eAAa,IAAI,KAAK,OAAO;AAC7B,SAAO;AACR;","names":[]}
@@ -0,0 +1,22 @@
1
+ import { L as LoadTapipayOptions, T as TapipayInstance } from './types-DmkYbkBI.cjs';
2
+ export { a as TapipayEnvironment, b as TapipayOptions, c as TapipayPaymentCancelledEvent, d as TapipayPaymentPendingEvent } from './types-DmkYbkBI.cjs';
3
+
4
+ /**
5
+ * Carga el SDK de TapiPay de forma asíncrona inyectando el script en el DOM.
6
+ *
7
+ * - Idempotente por entorno: múltiples llamadas con el mismo `environment` retornan la misma Promise.
8
+ * - Si window.tapipay ya existe (script cargado sync), resuelve inmediatamente.
9
+ * - Compatible con React Strict Mode (doble mount/unmount).
10
+ *
11
+ * @example
12
+ * // Producción (default)
13
+ * const tapipay = await loadTapipay();
14
+ *
15
+ * // Homologación
16
+ * const tapipay = await loadTapipay({ environment: 'homo' });
17
+ *
18
+ * tapipay.initialize({ container: "#widget", organization: "acme", identifier: "CLI-001" });
19
+ */
20
+ declare function loadTapipay(options?: LoadTapipayOptions): Promise<TapipayInstance>;
21
+
22
+ export { LoadTapipayOptions, TapipayInstance, loadTapipay };
@@ -0,0 +1,22 @@
1
+ import { L as LoadTapipayOptions, T as TapipayInstance } from './types-DmkYbkBI.js';
2
+ export { a as TapipayEnvironment, b as TapipayOptions, c as TapipayPaymentCancelledEvent, d as TapipayPaymentPendingEvent } from './types-DmkYbkBI.js';
3
+
4
+ /**
5
+ * Carga el SDK de TapiPay de forma asíncrona inyectando el script en el DOM.
6
+ *
7
+ * - Idempotente por entorno: múltiples llamadas con el mismo `environment` retornan la misma Promise.
8
+ * - Si window.tapipay ya existe (script cargado sync), resuelve inmediatamente.
9
+ * - Compatible con React Strict Mode (doble mount/unmount).
10
+ *
11
+ * @example
12
+ * // Producción (default)
13
+ * const tapipay = await loadTapipay();
14
+ *
15
+ * // Homologación
16
+ * const tapipay = await loadTapipay({ environment: 'homo' });
17
+ *
18
+ * tapipay.initialize({ container: "#widget", organization: "acme", identifier: "CLI-001" });
19
+ */
20
+ declare function loadTapipay(options?: LoadTapipayOptions): Promise<TapipayInstance>;
21
+
22
+ export { LoadTapipayOptions, TapipayInstance, loadTapipay };
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import {
2
+ loadTapipay
3
+ } from "./chunk-2WNQZXMS.js";
4
+ export {
5
+ loadTapipay
6
+ };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/react.cjs ADDED
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/react.tsx
21
+ var react_exports = {};
22
+ __export(react_exports, {
23
+ TapipayWidget: () => TapipayWidget,
24
+ useTapipay: () => useTapipay
25
+ });
26
+ module.exports = __toCommonJS(react_exports);
27
+ var import_react = require("react");
28
+
29
+ // src/loader.ts
30
+ var SDK_URLS = {
31
+ production: "https://app.tapipay.la/embed.js",
32
+ homo: "https://homo.tapipay.la/embed.js"
33
+ };
34
+ var loadPromises = /* @__PURE__ */ new Map();
35
+ function loadTapipay(options) {
36
+ var _a;
37
+ const env = (_a = options == null ? void 0 : options.environment) != null ? _a : "production";
38
+ const SDK_URL = SDK_URLS[env];
39
+ const SCRIPT_ID = `tapipay-embed-sdk-${env}`;
40
+ if (typeof window === "undefined") {
41
+ return Promise.reject(
42
+ new Error("[TapiPay] loadTapipay() requires a browser environment.")
43
+ );
44
+ }
45
+ if (window.tapipay && !window.tapipay._q) {
46
+ return Promise.resolve(window.tapipay);
47
+ }
48
+ const existing = loadPromises.get(env);
49
+ if (existing) return existing;
50
+ const promise = new Promise((resolve, reject) => {
51
+ const existingScript = document.getElementById(
52
+ SCRIPT_ID
53
+ );
54
+ const onLoad = () => {
55
+ if (window.tapipay) {
56
+ resolve(window.tapipay);
57
+ } else {
58
+ reject(
59
+ new Error(
60
+ "[TapiPay] El script carg\xF3 pero window.tapipay no est\xE1 definido."
61
+ )
62
+ );
63
+ }
64
+ };
65
+ const onError = () => {
66
+ loadPromises.delete(env);
67
+ reject(new Error(`[TapiPay] Error al cargar el SDK desde ${SDK_URL}`));
68
+ };
69
+ if (existingScript) {
70
+ existingScript.addEventListener("load", onLoad);
71
+ existingScript.addEventListener("error", onError);
72
+ return;
73
+ }
74
+ const script = document.createElement("script");
75
+ script.id = SCRIPT_ID;
76
+ script.src = SDK_URL;
77
+ script.async = true;
78
+ script.addEventListener("load", onLoad);
79
+ script.addEventListener("error", onError);
80
+ document.head.appendChild(script);
81
+ });
82
+ loadPromises.set(env, promise);
83
+ return promise;
84
+ }
85
+
86
+ // src/react.tsx
87
+ var import_jsx_runtime = require("react/jsx-runtime");
88
+ function useTapipay(options) {
89
+ const [tapipay, setTapipay] = (0, import_react.useState)(null);
90
+ const [error, setError] = (0, import_react.useState)(null);
91
+ const environment = options == null ? void 0 : options.environment;
92
+ (0, import_react.useEffect)(() => {
93
+ let cancelled = false;
94
+ loadTapipay({ environment }).then((instance) => {
95
+ if (!cancelled) setTapipay(instance);
96
+ }).catch((err) => {
97
+ if (!cancelled) setError(err);
98
+ });
99
+ return () => {
100
+ cancelled = true;
101
+ };
102
+ }, [environment]);
103
+ return { tapipay, error };
104
+ }
105
+ function TapipayWidget({
106
+ organization,
107
+ identifier,
108
+ externalRequestId,
109
+ selectionStrategy,
110
+ environment,
111
+ onPending,
112
+ onCancelled,
113
+ className,
114
+ style
115
+ }) {
116
+ const containerRef = (0, import_react.useRef)(null);
117
+ const onPendingRef = (0, import_react.useRef)(onPending);
118
+ const onCancelledRef = (0, import_react.useRef)(onCancelled);
119
+ (0, import_react.useEffect)(() => {
120
+ onPendingRef.current = onPending;
121
+ }, [onPending]);
122
+ (0, import_react.useEffect)(() => {
123
+ onCancelledRef.current = onCancelled;
124
+ }, [onCancelled]);
125
+ (0, import_react.useEffect)(() => {
126
+ if (!containerRef.current) return;
127
+ const container = containerRef.current;
128
+ let tapipayInstance = null;
129
+ let cancelled = false;
130
+ const handlePending = (data) => {
131
+ var _a;
132
+ (_a = onPendingRef.current) == null ? void 0 : _a.call(onPendingRef, data);
133
+ };
134
+ const handleCancelled = (data) => {
135
+ var _a;
136
+ (_a = onCancelledRef.current) == null ? void 0 : _a.call(onCancelledRef, data);
137
+ };
138
+ loadTapipay({ environment }).then((instance) => {
139
+ if (cancelled) return;
140
+ tapipayInstance = instance;
141
+ instance.on("paymentPending", handlePending);
142
+ instance.on("paymentCancelled", handleCancelled);
143
+ instance.initialize({
144
+ container,
145
+ organization,
146
+ identifier,
147
+ externalRequestId,
148
+ selectionStrategy
149
+ });
150
+ });
151
+ return () => {
152
+ cancelled = true;
153
+ if (tapipayInstance) {
154
+ tapipayInstance.off("paymentPending", handlePending);
155
+ tapipayInstance.off("paymentCancelled", handleCancelled);
156
+ tapipayInstance.destroy(container);
157
+ }
158
+ };
159
+ }, [
160
+ organization,
161
+ identifier,
162
+ externalRequestId,
163
+ selectionStrategy,
164
+ environment
165
+ ]);
166
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: containerRef, className, style });
167
+ }
168
+ // Annotate the CommonJS export names for ESM import in node:
169
+ 0 && (module.exports = {
170
+ TapipayWidget,
171
+ useTapipay
172
+ });
173
+ //# sourceMappingURL=react.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react.tsx","../src/loader.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { loadTapipay } from \"./loader\";\nimport type {\n\tLoadTapipayOptions,\n\tTapipayEnvironment,\n\tTapipayInstance,\n\tTapipayOptions,\n\tTapipayPaymentCancelledEvent,\n\tTapipayPaymentPendingEvent,\n} from \"./types\";\n\n// ─── useTapipay hook ──────────────────────────────────────────────────────────\n\n/**\n * Hook de bajo nivel que carga el SDK y retorna la instancia.\n * Útil cuando necesitas control manual sobre initialize/destroy.\n *\n * @example\n * const { tapipay, error } = useTapipay();\n * const { tapipay, error } = useTapipay({ environment: 'homo' });\n */\nexport function useTapipay(options?: LoadTapipayOptions): {\n\ttapipay: TapipayInstance | null;\n\terror: Error | null;\n} {\n\tconst [tapipay, setTapipay] = useState<TapipayInstance | null>(null);\n\tconst [error, setError] = useState<Error | null>(null);\n\tconst environment = options?.environment;\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\t\tloadTapipay({ environment })\n\t\t\t.then((instance) => {\n\t\t\t\tif (!cancelled) setTapipay(instance);\n\t\t\t})\n\t\t\t.catch((err: Error) => {\n\t\t\t\tif (!cancelled) setError(err);\n\t\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [environment]);\n\n\treturn { tapipay, error };\n}\n\n// ─── TapipayWidget component ──────────────────────────────────────────────────\n\nexport interface TapipayWidgetProps extends Omit<TapipayOptions, \"container\"> {\n\t/** Entorno del SDK a cargar. Por defecto `'production'`. Usar `'homo'` para homologación. */\n\tenvironment?: TapipayEnvironment;\n\t/** Callback invocado cuando Yuno redirige al callback (pago en proceso). */\n\tonPending?: (data: TapipayPaymentPendingEvent) => void;\n\t/** Callback invocado cuando el usuario cierra el popup sin completar el pago. */\n\tonCancelled?: (data: TapipayPaymentCancelledEvent) => void;\n\t/** Clases CSS adicionales para el contenedor del widget. */\n\tclassName?: string;\n\t/** Estilos inline adicionales para el contenedor del widget. */\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * Componente React que encapsula el widget de pago TapiPay.\n *\n * Maneja internamente la carga del SDK, el ciclo de vida del widget\n * y el cleanup al desmontar. Compatible con React Strict Mode.\n *\n * @example\n * <TapipayWidget\n * organization=\"acme\"\n * identifier=\"CLI-001\"\n * externalRequestId=\"FAC-2024-001\"\n * onPending={(data) => console.log(\"Pago en proceso\", data)}\n * onCancelled={() => console.log(\"Pago cancelado por el usuario\")}\n * />\n */\nexport function TapipayWidget({\n\torganization,\n\tidentifier,\n\texternalRequestId,\n\tselectionStrategy,\n\tenvironment,\n\tonPending,\n\tonCancelled,\n\tclassName,\n\tstyle,\n}: TapipayWidgetProps) {\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\t// Refs para evitar re-renders innecesarios y closures estáticos en useEffect\n\tconst onPendingRef = useRef(onPending);\n\tconst onCancelledRef = useRef(onCancelled);\n\n\tuseEffect(() => {\n\t\tonPendingRef.current = onPending;\n\t}, [onPending]);\n\n\tuseEffect(() => {\n\t\tonCancelledRef.current = onCancelled;\n\t}, [onCancelled]);\n\n\tuseEffect(() => {\n\t\tif (!containerRef.current) return;\n\t\tconst container = containerRef.current;\n\n\t\tlet tapipayInstance: TapipayInstance | null = null;\n\t\tlet cancelled = false;\n\n\t\tconst handlePending = (data: TapipayPaymentPendingEvent) => {\n\t\t\tonPendingRef.current?.(data);\n\t\t};\n\t\tconst handleCancelled = (data: TapipayPaymentCancelledEvent) => {\n\t\t\tonCancelledRef.current?.(data);\n\t\t};\n\n\t\tloadTapipay({ environment }).then((instance) => {\n\t\t\tif (cancelled) return;\n\t\t\ttapipayInstance = instance;\n\n\t\t\tinstance.on(\"paymentPending\", handlePending);\n\t\t\tinstance.on(\"paymentCancelled\", handleCancelled);\n\n\t\t\tinstance.initialize({\n\t\t\t\tcontainer,\n\t\t\t\torganization,\n\t\t\t\tidentifier,\n\t\t\t\texternalRequestId,\n\t\t\t\tselectionStrategy,\n\t\t\t});\n\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t\tif (tapipayInstance) {\n\t\t\t\ttapipayInstance.off(\"paymentPending\", handlePending);\n\t\t\t\ttapipayInstance.off(\"paymentCancelled\", handleCancelled);\n\t\t\t\ttapipayInstance.destroy(container);\n\t\t\t}\n\t\t};\n\t\t// El widget se re-monta si cambian los parámetros de identificación o entorno\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [\n\t\torganization,\n\t\tidentifier,\n\t\texternalRequestId,\n\t\tselectionStrategy,\n\t\tenvironment,\n\t]);\n\n\treturn <div ref={containerRef} className={className} style={style} />;\n}\n","import type {\n\tLoadTapipayOptions,\n\tTapipayEnvironment,\n\tTapipayInstance,\n} from \"./types\";\n\nconst SDK_URLS: Record<TapipayEnvironment, string> = {\n\tproduction: \"https://app.tapipay.la/embed.js\",\n\thomo: \"https://homo.tapipay.la/embed.js\",\n};\n\n// Idempotencia por entorno\nconst loadPromises = new Map<TapipayEnvironment, Promise<TapipayInstance>>();\n\n/**\n * Carga el SDK de TapiPay de forma asíncrona inyectando el script en el DOM.\n *\n * - Idempotente por entorno: múltiples llamadas con el mismo `environment` retornan la misma Promise.\n * - Si window.tapipay ya existe (script cargado sync), resuelve inmediatamente.\n * - Compatible con React Strict Mode (doble mount/unmount).\n *\n * @example\n * // Producción (default)\n * const tapipay = await loadTapipay();\n *\n * // Homologación\n * const tapipay = await loadTapipay({ environment: 'homo' });\n *\n * tapipay.initialize({ container: \"#widget\", organization: \"acme\", identifier: \"CLI-001\" });\n */\nexport function loadTapipay(\n\toptions?: LoadTapipayOptions,\n): Promise<TapipayInstance> {\n\tconst env: TapipayEnvironment = options?.environment ?? \"production\";\n\tconst SDK_URL = SDK_URLS[env];\n\tconst SCRIPT_ID = `tapipay-embed-sdk-${env}`;\n\n\t// SSR guard\n\tif (typeof window === \"undefined\") {\n\t\treturn Promise.reject(\n\t\t\tnew Error(\"[TapiPay] loadTapipay() requires a browser environment.\"),\n\t\t);\n\t}\n\n\t// Ya cargado de forma síncrona (script tag directo)\n\tif (window.tapipay && !window.tapipay._q) {\n\t\treturn Promise.resolve(window.tapipay);\n\t}\n\n\t// Reutilizar promise existente (idempotencia por entorno)\n\tconst existing = loadPromises.get(env);\n\tif (existing) return existing;\n\n\tconst promise = new Promise<TapipayInstance>((resolve, reject) => {\n\t\t// Si ya hay un script inyectado, esperar a que cargue\n\t\tconst existingScript = document.getElementById(\n\t\t\tSCRIPT_ID,\n\t\t) as HTMLScriptElement | null;\n\n\t\tconst onLoad = () => {\n\t\t\tif (window.tapipay) {\n\t\t\t\tresolve(window.tapipay);\n\t\t\t} else {\n\t\t\t\treject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\"[TapiPay] El script cargó pero window.tapipay no está definido.\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onError = () => {\n\t\t\tloadPromises.delete(env);\n\t\t\treject(new Error(`[TapiPay] Error al cargar el SDK desde ${SDK_URL}`));\n\t\t};\n\n\t\tif (existingScript) {\n\t\t\texistingScript.addEventListener(\"load\", onLoad);\n\t\t\texistingScript.addEventListener(\"error\", onError);\n\t\t\treturn;\n\t\t}\n\n\t\tconst script = document.createElement(\"script\");\n\t\tscript.id = SCRIPT_ID;\n\t\tscript.src = SDK_URL;\n\t\tscript.async = true;\n\t\tscript.addEventListener(\"load\", onLoad);\n\t\tscript.addEventListener(\"error\", onError);\n\t\tdocument.head.appendChild(script);\n\t});\n\n\tloadPromises.set(env, promise);\n\treturn promise;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,45 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { b as TapipayOptions, a as TapipayEnvironment, d as TapipayPaymentPendingEvent, c as TapipayPaymentCancelledEvent, L as LoadTapipayOptions, T as TapipayInstance } from './types-DmkYbkBI.cjs';
3
+
4
+ /**
5
+ * Hook de bajo nivel que carga el SDK y retorna la instancia.
6
+ * Útil cuando necesitas control manual sobre initialize/destroy.
7
+ *
8
+ * @example
9
+ * const { tapipay, error } = useTapipay();
10
+ * const { tapipay, error } = useTapipay({ environment: 'homo' });
11
+ */
12
+ declare function useTapipay(options?: LoadTapipayOptions): {
13
+ tapipay: TapipayInstance | null;
14
+ error: Error | null;
15
+ };
16
+ interface TapipayWidgetProps extends Omit<TapipayOptions, "container"> {
17
+ /** Entorno del SDK a cargar. Por defecto `'production'`. Usar `'homo'` para homologación. */
18
+ environment?: TapipayEnvironment;
19
+ /** Callback invocado cuando Yuno redirige al callback (pago en proceso). */
20
+ onPending?: (data: TapipayPaymentPendingEvent) => void;
21
+ /** Callback invocado cuando el usuario cierra el popup sin completar el pago. */
22
+ onCancelled?: (data: TapipayPaymentCancelledEvent) => void;
23
+ /** Clases CSS adicionales para el contenedor del widget. */
24
+ className?: string;
25
+ /** Estilos inline adicionales para el contenedor del widget. */
26
+ style?: React.CSSProperties;
27
+ }
28
+ /**
29
+ * Componente React que encapsula el widget de pago TapiPay.
30
+ *
31
+ * Maneja internamente la carga del SDK, el ciclo de vida del widget
32
+ * y el cleanup al desmontar. Compatible con React Strict Mode.
33
+ *
34
+ * @example
35
+ * <TapipayWidget
36
+ * organization="acme"
37
+ * identifier="CLI-001"
38
+ * externalRequestId="FAC-2024-001"
39
+ * onPending={(data) => console.log("Pago en proceso", data)}
40
+ * onCancelled={() => console.log("Pago cancelado por el usuario")}
41
+ * />
42
+ */
43
+ declare function TapipayWidget({ organization, identifier, externalRequestId, selectionStrategy, environment, onPending, onCancelled, className, style, }: TapipayWidgetProps): react_jsx_runtime.JSX.Element;
44
+
45
+ export { TapipayWidget, type TapipayWidgetProps, useTapipay };
@@ -0,0 +1,45 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { b as TapipayOptions, a as TapipayEnvironment, d as TapipayPaymentPendingEvent, c as TapipayPaymentCancelledEvent, L as LoadTapipayOptions, T as TapipayInstance } from './types-DmkYbkBI.js';
3
+
4
+ /**
5
+ * Hook de bajo nivel que carga el SDK y retorna la instancia.
6
+ * Útil cuando necesitas control manual sobre initialize/destroy.
7
+ *
8
+ * @example
9
+ * const { tapipay, error } = useTapipay();
10
+ * const { tapipay, error } = useTapipay({ environment: 'homo' });
11
+ */
12
+ declare function useTapipay(options?: LoadTapipayOptions): {
13
+ tapipay: TapipayInstance | null;
14
+ error: Error | null;
15
+ };
16
+ interface TapipayWidgetProps extends Omit<TapipayOptions, "container"> {
17
+ /** Entorno del SDK a cargar. Por defecto `'production'`. Usar `'homo'` para homologación. */
18
+ environment?: TapipayEnvironment;
19
+ /** Callback invocado cuando Yuno redirige al callback (pago en proceso). */
20
+ onPending?: (data: TapipayPaymentPendingEvent) => void;
21
+ /** Callback invocado cuando el usuario cierra el popup sin completar el pago. */
22
+ onCancelled?: (data: TapipayPaymentCancelledEvent) => void;
23
+ /** Clases CSS adicionales para el contenedor del widget. */
24
+ className?: string;
25
+ /** Estilos inline adicionales para el contenedor del widget. */
26
+ style?: React.CSSProperties;
27
+ }
28
+ /**
29
+ * Componente React que encapsula el widget de pago TapiPay.
30
+ *
31
+ * Maneja internamente la carga del SDK, el ciclo de vida del widget
32
+ * y el cleanup al desmontar. Compatible con React Strict Mode.
33
+ *
34
+ * @example
35
+ * <TapipayWidget
36
+ * organization="acme"
37
+ * identifier="CLI-001"
38
+ * externalRequestId="FAC-2024-001"
39
+ * onPending={(data) => console.log("Pago en proceso", data)}
40
+ * onCancelled={() => console.log("Pago cancelado por el usuario")}
41
+ * />
42
+ */
43
+ declare function TapipayWidget({ organization, identifier, externalRequestId, selectionStrategy, environment, onPending, onCancelled, className, style, }: TapipayWidgetProps): react_jsx_runtime.JSX.Element;
44
+
45
+ export { TapipayWidget, type TapipayWidgetProps, useTapipay };
package/dist/react.js ADDED
@@ -0,0 +1,92 @@
1
+ import {
2
+ loadTapipay
3
+ } from "./chunk-2WNQZXMS.js";
4
+
5
+ // src/react.tsx
6
+ import { useEffect, useRef, useState } from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+ function useTapipay(options) {
9
+ const [tapipay, setTapipay] = useState(null);
10
+ const [error, setError] = useState(null);
11
+ const environment = options == null ? void 0 : options.environment;
12
+ useEffect(() => {
13
+ let cancelled = false;
14
+ loadTapipay({ environment }).then((instance) => {
15
+ if (!cancelled) setTapipay(instance);
16
+ }).catch((err) => {
17
+ if (!cancelled) setError(err);
18
+ });
19
+ return () => {
20
+ cancelled = true;
21
+ };
22
+ }, [environment]);
23
+ return { tapipay, error };
24
+ }
25
+ function TapipayWidget({
26
+ organization,
27
+ identifier,
28
+ externalRequestId,
29
+ selectionStrategy,
30
+ environment,
31
+ onPending,
32
+ onCancelled,
33
+ className,
34
+ style
35
+ }) {
36
+ const containerRef = useRef(null);
37
+ const onPendingRef = useRef(onPending);
38
+ const onCancelledRef = useRef(onCancelled);
39
+ useEffect(() => {
40
+ onPendingRef.current = onPending;
41
+ }, [onPending]);
42
+ useEffect(() => {
43
+ onCancelledRef.current = onCancelled;
44
+ }, [onCancelled]);
45
+ useEffect(() => {
46
+ if (!containerRef.current) return;
47
+ const container = containerRef.current;
48
+ let tapipayInstance = null;
49
+ let cancelled = false;
50
+ const handlePending = (data) => {
51
+ var _a;
52
+ (_a = onPendingRef.current) == null ? void 0 : _a.call(onPendingRef, data);
53
+ };
54
+ const handleCancelled = (data) => {
55
+ var _a;
56
+ (_a = onCancelledRef.current) == null ? void 0 : _a.call(onCancelledRef, data);
57
+ };
58
+ loadTapipay({ environment }).then((instance) => {
59
+ if (cancelled) return;
60
+ tapipayInstance = instance;
61
+ instance.on("paymentPending", handlePending);
62
+ instance.on("paymentCancelled", handleCancelled);
63
+ instance.initialize({
64
+ container,
65
+ organization,
66
+ identifier,
67
+ externalRequestId,
68
+ selectionStrategy
69
+ });
70
+ });
71
+ return () => {
72
+ cancelled = true;
73
+ if (tapipayInstance) {
74
+ tapipayInstance.off("paymentPending", handlePending);
75
+ tapipayInstance.off("paymentCancelled", handleCancelled);
76
+ tapipayInstance.destroy(container);
77
+ }
78
+ };
79
+ }, [
80
+ organization,
81
+ identifier,
82
+ externalRequestId,
83
+ selectionStrategy,
84
+ environment
85
+ ]);
86
+ return /* @__PURE__ */ jsx("div", { ref: containerRef, className, style });
87
+ }
88
+ export {
89
+ TapipayWidget,
90
+ useTapipay
91
+ };
92
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { loadTapipay } from \"./loader\";\nimport type {\n\tLoadTapipayOptions,\n\tTapipayEnvironment,\n\tTapipayInstance,\n\tTapipayOptions,\n\tTapipayPaymentCancelledEvent,\n\tTapipayPaymentPendingEvent,\n} from \"./types\";\n\n// ─── useTapipay hook ──────────────────────────────────────────────────────────\n\n/**\n * Hook de bajo nivel que carga el SDK y retorna la instancia.\n * Útil cuando necesitas control manual sobre initialize/destroy.\n *\n * @example\n * const { tapipay, error } = useTapipay();\n * const { tapipay, error } = useTapipay({ environment: 'homo' });\n */\nexport function useTapipay(options?: LoadTapipayOptions): {\n\ttapipay: TapipayInstance | null;\n\terror: Error | null;\n} {\n\tconst [tapipay, setTapipay] = useState<TapipayInstance | null>(null);\n\tconst [error, setError] = useState<Error | null>(null);\n\tconst environment = options?.environment;\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\t\tloadTapipay({ environment })\n\t\t\t.then((instance) => {\n\t\t\t\tif (!cancelled) setTapipay(instance);\n\t\t\t})\n\t\t\t.catch((err: Error) => {\n\t\t\t\tif (!cancelled) setError(err);\n\t\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [environment]);\n\n\treturn { tapipay, error };\n}\n\n// ─── TapipayWidget component ──────────────────────────────────────────────────\n\nexport interface TapipayWidgetProps extends Omit<TapipayOptions, \"container\"> {\n\t/** Entorno del SDK a cargar. Por defecto `'production'`. Usar `'homo'` para homologación. */\n\tenvironment?: TapipayEnvironment;\n\t/** Callback invocado cuando Yuno redirige al callback (pago en proceso). */\n\tonPending?: (data: TapipayPaymentPendingEvent) => void;\n\t/** Callback invocado cuando el usuario cierra el popup sin completar el pago. */\n\tonCancelled?: (data: TapipayPaymentCancelledEvent) => void;\n\t/** Clases CSS adicionales para el contenedor del widget. */\n\tclassName?: string;\n\t/** Estilos inline adicionales para el contenedor del widget. */\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * Componente React que encapsula el widget de pago TapiPay.\n *\n * Maneja internamente la carga del SDK, el ciclo de vida del widget\n * y el cleanup al desmontar. Compatible con React Strict Mode.\n *\n * @example\n * <TapipayWidget\n * organization=\"acme\"\n * identifier=\"CLI-001\"\n * externalRequestId=\"FAC-2024-001\"\n * onPending={(data) => console.log(\"Pago en proceso\", data)}\n * onCancelled={() => console.log(\"Pago cancelado por el usuario\")}\n * />\n */\nexport function TapipayWidget({\n\torganization,\n\tidentifier,\n\texternalRequestId,\n\tselectionStrategy,\n\tenvironment,\n\tonPending,\n\tonCancelled,\n\tclassName,\n\tstyle,\n}: TapipayWidgetProps) {\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\t// Refs para evitar re-renders innecesarios y closures estáticos en useEffect\n\tconst onPendingRef = useRef(onPending);\n\tconst onCancelledRef = useRef(onCancelled);\n\n\tuseEffect(() => {\n\t\tonPendingRef.current = onPending;\n\t}, [onPending]);\n\n\tuseEffect(() => {\n\t\tonCancelledRef.current = onCancelled;\n\t}, [onCancelled]);\n\n\tuseEffect(() => {\n\t\tif (!containerRef.current) return;\n\t\tconst container = containerRef.current;\n\n\t\tlet tapipayInstance: TapipayInstance | null = null;\n\t\tlet cancelled = false;\n\n\t\tconst handlePending = (data: TapipayPaymentPendingEvent) => {\n\t\t\tonPendingRef.current?.(data);\n\t\t};\n\t\tconst handleCancelled = (data: TapipayPaymentCancelledEvent) => {\n\t\t\tonCancelledRef.current?.(data);\n\t\t};\n\n\t\tloadTapipay({ environment }).then((instance) => {\n\t\t\tif (cancelled) return;\n\t\t\ttapipayInstance = instance;\n\n\t\t\tinstance.on(\"paymentPending\", handlePending);\n\t\t\tinstance.on(\"paymentCancelled\", handleCancelled);\n\n\t\t\tinstance.initialize({\n\t\t\t\tcontainer,\n\t\t\t\torganization,\n\t\t\t\tidentifier,\n\t\t\t\texternalRequestId,\n\t\t\t\tselectionStrategy,\n\t\t\t});\n\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t\tif (tapipayInstance) {\n\t\t\t\ttapipayInstance.off(\"paymentPending\", handlePending);\n\t\t\t\ttapipayInstance.off(\"paymentCancelled\", handleCancelled);\n\t\t\t\ttapipayInstance.destroy(container);\n\t\t\t}\n\t\t};\n\t\t// El widget se re-monta si cambian los parámetros de identificación o entorno\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [\n\t\torganization,\n\t\tidentifier,\n\t\texternalRequestId,\n\t\tselectionStrategy,\n\t\tenvironment,\n\t]);\n\n\treturn <div ref={containerRef} className={className} style={style} />;\n}\n"],"mappings":";;;;;AAAA,SAAS,WAAW,QAAQ,gBAAgB;AAoJpC;AA/HD,SAAS,WAAW,SAGzB;AACD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAiC,IAAI;AACnE,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,IAAI;AACrD,QAAM,cAAc,mCAAS;AAE7B,YAAU,MAAM;AACf,QAAI,YAAY;AAChB,gBAAY,EAAE,YAAY,CAAC,EACzB,KAAK,CAAC,aAAa;AACnB,UAAI,CAAC,UAAW,YAAW,QAAQ;AAAA,IACpC,CAAC,EACA,MAAM,CAAC,QAAe;AACtB,UAAI,CAAC,UAAW,UAAS,GAAG;AAAA,IAC7B,CAAC;AACF,WAAO,MAAM;AACZ,kBAAY;AAAA,IACb;AAAA,EACD,GAAG,CAAC,WAAW,CAAC;AAEhB,SAAO,EAAE,SAAS,MAAM;AACzB;AAgCO,SAAS,cAAc;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAuB;AACtB,QAAM,eAAe,OAAuB,IAAI;AAEhD,QAAM,eAAe,OAAO,SAAS;AACrC,QAAM,iBAAiB,OAAO,WAAW;AAEzC,YAAU,MAAM;AACf,iBAAa,UAAU;AAAA,EACxB,GAAG,CAAC,SAAS,CAAC;AAEd,YAAU,MAAM;AACf,mBAAe,UAAU;AAAA,EAC1B,GAAG,CAAC,WAAW,CAAC;AAEhB,YAAU,MAAM;AACf,QAAI,CAAC,aAAa,QAAS;AAC3B,UAAM,YAAY,aAAa;AAE/B,QAAI,kBAA0C;AAC9C,QAAI,YAAY;AAEhB,UAAM,gBAAgB,CAAC,SAAqC;AA3G9D;AA4GG,yBAAa,YAAb,sCAAuB;AAAA,IACxB;AACA,UAAM,kBAAkB,CAAC,SAAuC;AA9GlE;AA+GG,2BAAe,YAAf,wCAAyB;AAAA,IAC1B;AAEA,gBAAY,EAAE,YAAY,CAAC,EAAE,KAAK,CAAC,aAAa;AAC/C,UAAI,UAAW;AACf,wBAAkB;AAElB,eAAS,GAAG,kBAAkB,aAAa;AAC3C,eAAS,GAAG,oBAAoB,eAAe;AAE/C,eAAS,WAAW;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD,CAAC;AAAA,IACF,CAAC;AAED,WAAO,MAAM;AACZ,kBAAY;AACZ,UAAI,iBAAiB;AACpB,wBAAgB,IAAI,kBAAkB,aAAa;AACnD,wBAAgB,IAAI,oBAAoB,eAAe;AACvD,wBAAgB,QAAQ,SAAS;AAAA,MAClC;AAAA,IACD;AAAA,EAGD,GAAG;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,CAAC;AAED,SAAO,oBAAC,SAAI,KAAK,cAAc,WAAsB,OAAc;AACpE;","names":[]}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Entorno de ejecución del SDK.
3
+ * - `'production'`: carga desde https://app.tapipay.la/embed.js (default)
4
+ * - `'homo'`: carga desde https://homo.tapipay.la/embed.js
5
+ */
6
+ type TapipayEnvironment = "production" | "homo";
7
+ /**
8
+ * Opciones para `loadTapipay()`.
9
+ */
10
+ interface LoadTapipayOptions {
11
+ /**
12
+ * Entorno a usar. Por defecto `'production'`.
13
+ * Para homologación usar `'homo'`.
14
+ */
15
+ environment?: TapipayEnvironment;
16
+ }
17
+ /**
18
+ * Opciones requeridas para montar el widget TapiPay.
19
+ */
20
+ interface TapipayOptions {
21
+ /** Selector CSS o elemento DOM donde se montará el widget. */
22
+ container: string | HTMLElement;
23
+ /** Alias de la Organización configurado en el dashboard de TapiPay (ej. "acme"). Corresponde al campo "Alias" en Configuración → Organización. */
24
+ organization: string;
25
+ /** Identificador del cliente en el sistema del cliente (ej. "CLI-001"). */
26
+ identifier: string;
27
+ /** ID externo de la deuda a preseleccionar (ej. número de factura). */
28
+ externalRequestId?: string;
29
+ /** Estrategia de selección automática de deuda. */
30
+ selectionStrategy?: "oldestCreated";
31
+ }
32
+ /**
33
+ * Payload del evento paymentPending.
34
+ * El usuario completó el flujo de Yuno; el pago está en proceso.
35
+ * El estado real del pago se confirma vía webhooks en el backend.
36
+ */
37
+ interface TapipayPaymentPendingEvent {
38
+ /** Siempre "TAPIPAY_CALLBACK" */
39
+ type: string;
40
+ /** Estado del pago: siempre "pending" */
41
+ status: "pending";
42
+ /** Parámetros que Yuno haya enviado al callback (pueden estar vacíos) */
43
+ data: Record<string, string>;
44
+ }
45
+ /**
46
+ * Payload del evento paymentCancelled.
47
+ * El usuario cerró el popup sin completar el flujo de pago.
48
+ */
49
+ type TapipayPaymentCancelledEvent = {};
50
+ /**
51
+ * Instancia del SDK TapiPay expuesta en window.tapipay y retornada por loadTapipay().
52
+ */
53
+ interface TapipayInstance {
54
+ initialize(options: TapipayOptions): void;
55
+ destroy(container: string | HTMLElement): void;
56
+ on(event: "paymentPending", handler: (data: TapipayPaymentPendingEvent) => void): void;
57
+ on(event: "paymentCancelled", handler: (data: TapipayPaymentCancelledEvent) => void): void;
58
+ off(event: "paymentPending", handler: (data: TapipayPaymentPendingEvent) => void): void;
59
+ off(event: "paymentCancelled", handler: (data: TapipayPaymentCancelledEvent) => void): void;
60
+ off(event: string, handler: (...args: unknown[]) => unknown): void;
61
+ /** Cola interna usada por el stub antes de que cargue el SDK real. */
62
+ _q?: [string, unknown[]][];
63
+ }
64
+ declare global {
65
+ interface Window {
66
+ tapipay?: TapipayInstance;
67
+ }
68
+ }
69
+
70
+ export type { LoadTapipayOptions as L, TapipayInstance as T, TapipayEnvironment as a, TapipayOptions as b, TapipayPaymentCancelledEvent as c, TapipayPaymentPendingEvent as d };
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Entorno de ejecución del SDK.
3
+ * - `'production'`: carga desde https://app.tapipay.la/embed.js (default)
4
+ * - `'homo'`: carga desde https://homo.tapipay.la/embed.js
5
+ */
6
+ type TapipayEnvironment = "production" | "homo";
7
+ /**
8
+ * Opciones para `loadTapipay()`.
9
+ */
10
+ interface LoadTapipayOptions {
11
+ /**
12
+ * Entorno a usar. Por defecto `'production'`.
13
+ * Para homologación usar `'homo'`.
14
+ */
15
+ environment?: TapipayEnvironment;
16
+ }
17
+ /**
18
+ * Opciones requeridas para montar el widget TapiPay.
19
+ */
20
+ interface TapipayOptions {
21
+ /** Selector CSS o elemento DOM donde se montará el widget. */
22
+ container: string | HTMLElement;
23
+ /** Alias de la Organización configurado en el dashboard de TapiPay (ej. "acme"). Corresponde al campo "Alias" en Configuración → Organización. */
24
+ organization: string;
25
+ /** Identificador del cliente en el sistema del cliente (ej. "CLI-001"). */
26
+ identifier: string;
27
+ /** ID externo de la deuda a preseleccionar (ej. número de factura). */
28
+ externalRequestId?: string;
29
+ /** Estrategia de selección automática de deuda. */
30
+ selectionStrategy?: "oldestCreated";
31
+ }
32
+ /**
33
+ * Payload del evento paymentPending.
34
+ * El usuario completó el flujo de Yuno; el pago está en proceso.
35
+ * El estado real del pago se confirma vía webhooks en el backend.
36
+ */
37
+ interface TapipayPaymentPendingEvent {
38
+ /** Siempre "TAPIPAY_CALLBACK" */
39
+ type: string;
40
+ /** Estado del pago: siempre "pending" */
41
+ status: "pending";
42
+ /** Parámetros que Yuno haya enviado al callback (pueden estar vacíos) */
43
+ data: Record<string, string>;
44
+ }
45
+ /**
46
+ * Payload del evento paymentCancelled.
47
+ * El usuario cerró el popup sin completar el flujo de pago.
48
+ */
49
+ type TapipayPaymentCancelledEvent = {};
50
+ /**
51
+ * Instancia del SDK TapiPay expuesta en window.tapipay y retornada por loadTapipay().
52
+ */
53
+ interface TapipayInstance {
54
+ initialize(options: TapipayOptions): void;
55
+ destroy(container: string | HTMLElement): void;
56
+ on(event: "paymentPending", handler: (data: TapipayPaymentPendingEvent) => void): void;
57
+ on(event: "paymentCancelled", handler: (data: TapipayPaymentCancelledEvent) => void): void;
58
+ off(event: "paymentPending", handler: (data: TapipayPaymentPendingEvent) => void): void;
59
+ off(event: "paymentCancelled", handler: (data: TapipayPaymentCancelledEvent) => void): void;
60
+ off(event: string, handler: (...args: unknown[]) => unknown): void;
61
+ /** Cola interna usada por el stub antes de que cargue el SDK real. */
62
+ _q?: [string, unknown[]][];
63
+ }
64
+ declare global {
65
+ interface Window {
66
+ tapipay?: TapipayInstance;
67
+ }
68
+ }
69
+
70
+ export type { LoadTapipayOptions as L, TapipayInstance as T, TapipayEnvironment as a, TapipayOptions as b, TapipayPaymentCancelledEvent as c, TapipayPaymentPendingEvent as d };
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@npmtapi/embed",
3
+ "version": "1.0.0",
4
+ "description": "TapiPay Embed SDK — carga y controla el widget de pago embebido",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js",
10
+ "require": "./dist/index.cjs"
11
+ },
12
+ "./react": {
13
+ "types": "./dist/react.d.ts",
14
+ "import": "./dist/react.js",
15
+ "require": "./dist/react.cjs"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "dev": "tsup --watch",
24
+ "prepublishOnly": "pnpm build"
25
+ },
26
+ "author": "tapipay",
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "peerDependencies": {
31
+ "react": ">=18"
32
+ },
33
+ "peerDependenciesMeta": {
34
+ "react": {
35
+ "optional": true
36
+ }
37
+ },
38
+ "devDependencies": {
39
+ "@types/react": "^18.0.0",
40
+ "react": "^18.0.0",
41
+ "tsup": "^8.0.0",
42
+ "typescript": "^5.0.0"
43
+ }
44
+ }