ipagos-js-sdk 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,150 @@
1
+ # iPagos SDK
2
+
3
+ Bienvenido al ecosistema de **iPagos**.
4
+
5
+ iPagos provee librerías oficiales que permiten integrar tu afiliación
6
+ mediante tu **MID** y **API Keys**, habilitando la aceptación de pagos
7
+ en línea, tokenización de tarjetas y cobros automáticos de forma segura
8
+ y escalable.
9
+
10
+ ------------------------------------------------------------------------
11
+
12
+ ## 🌎 ¿Qué es iPagos?
13
+
14
+ **iPagos** es una plataforma de procesamiento de pagos que te permite:
15
+
16
+ - 💳 Realizar cobros en línea mediante formulario eCommerce.
17
+ - 🔐 Tokenizar tarjetas de crédito de tus clientes.
18
+ - 🔁 Implementar cobros automáticos (recurrencias).
19
+ - ⚡ Ejecutar cobros manuales o directos.
20
+ - 🧾 Realizar cobros directos sin tokenización cuando el flujo lo requiera.
21
+
22
+ ------------------------------------------------------------------------
23
+
24
+ ## 🔑 Requisitos de Integración
25
+
26
+ Para comenzar necesitas:
27
+
28
+ - **MID (Merchant ID)** asignado por iPagos.
29
+ - **API Keys** (key y secret).
30
+ - Acceso al entorno sandbox o producción.
31
+
32
+ Si aún no cuentas con tus credenciales, contacta a tu ejecutivo de iPagos.
33
+
34
+ ------------------------------------------------------------------------
35
+
36
+ ## 📦 SDKs Oficiales
37
+
38
+ Actualmente contamos con librerías oficiales para:
39
+
40
+ - 🟦 **TypeScript / JavaScript (Node.js y Frontend)**
41
+
42
+ [Guía de uso](./docs/ts.md)
43
+
44
+ Si necesitas integración en otro lenguaje (Java, PHP, Python, C#, etc.), puedes solicitarlo y:
45
+
46
+ - Creamos la librería oficial.
47
+ - Brindamos capacitación técnica.
48
+ - Acompañamos el proceso de integración.
49
+ ------------------------------------------------------------------------
50
+
51
+ ## 🛠 Funcionalidades Principales
52
+
53
+ ### 1️⃣ Pagos en línea (eCommerce)
54
+ Permite integrar un formulario seguro para:
55
+
56
+ - Capturar datos de tarjeta.
57
+ - Procesar pagos en tiempo real.
58
+ - Obtener respuesta inmediata de autorización.
59
+
60
+ Ideal para:
61
+ - Tiendas en línea
62
+ - Servicios digitales
63
+ - Plataformas SaaS
64
+
65
+ ------------------------------------------------------------------------
66
+
67
+ ### 2️⃣ Tokenización de Tarjetas
68
+
69
+ La tokenización permite:
70
+
71
+ - Guardar un identificador seguro del método de pago.
72
+ - Evitar almacenar datos sensibles en tu servidor.
73
+ - Cumplir mejores prácticas de seguridad.
74
+
75
+ Casos de uso:
76
+ - Suscripciones
77
+ - Membresías
78
+ - Cobros recurrentes
79
+ - Pagos rápidos con tarjeta guardada
80
+
81
+ ------------------------------------------------------------------------
82
+
83
+ ### 3️⃣ Cobros Automáticos (Recurrencia)
84
+
85
+ Puedes implementar:
86
+
87
+ - ⏰ Un programador de cobros estilo **cronjob**
88
+ - 🔄 Ejecuciones automáticas programadas
89
+ - 💳 Cobros directos usando token
90
+ - ⚡ Cobros directos sin tokenización (cuando aplique)
91
+
92
+ Ejemplo de escenarios:
93
+
94
+ - Suscripciones mensuales
95
+ - Planes anuales
96
+ - Membresías premium
97
+ - Financiamientos
98
+
99
+ ------------------------------------------------------------------------
100
+
101
+ ### 4️⃣ Cobros Manuales
102
+
103
+ Permite:
104
+
105
+ - Ejecutar un cobro bajo demanda.
106
+ - Procesar pagos administrativos.
107
+ - Realizar cargos únicos fuera del flujo automático.
108
+
109
+ ------------------------------------------------------------------------
110
+
111
+ ## 🔒 Seguridad
112
+
113
+ El ecosistema iPagos está diseñado bajo principios de:
114
+
115
+ - Tokenización segura
116
+ - Separación de llaves públicas y privadas
117
+ - Buenas prácticas de protección de datos
118
+ - Cumplimiento de estándares de la industria
119
+
120
+ ------------------------------------------------------------------------
121
+ ## 🏗 Arquitectura Recomendada
122
+
123
+ Flujo típico de integración:
124
+
125
+ 1. Frontend obtiene token de transición seguro.
126
+ 2. Backend utiliza API privada para:
127
+ - Crear cargos
128
+ - Programar recurrencias
129
+ - Consultar transacciones
130
+
131
+
132
+ ------------------------------------------------------------------------
133
+
134
+ ## 🤝 Soporte e Integraciones Especiales
135
+
136
+ Si requieres:
137
+
138
+ - SDK en otro lenguaje
139
+ - Integraciones empresariales
140
+ - Capacitación técnica
141
+ - Acompañamiento en implementación
142
+
143
+ Contáctanos y diseñamos la solución adecuada para tu proyecto.
144
+ integraciones@ipagos.lat
145
+
146
+ ------------------------------------------------------------------------
147
+
148
+ # 💡 iPagos
149
+
150
+ Procesamiento inteligente de pagos para tu ecosistema digital.
@@ -0,0 +1,531 @@
1
+ import { BillTo, CSClientConfig, iPagosCSClientResponse } from './types';
2
+ export declare class iPagosCSClient {
3
+ private readonly config;
4
+ private client;
5
+ constructor(config: CSClientConfig);
6
+ private handleError;
7
+ /**
8
+ * Firma CyberSource
9
+ */
10
+ private sign;
11
+ /**
12
+ * POST CyberSource
13
+ */
14
+ post<T = any>(path: string, body: unknown): Promise<iPagosCSClientResponse<T>>;
15
+ /**
16
+ * GET CyberSource
17
+ */
18
+ get<T = any>(path: string): Promise<iPagosCSClientResponse<T>>;
19
+ /**
20
+ * getPaymentDetails
21
+ * -------------------------------------------------------
22
+ * Obtiene los detalles del pago asociados a un
23
+ * transientToken generado por Flex (Microform).
24
+ *
25
+ * ⚠️ Este método NO realiza ningún cobro.
26
+ * Solo recupera información contenida en el token
27
+ * de transición.
28
+ *
29
+ * -------------------------------------------------------
30
+ * ¿Para qué sirve?
31
+ *
32
+ * - Validar información antes de procesar el pago.
33
+ * - Obtener últimos 4 dígitos de tarjeta.
34
+ * - Verificar marca (VISA, MASTERCARD, etc.).
35
+ * - Aplicar reglas antifraude previas al cobro.
36
+ * - Mostrar resumen de pago al usuario.
37
+ *
38
+ * -------------------------------------------------------
39
+ * FLUJO TÍPICO:
40
+ *
41
+ * 1️⃣ Backend genera sesión (createSession).
42
+ * 2️⃣ Frontend usa Flex para capturar tarjeta.
43
+ * 3️⃣ Flex genera transientToken.
44
+ * 4️⃣ Backend recibe transientToken.
45
+ * 5️⃣ Se llama getPaymentDetails() para inspección.
46
+ * 6️⃣ Luego se decide si ejecutar createPaymentToken().
47
+ *
48
+ * -------------------------------------------------------
49
+ * @param transientToken
50
+ * Token de transición (JWT) generado por Flex.
51
+ *
52
+ * ⚠️ Es de un solo uso.
53
+ * ⚠️ Tiene vigencia limitada.
54
+ * ⚠️ No representa un pago aún.
55
+ *
56
+ * -------------------------------------------------------
57
+ * @returns Promise<iPagosCSClientResponse<T>>
58
+ *
59
+ * Respuesta exitosa:
60
+ *
61
+ * {
62
+ * success: true,
63
+ * data: {
64
+ * paymentInformation: {
65
+ * card: {
66
+ * type: string,
67
+ * expirationMonth: string,
68
+ * expirationYear: string,
69
+ * bin: string,
70
+ * last4: string
71
+ * }
72
+ * }
73
+ * }
74
+ * }
75
+ *
76
+ * Respuesta de error:
77
+ *
78
+ * {
79
+ * success: false,
80
+ * status?: number,
81
+ * error: any
82
+ * }
83
+ *
84
+ * -------------------------------------------------------
85
+ * 🔐 SEGURIDAD
86
+ *
87
+ * Este método debe ejecutarse únicamente en backend.
88
+ *
89
+ * Aunque no realiza cobro, el transientToken es sensible
90
+ * y no debe exponerse innecesariamente.
91
+ *
92
+ * -------------------------------------------------------
93
+ * 🧠 Buenas Prácticas
94
+ *
95
+ * - No almacenar transientToken en base de datos.
96
+ * - Usarlo inmediatamente y descartarlo.
97
+ * - Validar coherencia antes de ejecutar el cobro.
98
+ *
99
+ * -------------------------------------------------------
100
+ */
101
+ getPaymentDetails<T = any>(transientToken: string): Promise<iPagosCSClientResponse<any>>;
102
+ /**
103
+ * refundsPayment
104
+ * -------------------------------------------------------
105
+ * Realiza un reembolso (refund) utilizando el paymentId
106
+ * de una transacción previamente capturada.
107
+ *
108
+ * ⚠️ Solo puede ejecutarse sobre pagos ya autorizados
109
+ * y capturados.
110
+ *
111
+ * -------------------------------------------------------
112
+ * ¿Qué hace este método?
113
+ *
114
+ * - Genera una transacción de tipo REFUND.
115
+ * - Devuelve el monto especificado al método de pago original.
116
+ * - Se asocia directamente al paymentId original.
117
+ *
118
+ * -------------------------------------------------------
119
+ * CONSIDERACIONES IMPORTANTES
120
+ *
121
+ * - amountDetails.totalAmount debe coincidir con:
122
+ * • El monto total original (para refund completo), o
123
+ * • Un monto menor (para refund parcial).
124
+ *
125
+ * - currency debe ser la misma moneda del cobro original.
126
+ *
127
+ * ⚠️ No se puede reembolsar más del monto capturado.
128
+ * ⚠️ No se puede cambiar la moneda.
129
+ *
130
+ * -------------------------------------------------------
131
+ * @param paymentId
132
+ * Identificador del pago original generado por CyberSource.
133
+ *
134
+ * Ejemplo:
135
+ * "7123456789012345678901"
136
+ *
137
+ * Este ID se obtiene al ejecutar createPaymentToken()
138
+ * o createCharge().
139
+ *
140
+ * -------------------------------------------------------
141
+ * @param amountDetails
142
+ * Información del monto a reembolsar.
143
+ *
144
+ * - totalAmount: string con 2 decimales.
145
+ * Ejemplo: "100.00"
146
+ *
147
+ * - currency: Código ISO 4217 en mayúsculas.
148
+ * Ejemplo: "MXN", "USD"
149
+ *
150
+ * ⚠️ Debe coincidir con la moneda del pago original.
151
+ *
152
+ * -------------------------------------------------------
153
+ * @returns Promise<iPagosCSClientResponse<T>>
154
+ *
155
+ * Respuesta exitosa:
156
+ *
157
+ * {
158
+ * success: true,
159
+ * data: {
160
+ * id: string,
161
+ * status: string,
162
+ * ...
163
+ * }
164
+ * }
165
+ *
166
+ * Respuesta de error:
167
+ *
168
+ * {
169
+ * success: false,
170
+ * status?: number,
171
+ * error: any
172
+ * }
173
+ *
174
+ * -------------------------------------------------------
175
+ * 🧠 CASOS DE USO COMUNES
176
+ *
177
+ * - Cancelación de pedido.
178
+ * - Devolución parcial.
179
+ * - Ajuste administrativo.
180
+ * - Reversión por error operativo.
181
+ *
182
+ * -------------------------------------------------------
183
+ * 🔐 SEGURIDAD Y CONTABILIDAD
184
+ *
185
+ * - Registrar internamente cada refund.
186
+ * - Asociar refund con orden interna.
187
+ * - No ejecutar reembolsos duplicados.
188
+ *
189
+ * Recomendado:
190
+ * Implementar control interno de idempotencia.
191
+ *
192
+ * -------------------------------------------------------
193
+ */
194
+ refundsPayment<T = any>({ paymentId, amountDetails }: {
195
+ paymentId: string;
196
+ amountDetails: {
197
+ totalAmount: string;
198
+ currency: string;
199
+ };
200
+ }): Promise<iPagosCSClientResponse<T>>;
201
+ /**
202
+ * createPaymentToken
203
+ * -------------------------------------------------------
204
+ * Procesa un pago utilizando un transientToken generado
205
+ * desde el SDK de Flex (Microform).
206
+ *
207
+ * Este método permite:
208
+ *
209
+ * 1️⃣ Realizar únicamente el cobro (sin tokenización).
210
+ * 2️⃣ Realizar cobro y crear token permanente.
211
+ * 3️⃣ Solo tokenizar sin capturar fondos (capture = false).
212
+ *
213
+ * 🔹 COMPORTAMIENTO SEGÚN CONFIGURACIÓN:
214
+ *
215
+ * • Cobro sin tokenizar:
216
+ * actionList = []
217
+ * actionTokenTypes = []
218
+ *
219
+ * • Cobro + tokenización (por defecto):
220
+ * actionList = ["TOKEN_CREATE"]
221
+ * actionTokenTypes = ["customer", "paymentInstrument"]
222
+ *
223
+ * • Solo tokenización (sin captura):
224
+ * capture = false
225
+ *
226
+ * -------------------------------------------------------
227
+ * @param transientToken
228
+ * Token de transición (JWT) generado desde el SDK de Flex.
229
+ * Este token representa la tarjeta del cliente de forma segura.
230
+ *
231
+ * ⚠️ Es de un solo uso y expira rápidamente.
232
+ *
233
+ * @param internalId
234
+ * Identificador interno único del comercio.
235
+ * Se envía como clientReferenceInformation.code.
236
+ *
237
+ * ⚠️ Debe ser único por transacción (recomendado usar UUID).
238
+ *
239
+ * @param amountDetails
240
+ * Información del monto del pago.
241
+ *
242
+ * - totalAmount: Número con máximo 2 decimales.
243
+ * Ejemplo válido: 100.00
244
+ *
245
+ * - currency: Código de moneda ISO 4217 en mayúsculas.
246
+ * Ejemplo: "MXN", "USD"
247
+ *
248
+ * ⚠️ Currency debe ser de 3 caracteres.
249
+ *
250
+ * @param billTo
251
+ * Información de facturación del cliente.
252
+ * Debe cumplir con la estructura requerida por CyberSource.
253
+ *
254
+ * @param actionList (Opcional)
255
+ * Define acciones adicionales a ejecutar.
256
+ *
257
+ * - ["TOKEN_CREATE"] → Crea token permanente.
258
+ * - [] → No crea token.
259
+ *
260
+ * @param actionTokenTypes (Opcional)
261
+ * Define qué tipos de token se crearán.
262
+ *
263
+ * Valores comunes:
264
+ * - "customer"
265
+ * - "paymentInstrument"
266
+ *
267
+ * @param capture (Opcional)
268
+ * Define si la transacción se captura inmediatamente.
269
+ *
270
+ * - true → Autorización + captura inmediata.
271
+ * - false → Solo autorización.
272
+ *
273
+ * -------------------------------------------------------
274
+ * @returns Promise<iPagosCSClientResponse<T>>
275
+ *
276
+ * Respuesta estandarizada:
277
+ *
278
+ * {
279
+ * success: true,
280
+ * data: ...
281
+ * }
282
+ *
283
+ * o
284
+ *
285
+ * {
286
+ * success: false,
287
+ * status?: number,
288
+ * error: any
289
+ * }
290
+ *
291
+ * -------------------------------------------------------
292
+ * 🔐 SEGURIDAD
293
+ *
294
+ * Este método debe ejecutarse únicamente en backend.
295
+ * Nunca expongas secretKey en frontend.
296
+ *
297
+ * -------------------------------------------------------
298
+ */
299
+ createPaymentToken<T = any>({ transientToken, internalId, amountDetails, billTo, actionTokenTypes, actionList, capture, }: {
300
+ transientToken: string;
301
+ internalId: string;
302
+ amountDetails: {
303
+ totalAmount: number;
304
+ currency: string;
305
+ };
306
+ billTo: BillTo;
307
+ actionList?: string[];
308
+ actionTokenTypes?: string[];
309
+ capture?: boolean;
310
+ }): Promise<iPagosCSClientResponse<T>>;
311
+ /**
312
+ * createSession
313
+ * -------------------------------------------------------
314
+ * Genera un token de sesión (contexto) para inicializar
315
+ * el SDK de Flex (Microform).
316
+ *
317
+ * Esta sesión permite que el frontend:
318
+ *
319
+ * 1️⃣ Inicialice el formulario seguro de tarjeta.
320
+ * 2️⃣ Capture datos sensibles de tarjeta de forma segura.
321
+ * 3️⃣ Genere un transientToken (token de transición).
322
+ *
323
+ * 🔹 Flujo típico:
324
+ *
325
+ * Backend:
326
+ * → createSession()
327
+ *
328
+ * Frontend:
329
+ * → Inicializa Flex con el sessionToken
330
+ * → Captura datos de tarjeta
331
+ * → Genera transientToken
332
+ *
333
+ * Backend:
334
+ * → Usa transientToken para crear el pago
335
+ *
336
+ * -------------------------------------------------------
337
+ * @param targetOrigins
338
+ * Dominio autorizado para inicializar Flex.
339
+ *
340
+ * Ejemplo:
341
+ * "https://micomercio.com"
342
+ *
343
+ * ⚠️ Debe coincidir exactamente con el dominio donde
344
+ * se ejecutará el SDK de Flex.
345
+ *
346
+ * ⚠️ No usar comodines (*).
347
+ *
348
+ * -------------------------------------------------------
349
+ * @param allowedCardNetworks (Opcional)
350
+ * Define las marcas de tarjeta permitidas.
351
+ *
352
+ * Valores comunes:
353
+ * - "VISA"
354
+ * - "MASTERCARD"
355
+ * - "AMEX"
356
+ *
357
+ * Si no se especifica, por defecto:
358
+ * ["VISA", "MASTERCARD", "AMEX"]
359
+ *
360
+ * -------------------------------------------------------
361
+ * @param allowedPaymentTypes (Opcional)
362
+ * Define el tipo de método de pago permitido.
363
+ *
364
+ * Valor común:
365
+ * - "CARD"
366
+ *
367
+ * Si no se especifica, por defecto:
368
+ * ["CARD"]
369
+ *
370
+ * -------------------------------------------------------
371
+ * @returns Promise<iPagosCSClientResponse<T>>
372
+ *
373
+ * Respuesta exitosa:
374
+ *
375
+ * {
376
+ * success: true,
377
+ * data: {
378
+ * id: string,
379
+ * clientVersion: string,
380
+ * ...
381
+ * }
382
+ * }
383
+ *
384
+ * El ID retornado se usa en el frontend para
385
+ * inicializar Flex.
386
+ *
387
+ * -------------------------------------------------------
388
+ * 🔐 SEGURIDAD
389
+ *
390
+ * Este método debe ejecutarse únicamente en backend.
391
+ * Nunca expongas secretKey ni firmes requests desde frontend.
392
+ *
393
+ * El sessionToken tiene vigencia limitada.
394
+ *
395
+ * -------------------------------------------------------
396
+ * 🧠 Buenas Prácticas
397
+ *
398
+ * - Generar sesión por cada intento de pago.
399
+ * - No reutilizar sesiones antiguas.
400
+ * - Validar que targetOrigins coincida con tu dominio real.
401
+ *
402
+ * -------------------------------------------------------
403
+ */
404
+ createSession<T = any>({ targetOrigins, allowedCardNetworks, allowedPaymentTypes }: {
405
+ targetOrigins: string;
406
+ allowedCardNetworks?: string[];
407
+ allowedPaymentTypes?: string[];
408
+ }): Promise<iPagosCSClientResponse<T>>;
409
+ /**
410
+ * createCharge
411
+ * -------------------------------------------------------
412
+ * Realiza un cobro utilizando un customer_id y
413
+ * paymentInstrument_id previamente generados mediante
414
+ * tokenización.
415
+ *
416
+ * Este método se utiliza cuando:
417
+ *
418
+ * 1️⃣ Ya se tokenizó una tarjeta previamente.
419
+ * 2️⃣ Se desea realizar cobros recurrentes.
420
+ * 3️⃣ Se ejecutan cargos automáticos (suscripciones).
421
+ * 4️⃣ Se realizan cobros manuales administrativos.
422
+ *
423
+ * 🔹 No requiere transientToken.
424
+ * 🔹 No requiere interacción del cliente.
425
+ *
426
+ * -------------------------------------------------------
427
+ * FLUJO TÍPICO:
428
+ *
429
+ * 1) Cliente ingresa tarjeta (Flex).
430
+ * 2) Se genera transientToken.
431
+ * 3) Se ejecuta createPaymentToken() con TOKEN_CREATE.
432
+ * 4) Se obtiene:
433
+ * - customer_id
434
+ * - paymentInstrument_id
435
+ * 5) En futuros cobros se usa createCharge().
436
+ *
437
+ * -------------------------------------------------------
438
+ * @param internalId
439
+ * Identificador único interno del comercio.
440
+ * Se envía como clientReferenceInformation.code.
441
+ *
442
+ * ⚠️ Debe ser único por transacción.
443
+ * Recomendado: UUID o ID de orden interno.
444
+ *
445
+ * -------------------------------------------------------
446
+ * @param amountDetails
447
+ * Información del monto del pago.
448
+ *
449
+ * - totalAmount: Número con máximo 2 decimales.
450
+ * Ejemplo válido: 499.99
451
+ *
452
+ * - currency: Código de moneda ISO 4217 en mayúsculas.
453
+ * Ejemplo: "MXN", "USD"
454
+ *
455
+ * ⚠️ Currency debe ser de 3 caracteres.
456
+ *
457
+ * -------------------------------------------------------
458
+ * @param customer_id
459
+ * Identificador del cliente generado al tokenizar.
460
+ *
461
+ * Representa al cliente almacenado en CyberSource.
462
+ *
463
+ * -------------------------------------------------------
464
+ * @param paymentInstrument_id
465
+ * Identificador del método de pago tokenizado.
466
+ *
467
+ * Representa la tarjeta tokenizada asociada al customer_id.
468
+ *
469
+ * -------------------------------------------------------
470
+ * @param capture (Opcional)
471
+ * Define si la transacción se captura inmediatamente.
472
+ *
473
+ * - true → Autorización + captura inmediata.
474
+ * - false → Solo autorización (capture posterior).
475
+ *
476
+ * Por defecto: true
477
+ *
478
+ * -------------------------------------------------------
479
+ * @returns Promise<iPagosCSClientResponse<T>>
480
+ *
481
+ * Respuesta exitosa:
482
+ *
483
+ * {
484
+ * success: true,
485
+ * data: {
486
+ * id: string,
487
+ * status: string,
488
+ * ...
489
+ * }
490
+ * }
491
+ *
492
+ * Respuesta de error:
493
+ *
494
+ * {
495
+ * success: false,
496
+ * status?: number,
497
+ * error: any
498
+ * }
499
+ *
500
+ * -------------------------------------------------------
501
+ * 🧠 CASOS DE USO COMUNES
502
+ *
503
+ * - Suscripciones mensuales
504
+ * - Membresías
505
+ * - Financiamiento en parcialidades
506
+ * - Renovaciones automáticas
507
+ * - Reintentos de cobro
508
+ *
509
+ * -------------------------------------------------------
510
+ * 🔐 SEGURIDAD
511
+ *
512
+ * Este método debe ejecutarse únicamente en backend.
513
+ *
514
+ * No expone datos sensibles de tarjeta.
515
+ * Utiliza únicamente identificadores tokenizados.
516
+ *
517
+ * Ideal para arquitecturas PCI SAQ-A.
518
+ *
519
+ * -------------------------------------------------------
520
+ */
521
+ createCharge<T = any>({ internalId, amountDetails, customer_id, paymentInstrument_id, capture, }: {
522
+ internalId: string;
523
+ amountDetails: {
524
+ totalAmount: number;
525
+ currency: string;
526
+ };
527
+ customer_id: string;
528
+ paymentInstrument_id: string;
529
+ capture?: boolean;
530
+ }): Promise<iPagosCSClientResponse<T>>;
531
+ }