{"info":{"_postman_id":"1354f36d-52f7-4101-ac75-2b771487f8c6","name":"GreenPay 2.0 API Services (Public)","description":"<html><head></head><body><p>Se detallan en esta documentación todos los servicios disponibles para realizar transacciones utilizando los servicios API de GreenPay. Todos los datos que se exponen en los ejemplos son ficticios y deben ser reemplazados por los verdaderos credenciales que solamente el equipo de GreenPay podrá facilitarle.</p>\n<p>Maneje todos los datos con suma discresión.</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"21714358","collectionId":"1354f36d-52f7-4101-ac75-2b771487f8c6","publishedId":"2sA3QmFFks","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"3ca7dd"},"publishDate":"2024-05-20T15:49:11.000Z"},"item":[{"name":"Checkout","item":[{"name":"Create Payment Order","event":[{"listen":"test","script":{"id":"16120070-3592-4fca-a13e-a185d9151250","exec":["var jsonData = JSON.parse(responseBody);","postman.setEnvironmentVariable(\"liszt-token\", jsonData.token);","postman.setEnvironmentVariable(\"GP_SESSION\", jsonData.session);","","if(typeof jsonData.token!== \"undefined\"){","    postman.setEnvironmentVariable(\"GP_TOKEN\", jsonData.token);","};","","pm.test(\"Status code is 200\", function () {","    pm.response.to.have.status(200);","});"],"type":"text/javascript","packages":{}}},{"listen":"prerequest","script":{"id":"b3626b9b-41e9-42a0-9e4b-5eba81b249b3","exec":["var moment = require('moment');","","pm.environment.set('currentdate', moment().format((\"YYYY-MM-DD\")));"],"type":"text/javascript","packages":{}}}],"id":"584ed2fe-5056-469a-a1c4-3510b0de2c03","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"{\n    \"secret\": \"{{Secret provisto por GreenPay}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"terminal\": \"\",\n    \"amount\": 262.11,\n    \"currency\": \"USD\",\n    \"description\": \"Compra producto 886\",\n    \"orderReference\": \"compra-{{currentdate}}-USD-752\",\n    \"callback\": \"http://localchost:3000\",\n    \"additional\": {\n        \"customer\": {\n            \"name\": \"John Doe\",\n            \"email\": \"johndoe@greenpay.me\",\n            \"identification\": \"12345\",\n            \"billingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"10801\"\n            },\n            \"shippingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"10801\"\n            }\n        },\n        \"products\": [\n            {\n                \"description\": \"Compra de prueba-USD en {{ambiente}}\",\n                \"skuId\": \"612\",\n                \"quantity\": 1,\n                \"price\": 737,\n                \"type\": \"TD\"\n            }\n        ]\n    }\n}"},"url":"https://checkoutv2.greenpaysbx.me/createOrder","description":"<h1 id=\"creación-de-orden-de-pago--greenpay-20\">Creación de Orden de Pago – GreenPay 2.0</h1>\n<p>Una orden de pago se utiliza para indicar al API que se efectuará una transacción con los datos proporcionados.</p>\n<p>Al crear la orden, se retorna un objeto JSON con los valores token y session, necesarios para invocar el servicio de pago.Estos valores tienen una vigencia de 30 minutos.</p>\n<p>&gt; Recomendación: Realiza este proceso desde el backend del comercio para proteger las credenciales y detalles de la orden.</p>\n<hr />\n<h2 id=\"endpoint\">Endpoint</h2>\n<p>Método: POST</p>\n<p>Body: JSON</p>\n<hr />\n<h2 id=\"estructura-del-request\">Estructura del Request</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"secret\": \"\",\n  \"merchantId\": \"\",\n  \"terminal\": \"\",\n  \"amount\": 0,\n  \"currency\": \"\",\n  \"description\": \"\",\n  \"orderReference\": \"\",\n  \"callback\": \"\",\n  \"additional\": {\n    \"customer\": {\n      \"name\": \"\",\n      \"email\": \"\",\n      \"identification\": \"\",\n      \"billingAddress\": {\n        \"country\": \"\",\n        \"province\": \"\",\n        \"city\": \"\",\n        \"street1\": \"\",\n        \"street2\": \"\",\n        \"zip\": \"\"\n      },\n      \"shippingAddress\": {\n        \"country\": \"\",\n        \"province\": \"\",\n        \"city\": \"\",\n        \"street1\": \"\",\n        \"street2\": \"\",\n        \"zip\": \"\"\n      }\n    },\n    \"products\": [\n      {\n        \"description\": \"\",\n        \"skuId\": \"\",\n        \"quantity\": 0,\n        \"price\": 0,\n        \"type\": \"\"\n      }\n    ]\n  }\n}\n\n</code></pre>\n<hr />\n<h2 id=\"detalle-de-campos\">Detalle de Campos</h2>\n<h3 id=\"campos-principales\">Campos Principales</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Longitud Mínima</th>\n<th>Longitud Máxima</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>secret</td>\n<td>String</td>\n<td>Sí</td>\n<td>1</td>\n<td>100</td>\n<td>Llave secreta provista por GreenPay 2.0</td>\n</tr>\n<tr>\n<td>merchantId</td>\n<td>String</td>\n<td>Sí</td>\n<td>1</td>\n<td>100</td>\n<td>Identificador único del comercio</td>\n</tr>\n<tr>\n<td>terminal</td>\n<td>UUID</td>\n<td>Sí</td>\n<td>36</td>\n<td>36</td>\n<td>Terminal provisto por GreenPay 2.0</td>\n</tr>\n<tr>\n<td>amount</td>\n<td>Number</td>\n<td>Sí</td>\n<td>-</td>\n<td>-</td>\n<td>Monto a cobrar (dos decimales, ej: 10.26)</td>\n</tr>\n<tr>\n<td>currency</td>\n<td>String</td>\n<td>Sí</td>\n<td>3</td>\n<td>3</td>\n<td>Moneda (CRC o USD)</td>\n</tr>\n<tr>\n<td>description</td>\n<td>String</td>\n<td>Sí</td>\n<td>5</td>\n<td>200</td>\n<td>Descripción de la orden</td>\n</tr>\n<tr>\n<td>orderReference</td>\n<td>String</td>\n<td>Sí</td>\n<td>5</td>\n<td>100</td>\n<td>Identificador único de la orden</td>\n</tr>\n<tr>\n<td>callback</td>\n<td>String</td>\n<td>Opcional</td>\n<td>5</td>\n<td>200</td>\n<td>URL para recibir la respuesta de la transacción</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"additionalcustomer\">additional.customer</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Longitud Mínima</th>\n<th>Longitud Máxima</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>String</td>\n<td>Sí</td>\n<td>5</td>\n<td>100</td>\n<td>Nombre del cliente</td>\n</tr>\n<tr>\n<td>email</td>\n<td>String</td>\n<td>Sí</td>\n<td>5</td>\n<td>100</td>\n<td>Correo electrónico válido</td>\n</tr>\n<tr>\n<td>identification</td>\n<td>String</td>\n<td>Sí</td>\n<td>5</td>\n<td>20</td>\n<td>Identificación única</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"additionalcustomerbillingaddress\">additional.customer.billingAddress</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Longitud Mínima</th>\n<th>Longitud Máxima</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>country</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>2</td>\n<td>Código país ISO</td>\n</tr>\n<tr>\n<td>province</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>50</td>\n<td>Provincia</td>\n</tr>\n<tr>\n<td>city</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>50</td>\n<td>Ciudad</td>\n</tr>\n<tr>\n<td>street1</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>200</td>\n<td>Dirección 1</td>\n</tr>\n<tr>\n<td>street2</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>200</td>\n<td>Dirección 2</td>\n</tr>\n<tr>\n<td>zip</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>10</td>\n<td>Código postal</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"additionalcustomershippingaddress\">additional.customer.shippingAddress</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Longitud Mínima</th>\n<th>Longitud Máxima</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>country</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>2</td>\n<td>Código país ISO</td>\n</tr>\n<tr>\n<td>province</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>50</td>\n<td>Provincia</td>\n</tr>\n<tr>\n<td>city</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>50</td>\n<td>Ciudad</td>\n</tr>\n<tr>\n<td>street1</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>200</td>\n<td>Dirección 1</td>\n</tr>\n<tr>\n<td>street2</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>200</td>\n<td>Dirección 2</td>\n</tr>\n<tr>\n<td>zip</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>10</td>\n<td>Código postal</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"additionalproducts-array-de-objetos\">additional.products (Array de objetos)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Longitud Mínima</th>\n<th>Longitud Máxima</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>description</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>50</td>\n<td>Descripción del producto</td>\n</tr>\n<tr>\n<td>skuId</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>50</td>\n<td>Identificador único</td>\n</tr>\n<tr>\n<td>quantity</td>\n<td>Integer</td>\n<td>Sí</td>\n<td>-</td>\n<td>-</td>\n<td>Cantidad</td>\n</tr>\n<tr>\n<td>price</td>\n<td>Decimal</td>\n<td>Sí</td>\n<td>-</td>\n<td>-</td>\n<td>Precio (dos decimales)</td>\n</tr>\n<tr>\n<td>type</td>\n<td>String</td>\n<td>Sí</td>\n<td>2</td>\n<td>50</td>\n<td>Tipo de producto</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<hr />\n<h2 id=\"respuestas-de-la-api\">Respuestas de la API</h2>\n<h3 id=\"éxito-http-200\">Éxito (HTTP 200)</h3>\n<p>Orden creada exitosamente.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"statusCode\": 200,\n  \"message\": \"SUCCESS\",\n  \"session\": \"fb3af538-3398-4251-8fcd-3d236fcc6e88\",\n  \"token\": \"a944c95c-5380-40fc-b5b7-e9138254bdfa\"\n}\n\n</code></pre>\n<ul>\n<li><p><code>session</code>: Se utilizará en procesos de pagos posteriores.</p>\n</li>\n<li><p><code>token</code>: Se enviará en los headers en procesos de pago posteriores.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"error-de-validación-http-400\">Error de Validación (HTTP 400)</h3>\n<p>Orden no creada por error de validación.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"message\": \"Event object failed validation\",\n  \"status\": 400\n}\n\n</code></pre>\n<hr />\n<h2 id=\"notas\">Notas</h2>\n<ul>\n<li><p>Todos los campos son requeridos, excepto callback que es opcional.</p>\n</li>\n<li><p>El campo <code>callback</code> es obligatorio si la integración es por checkoutform.</p>\n</li>\n<li><p>Si el token y session expiran (30 minutos), se debe crear una nueva orden.</p>\n</li>\n<li><p>Se recomienda enviar todos los datos disponibles para mayor trazabilidad.</p>\n</li>\n</ul>\n","urlObject":{"path":["createOrder"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"1a3c8ecf-ba2d-46a4-97c8-ea5f610fda01","name":"successful order","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"{\n    \"secret\": \"IEm6H2RgtLOOZnJwvgM8qgyaH1GdV1NzgupvfsNtUV3/M35EkKY/Eyj8x7bDHNP5pRsbNDJlaCBIvpKWUj+Vi87P52/6G9f7XG+3f4chX2UV8rFFsOtSZBydkTJpljEsAoIvWtaAT...\",\n    \"merchantId\": \"ff548607-cca1-43ae-8626-7172fabbea59\",\n    \"terminal\": \"{{Terminal en USD provista por GreenPay}}\",\n    \"amount\": 431.03,\n    \"currency\": \"USD\",\n    \"callback\": \"https://webhook.site/2b98eb7c-5aa8-4480-9d42-5f3f3dfbc96f\",\n    \"description\": \"Compra producto 885\",\n    \"orderReference\": \"compra--USD-773\",\n    \"additional\": {\n        \"customer\": {\n            \"name\": \"John Doe\",\n            \"email\": \"johndoe@greenpay.me\",\n            \"identification\": \"12345\",\n            \"billingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"10801\"\n            },\n            \"shippingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"10801\"\n            }\n        },\n        \"products\": [\n            {\n                \"description\": \"Compra de prueba-USD en {{ambiente}}\",\n                \"skuId\": \"213\",\n                \"quantity\": 1,\n                \"price\": 489,\n                \"type\": \"TD\"\n            }\n        ]\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpayqa.me/createOrder"},"code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":""}],"cookie":[],"responseTime":null,"body":"{\n  \"statusCode\": 200,\n  \"message\": \"SUCCESS\",\n  \"session\": \"fb3af538-3398-4251-8fcd-3d236fcc6e88\",\n  \"token\": \"a944c95c-5380-40fc-b5b7-e9138254bdfa\"\n}"},{"id":"47fb68eb-1cbb-4027-96a6-b5520c1fa9fb","name":"failed order","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"{\n    \"secret\": \"{{Secret provisto por GreenPay}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"terminal\": \"{{Terminal en USD provista por GreenPay}}\",\n    \"amount\": 226.95,\n    \"currency\": \"USD\",\n    \"callback\": \"https://webhook.site/2b98eb7c-5aa8-4480-9d42-5f3f3dfbc96f\",\n    \"description\": \"Compra producto 612\",\n    \"orderReference\": \"compra-{{currentdate}}-USD-259\",\n    \"additional\": {\n        \"customer\": {\n            \"name\": \"John Doe\",\n            \"email\": \"johndoe@greenpay.me\",\n            \"identification\": \"12345\",\n            \"billingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"10801\"\n            },\n            \"shippingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"10801\"\n            }\n        },\n        \"products\": [\n            {\n                \"description\": \"Compra de prueba-USD en {{ambiente}}\",\n                \"skuId\": \"958\",\n                \"quantity\": 1,\n                \"price\": 585,\n                \"type\": \"TD\"\n            }\n        ]\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/createOrder"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":""}],"cookie":[],"responseTime":null,"body":"{ \n  \"status\": \"String razón solicitud rechazada\",\n  \"message\":\"String mensaje solicitud rechazada\"\n }"}],"_postman_id":"584ed2fe-5056-469a-a1c4-3510b0de2c03"},{"name":"Authorization","id":"57966d30-f3f2-47c5-b6d9-dd2ec13e7795","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"session\": \"1a5e6f0f-0d62-45e6-ac70-a68c02507c64\",\n    \"ed\": \"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMTIiLCJ5ZWFyIjoiMzEifSwiY2FyZE51bWJlciI6IjU1OTcyNzAwMDAwMDE4MTUiLCJjdmMiOiIxOTYifSwiYWRkaXRpb25hbCI6eyJjaGFubmVsRGF0YSI6eyJjaGFubmVsIjoiMDEiLCJzb3VyY2UiOiJBUElfQ0FSRCJ9fSwia291bnRTZXNzaW9uIjoiNTgyMThkMjJhMzRmNDJjZGEwNDE3ODliM2FiYzlkNTAifQ==\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me","description":"<h1 id=\"autorización-de-pago--api-v2\">Autorización de Pago – API V2</h1>\n<p>Este endpoint permite autorizar un monto de una orden de pago y debitar el monto directamente a la tarjeta. Para utilizar este servicio, primero debes crear una orden de pago. Los valores de session y token generados al crear la orden son requeridos para el correcto funcionamiento de este endpoint.</p>\n<hr />\n<h2 id=\"pasos-previos-crear-una-orden-de-pago\">Pasos Previos: Crear una Orden de Pago</h2>\n<ol>\n<li>Crear la orden de pago:</li>\n</ol>\n<p>Realiza una solicitud al endpoint correspondiente para crear una orden de pago.</p>\n<ul>\n<li><p>Obtendrás dos valores importantes:</p>\n</li>\n<li><p><code>session</code>: Identificador de la sesión de la orden de pago (UUID).</p>\n</li>\n<li><p><code>token</code>: Token de seguridad para la sesión (UUID).</p>\n</li>\n</ul>\n<ol>\n<li>Conservar los valores:</li>\n</ol>\n<p>Guarda los valores de <code>session</code> y <code>token</code>, ya que serán requeridos para la autorización.</p>\n<hr />\n<h2 id=\"endpoint-de-autorización\">Endpoint de Autorización</h2>\n<ul>\n<li><p>Método: POST</p>\n</li>\n<li><p>Descripción: Autoriza un monto de una orden de pago.</p>\n</li>\n<li><p>Requiere conexión segura: Sí, bajo TLS 1.2.</p>\n</li>\n<li><p>Cifrado de datos: Los datos de la tarjeta deben enviarse en formato JSON, codificados en base64.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"headers\">Headers</h3>\n<p>⚠️ ¡Importante!</p>\n<p>El header <code>session-token</code> es obligatorio y debe ser enviado en cada solicitud a este endpoint.</p>\n<p>El valor de <code>session-token</code> corresponde exactamente al <code>token</code> obtenido al crear la orden de pago.</p>\n<p>Si no se incluye este header, la autorización será rechazada.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>session-token</td>\n<td>String</td>\n<td>Token obtenido en la creación de la orden de pago.</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><p>Ejemplo de session-token (UUID): ad79b9b0-917d-11ef-8a48-19ee98944b83</p>\n<hr />\n<h3 id=\"body-json\">Body (JSON)</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"session\": \"ad79b9b0-917d-11ef-8a48-19ee98944b83\",\n  \"ed\": \"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMTIiLCJ5ZWFyIjoiMzEifSwiY2FyZE51bWJlciI6IjQwMDU1Mjk5OTkwMDEyMyIsImN2YyI6IjE5NiJ9LCJhZGRpdGlvbmFsIjp7ImNoYW5uZWxEYXRhIjp7ImNoYW5uZWwiOiIwMSIsInNvdXJjZSI6IkFQSV9DQVJEIn19fSwia291bnRTZXNzaW9uIjoiNTgyMThkMjJhMzRmNDJjZGEwNDE3ODliM2FiYzlkNTAifQ==\"\n}\n\n</code></pre>\n<ul>\n<li><p><code>session</code>: UUID obtenido al crear la orden de pago.</p>\n</li>\n<li><p><code>ed</code>: Datos de la tarjeta cifrados en base64 (ver estructura y ejemplo abajo).</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"campos-obligatorios-del-request\">Campos obligatorios del request</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>session</td>\n<td>String</td>\n<td>Sesión obtenida al crear la orden de pago (UUID).</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>ed</td>\n<td>String</td>\n<td>Datos de la tarjeta cifrados en base64.</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"estructura-del-objeto-antes-de-codificar-en-base64-ed\">Estructura del objeto antes de codificar en base64 (ed)</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Restricciones / Ejemplo</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>card.cardHolder</td>\n<td>String</td>\n<td>Nombre del dueño de la tarjeta.</td>\n<td>5-50 caracteres, Ej: \"John Doe\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.month</td>\n<td>String</td>\n<td>Mes de vencimiento de la tarjeta.</td>\n<td>2 caracteres, \"01\" a \"12\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.year</td>\n<td>String</td>\n<td>Año de vencimiento (últimos 2 dígitos).</td>\n<td>2 caracteres, Ej: \"31\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cardNumber</td>\n<td>String</td>\n<td>Número de la tarjeta.</td>\n<td></td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cvc</td>\n<td>String</td>\n<td>Código de seguridad de la tarjeta.</td>\n<td></td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.channel</td>\n<td>String</td>\n<td>Canal, debe ser \"01\".</td>\n<td>\"01\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.source</td>\n<td>String</td>\n<td>Fuente, debe ser \"API_CARD\".</td>\n<td>\"API_CARD\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>kountSession</td>\n<td>String</td>\n<td>ID de sesión de Kount (antifraude).</td>\n<td>Ej: \"58218d22a34f42cda041789b3abc9d50\"</td>\n<td>No</td>\n</tr>\n<tr>\n<td>plan</td>\n<td>String</td>\n<td>Id identificador del plan</td>\n<td>06ae4d6a-a55d-41b8-894e-be9b75c4f063</td>\n<td>Solo para pagos con planes</td>\n</tr>\n<tr>\n<td>quota</td>\n<td>Number</td>\n<td>Cuota del plan</td>\n<td>Eje: 6</td>\n<td>Solo con planes</td>\n</tr>\n</tbody>\n</table>\n</div><p>ℹ️ Nota sobre <code>kountSession</code>:</p>\n<p>Antes de enviar el campo kountSession, debes consultar si la integración que vas a utilizar requiere o no este campo y si tienes la aprobación de GreenPay para el uso de esta funcionalidad.</p>\n<p>El campo <code>kountSession</code> es obligatorio únicamente si tu integración y GreenPay lo requieren y han aprobado su uso.</p>\n<p>La recolección de este dato se realiza del lado del frontend, utilizando el SDK de Kount o el Data Collector correspondiente.</p>\n<p>Consulta la documentación específica de integración de Kount para más detalles sobre cómo obtener este valor en el navegador del usuario.</p>\n<p>ℹ️ Nota sobre <code>plan</code> y <code>quota</code>:</p>\n<p>Para realizar plagos con planes se deben enviar estos dos valores, estos valores los debe obtener mediante un endpoint que GreenPay Facilita, la documentacion del endpoint la puede encontrar en la Merchant/Plans en la documentacion de postman</p>\n<p>Estos datos los tiene que solicitar mediante interfaz gráfica en su frontend, para revisar una integración por código puede revisar el siguiente ejemplo en NodeJS<br /><a href=\"https://bitbucket.org/greeenpay/checkout-v2-nodejs/src/main/\">Checkout V2 API</a></p>\n<p>Sino utiliza pagos con Cuota y plan porfavor omitir estos campos.</p>\n<p>Su terminal debe estar configurada para aceptar pagos con planes</p>\n<h4 id=\"ejemplo-de-objeto-antes-de-base64\">Ejemplo de objeto antes de base64</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"card\": {\n    \"cardHolder\": \"John Doe\",\n    \"expirationDate\": { \"month\": \"12\", \"year\": \"31\" },\n    \"cardNumber\": \"4005529999000123\",\n    \"cvc\": \"196\"\n  },\n  \"additional\": {\n    \"channelData\": { \"channel\": \"01\", \"source\": \"API_CARD\" }\n  },\n  \"kountSession\": \"58218d22a34f42cda041789b3abc9d50\",\n  // solo aplica para planes \n    // campos requeridos para pagos con planes\n  \"plan\": \"06ae4d6a-a55d-41b8-894e-be9b75c4f063\",\n  \"quota\": 6, // DEBE ser número entero, NO string\n}\n\n</code></pre>\n<h4 id=\"ejemplo-de-datos-cifrados-en-base64-ed\">Ejemplo de datos cifrados en base64 (ed)</h4>\n<p>eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMTIiLCJ5ZWFyIjoiMzEifSwiY2FyZE51bWJlciI6IjQwMDU1Mjk5OTkwMDEyMyIsImN2YyI6IjE5NiJ9LCJhZGRpdGlvbmFsIjp7ImNoYW5uZWxEYXRhIjp7ImNoYW5uZWwiOiIwMSIsInNvdXJjZSI6IkFQSV9DQVJEIn19fSwia291bnRTZXNzaW9uIjoiNTgyMThkMjJhMzRmNDJjZGEwNDE3ODliM2FiYzlkNTAifQ==</p>\n<hr />\n<h2 id=\"respuestas-de-la-autorización\">Respuestas de la Autorización</h2>\n<p>Dependiendo del resultado de la solicitud, la API puede devolver una respuesta exitosa o fallida.</p>\n<p>A continuación se describen ambos escenarios:</p>\n<hr />\n<h3 id=\"¿qué-es-el-http-code\">¿Qué es el HTTP code?</h3>\n<p>El HTTP code (código de estado HTTP) es un número que indica el resultado de una solicitud HTTP:</p>\n<ul>\n<li><p>Un código 200 significa que la solicitud fue exitosa.</p>\n</li>\n<li><p>Cualquier código diferente a 200 (por ejemplo, 400, 401, 404, 500, etc.) indica que la solicitud falló por algún motivo.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"respuesta-exitosa-http-code-200\">Respuesta Exitosa (HTTP code 200)</h3>\n<p>Cuando la autorización es exitosa, la API responde con un código HTTP 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"status\": 200,\n    \"orderId\": \"compra-2024-10-23-USD-265\",\n    \"authorization\": \"445000\",\n    \"amount\": 302,\n    \"currency\": \"USD\",\n    \"token\": \"0c86cae0-917b-11ef-8500-27f1ad691f71\",\n    \"internalRef\": 10819032514292,\n    \"transactionId\": \"beb386d4-0595-49b1-a7a9-e23876cf0b97\",\n    \"errors\": [],\n    \"last4\": \"1815\",\n    \"brand\": \"Mastercard\",\n    \"quota\": 0\n}\n\n</code></pre>\n<ul>\n<li><p>authorization: Referencia de autorización de la transacción.</p>\n</li>\n<li><p>transactionId: Identificador único de la transacción en GreenPay.</p>\n</li>\n<li><p>errors: Siempre es un arreglo vacío en respuestas exitosas.</p>\n</li>\n<li><p>quota: El campo quota es para transacciones a plazos, se establece por defecto en 0 en la respuesta exitosa. Omitir este campo si no hace uso de transacciones a plazos.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"respuesta-fallida-http-code-diferente-de-200\">Respuesta Fallida (HTTP code diferente de 200)</h3>\n<p>Cuando la autorización falla, la API responde con un código HTTP distinto de 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"message\": \"terminal not found\",\n    \"status\": \"fail\"\n}\n\n</code></pre>\n<ul>\n<li><p>message: Descripción del motivo de la falla.</p>\n</li>\n<li><p>status: Siempre será \"fail\" en caso de error.</p>\n</li>\n</ul>\n<hr />\n<h2 id=\"webhook-de-respuesta\">Webhook de Respuesta</h2>\n<p>⚡ ¿Cómo funciona el Webhook?La URL del webhook debe ser configurada previamente desde el dashboard de GreenPay.</p>\n<p>Para este endpoint de autorizaciones, la respuesta será enviada a la URL raíz del webhook que hayas configurado para tu comercio.</p>\n<p>Ejemplo: Si tu webhook es <code>https://miwebhook.com</code>, se enviará una petición HTTP tipo POST a esa URL con un objeto como los siguientes ejemplos.</p>\n<p>El campo status en la respuesta del webhook indica el resultado de la transacción:</p>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-exitosa\">Ejemplo de respuesta exitosa</h3>\n<p>🟢 status: 200 en el campo <code>status</code> de la respuesta del webhook indica una transacción exitosa.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 200,\n  \"orderId\": \"compra-2024-10-23-USD-431\",\n  \"authorization\": \"831000\",\n  \"amount\": 14,\n  \"currency\": \"USD\",\n  \"token\": \"ad79b9b0-917d-11ef-8a48-19ee98944b83\",\n  \"internalRef\": 18155385770690,\n  \"transactionId\": \"76b784bb-9e0c-4091-8c5c-48b2b00e7cb6\",\n  \"errors\": [],\n  \"last4\": \"1815\",\n  \"brand\": \"Mastercard\",\n  \"quota\": 0\n}\n\n</code></pre>\n<ul>\n<li><p>El campo status con valor 200 indica una transacción exitosa en la respuesta del webhook.</p>\n</li>\n<li><p>El campo quota es para transacciones a plazos, se establece por defecto en 0 en la respuesta exitosa. Omitir este campo si no hace uso de transacciones a plazos.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-fallida\">Ejemplo de respuesta fallida</h3>\n<p>🔴 status diferente de 200 en el campo status de la respuesta del webhook indica una transacción fallida.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 500,\n  \"orderId\": \"compra-2024-10-23-USD-617\",\n  \"authorization\": null,\n  \"amount\": 53,\n  \"currency\": \"USD\",\n  \"token\": null,\n  \"internalRef\": 8139382378302,\n  \"transactionId\": \"2d3af6f7-e610-4854-82ee-fb576da23cec\",\n  \"errors\": [\n    \"All other response codes received\"\n  ],\n  \"last4\": \"1815\",\n  \"brand\": \"Mastercard\"\n}\n\n</code></pre>\n","urlObject":{"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"b00f23cf-4287-4d62-9bf7-64c81154f8ce","name":"Successful Authorization","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"session\": \"1a5e6f0f-0d62-45e6-ac70-a68c02507c64\",\n    \"ed\": \"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMTIiLCJ5ZWFyIjoiMzEifSwiY2FyZE51bWJlciI6IjU1OTcyNzAwMDAwMDE4MTUiLCJjdmMiOiIxOTYifSwiYWRkaXRpb25hbCI6eyJjaGFubmVsRGF0YSI6eyJjaGFubmVsIjoiMDEiLCJzb3VyY2UiOiJBUElfQ0FSRCJ9fSwia291bnRTZXNzaW9uIjoiNTgyMThkMjJhMzRmNDJjZGEwNDE3ODliM2FiYzlkNTAifQ==\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpayqa.me"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": 200,\n    \"orderId\": \"compra-2024-10-23-USD-265\",\n    \"authorization\": \"445000\",\n    \"amount\": 302,\n    \"currency\": \"USD\",\n    \"token\": \"0c86cae0-917b-11ef-8500-27f1ad691f71\",\n    \"internalRef\": 10819032514292,\n    \"transactionId\": \"beb386d4-0595-49b1-a7a9-e23876cf0b97\",\n    \"errors\": [],\n    \"last4\": \"1815\",\n    \"brand\": \"Mastercard\",\n    \"quota\": 0\n}"},{"id":"3bb71b43-0a5e-46f5-a0ac-d013ef623605","name":"Failed Authorization","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"session\": \"1a5e6f0f-0d62-45e6-ac70-a68c02507c64\",\n    \"ed\": \"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMTIiLCJ5ZWFyIjoiMzEifSwiY2FyZE51bWJlciI6IjU1OTcyNzAwMDAwMDE4MTUiLCJjdmMiOiIxOTYifSwiYWRkaXRpb25hbCI6eyJjaGFubmVsRGF0YSI6eyJjaGFubmVsIjoiMDEiLCJzb3VyY2UiOiJBUElfQ0FSRCJ9fSwia291bnRTZXNzaW9uIjoiNTgyMThkMjJhMzRmNDJjZGEwNDE3ODliM2FiYzlkNTAifQ==\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"terminal not found\",\n    \"status\": \"fail\"\n}"}],"_postman_id":"57966d30-f3f2-47c5-b6d9-dd2ec13e7795"}],"id":"b9d8c67b-e358-4e63-9df3-08c9bf4d7d9b","description":"<p>Métodos necesarios para procesar transacciones on demand utilizando los servicios de GreenPay</p>\n<h1 id=\"orden-de-pago\">Orden de Pago</h1>\n<p>Una orden de pago se crea para indicar al API de pago que se efectuará una transacción por el motivo de los datos indicados en la orden. Para esto se debe tener las siguientes consideraciones:</p>\n<ol>\n<li>Utilizar el servicio en los <em><strong>endpoints:</strong></em></li>\n</ol>\n<p>En sandbox: <code>https://checkoutv2.greenpaysbx.me/createOrder</code></p>\n<p>En producción: <code>https://checkoutv2.greenpay.me/createOrder</code></p>\n<ol>\n<li><p>Una orden de pago genera una respuesta en formato JSON que contiene un valor <strong>session, token, statusCode</strong> y <strong>message</strong></p>\n</li>\n<li><p>El valor <strong>session</strong> y el <strong>token</strong> tendrá una vigencia de <strong>30 minutos</strong> a partir de la creación de la orden de pago. Una vez cumplido ese plazo no tendrán validez, si se quiere continuar con el proceso <strong>se debe crear otra orden</strong>.</p>\n</li>\n<li><p>Se recomienda que este proceso se realice desde el <strong>backend</strong> del comercio, para proteger los datos de las credenciales y detalles de la orden de pago.</p>\n</li>\n</ol>\n<h2 id=\"pasos-para-el-uso-del-servicio\">Pasos para el uso del servicio</h2>\n<p>Para realizar la creación de una orden de Pago GreenPay cuenta con ejemplos tanto en NodeJS como en Postman</p>\n<p><strong>NodeJS</strong></p>\n<p><a href=\"https://bitbucket.org/greeenpay/checkout-v2-nodejs/src/main/\">Checkout NodeJS</a></p>\n<p>Este ejemplo contiene la creación de la orden y el pago por API</p>\n","_postman_id":"b9d8c67b-e358-4e63-9df3-08c9bf4d7d9b"},{"name":"Preauthorization","item":[{"name":"Preauthorization request","event":[{"listen":"test","script":{"id":"1098dc37-cea8-455e-ac19-9cede81676f7","exec":["var jsonData = JSON.parse(responseBody);","postman.setEnvironmentVariable(\"confirm-authorization-token\", jsonData.jwt);","","if(typeof jsonData.jwt!== \"undefined\"){","    postman.setEnvironmentVariable(\"confirm-authorization-token\", jsonData.jwt);","};","","pm.test(\"Status code is 200\", function () {","    pm.response.to.have.status(200);","});"],"type":"text/javascript","packages":{}}}],"id":"cd6c1a07-c4fe-4f34-bbce-fd55eb9c6dd1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n    \"ed\":\"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMTIiLCJ5ZWFyIjoiMzEifSwiY2FyZE51bWJlciI6IjQwMDU1Mjk5OTkwMDAxMjMiLCJjdmMiOiIxOTYifSwiYWRkaXRpb25hbCI6eyJjaGFubmVsRGF0YSI6eyJjaGFubmVsIjoiMDEiLCJzb3VyY2UiOiJBUElfQ0FSRCJ9fSwia291bnRTZXNzaW9uIjoiNTgyMThkMjJhMzRmNDJjZGEwNDE3ODliM2FiYzlkNTAifQ==\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/preauthorize","description":"<h1 id=\"preautorización-de-pago--api-v2\">Preautorización de Pago – API V2</h1>\n<p>Este endpoint permite crear una preautorización sobre una orden de pago. La preautorización retiene el monto en la tarjeta, pero no lo debita. Es ideal para escenarios donde se requiere garantizar fondos antes de realizar el cobro final.</p>\n<hr />\n<h2 id=\"pasos-previos-crear-una-orden-de-pago\">Pasos Previos: Crear una Orden de Pago</h2>\n<ol>\n<li>Crear la orden de pago:</li>\n</ol>\n<p>Realiza una solicitud al endpoint correspondiente para crear una orden de pago.</p>\n<ul>\n<li>Obtendrás dos valores importantes:</li>\n<li><code>session</code>: Identificador de la sesión de la orden de pago (UUID).</li>\n<li><code>token</code>: Token de seguridad para la sesión (UUID).</li>\n</ul>\n<ol>\n<li>Conservar los valores:</li>\n</ol>\n<p>Guarda los valores de session y token, ya que serán requeridos para la preautorización.</p>\n<hr />\n<h2 id=\"endpoint-de-preautorización\">Endpoint de Preautorización</h2>\n<ul>\n<li>Método: POST</li>\n<li>Ambiente de desarrollo: <a href=\"https://checkoutv2.greenpaysbx.me/preauthorize\">https://checkoutv2.greenpaysbx.me/preauthorize</a></li>\n<li>Ambiente productivo: <a href=\"https://checkoutv2.greenpay.me/preauthorize\">https://checkoutv2.greenpay.me/preauthorize</a></li>\n<li>Descripción: Realiza una preautorización sobre una orden de pago existente.</li>\n<li>Requiere conexión segura: Sí, bajo TLS 1.2.</li>\n<li>Cifrado de datos: Los datos de la tarjeta deben enviarse en formato JSON, codificados en base64.</li>\n</ul>\n<hr />\n<h3 id=\"headers\">Headers</h3>\n<p>⚠️ ¡Importante!</p>\n<p>El header <code>session-token</code> es obligatorio y debe ser enviado en cada solicitud a este endpoint.</p>\n<p>El valor de <code>session-token</code> corresponde exactamente al token obtenido al crear la orden de pago.</p>\n<p>Si no se incluye este header, la preautorización será rechazada.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>session-token</td>\n<td>String</td>\n<td>Token obtenido en la creación de la orden de pago.</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><p>Ejemplo de session-token (UUID):ad79b9b0-917d-11ef-8a48-19ee98944b83</p>\n<h3 id=\"body-json\">Body (JSON)</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"session\": \"ad79b9b0-917d-11ef-8a48-19ee98944b83\",\n  \"ed\": \"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJBbmdlbCBHb256YWxleiIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMDMiLCJ5ZWFyIjoiMjUifSwiY2FyZE51bWJlciI6IjU1OTcyNzAwMDAwMDE4MTUiLCJjdmMiOiIxOTYifSwiYWRkaXRpb25hbCI6eyJjaGFubmVsRGF0YSI6eyJjaGFubmVsIjoiMDEiLCJzb3VyY2UiOiJBUElfQ0FSRCJ9fSwia291bnRTZXNzaW9uIjoiNTgyMThkMjJhMzRmNDJjZGEwNDE3ODliM2FiYzlkNTAifQ==\"\n}\n\n</code></pre>\n<ul>\n<li><code>session</code>: UUID obtenido al crear la orden de pago (requerido).</li>\n<li><code>ed</code>: Datos de la tarjeta cifrados en base64 (requerido, ver estructura y ejemplo abajo).</li>\n</ul>\n<hr />\n<h3 id=\"campos-obligatorios-del-request\">Campos obligatorios del request</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>session</td>\n<td>String</td>\n<td>Sesión obtenida al crear la orden de pago (UUID).</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>ed</td>\n<td>String</td>\n<td>Datos de la tarjeta cifrados en base64.</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"estructura-del-objeto-antes-de-codificar-en-base64-ed\">Estructura del objeto antes de codificar en base64 (ed)</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Restricciones / Ejemplo</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>card.cardHolder</td>\n<td>String</td>\n<td>Nombre del dueño de la tarjeta.</td>\n<td>5-50 caracteres, Ej: \"John Doe\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.month</td>\n<td>String</td>\n<td>Mes de vencimiento de la tarjeta.</td>\n<td>2 caracteres, \"01\" a \"12\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.year</td>\n<td>String</td>\n<td>Año de vencimiento (últimos 2 dígitos).</td>\n<td>2 caracteres, Ej: \"31\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cardNumber</td>\n<td>String</td>\n<td>Número de la tarjeta.</td>\n<td></td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cvc</td>\n<td>String</td>\n<td>Código de seguridad de la tarjeta.</td>\n<td></td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.channel</td>\n<td>String</td>\n<td>Canal, debe ser \"01\".</td>\n<td>\"01\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.source</td>\n<td>String</td>\n<td>Fuente, debe ser \"API_CARD\".</td>\n<td>\"API_CARD\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>kountSession</td>\n<td>String</td>\n<td>ID de sesión de Kount (antifraude).</td>\n<td>Ej: \"58218d22a34f42cda041789b3abc9d50\"</td>\n<td>No</td>\n</tr>\n</tbody>\n</table>\n</div><p>ℹ️ Nota sobre <code>kountSession</code>:</p>\n<p>Antes de enviar el campo kountSession, debes consultar si la integración que vas a utilizar requiere o no este campo y si tienes la aprobación de GreenPay para el uso de esta funcionalidad.</p>\n<p>El campo kountSession es obligatorio únicamente si tu integración y GreenPay lo requieren y han aprobado su uso.</p>\n<p>La recolección de este dato se realiza del lado del frontend, utilizando el SDK de Kount o el Data Collector correspondiente.</p>\n<p>Consulta la documentación específica de integración de Kount para más detalles sobre cómo obtener este valor en el navegador del usuario.</p>\n<h4 id=\"ejemplo-de-objeto-antes-de-base64\">Ejemplo de objeto antes de base64</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"card\": {\n    \"cardHolder\": \"Angel Gonzalez\",\n    \"expirationDate\": { \"month\": \"03\", \"year\": \"25\" },\n    \"cardNumber\": \"5597270000001815\",\n    \"cvc\": \"196\"\n  },\n  \"additional\": {\n    \"channelData\": { \"channel\": \"01\", \"source\": \"API_CARD\" }\n  },\n  \"kountSession\": \"58218d22a34f42cda041789b3abc9d50\"\n}\n\n</code></pre>\n<h4 id=\"ejemplo-de-datos-cifrados-en-base64-ed\">Ejemplo de datos cifrados en base64 (ed)</h4>\n<p>eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJBbmdlbCBHb256YWxleiIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMDMiLCJ5ZWFyIjoiMjUifSwiY2FyZE51bWJlciI6IjU1OTcyNzAwMDAwMDE4MTUiLCJjdmMiOiIxOTYifSwiYWRkaXRpb25hbCI6eyJjaGFubmVsRGF0YSI6eyJjaGFubmVsIjoiMDEiLCJzb3VyY2UiOiJBUElfQ0FSRCJ9fSwia291bnRTZXNzaW9uIjoiNTgyMThkMjJhMzRmNDJjZGEwNDE3ODliM2FiYzlkNTAifQ==</p>\n<hr />\n<h2 id=\"respuestas-de-la-preautorización\">Respuestas de la Preautorización</h2>\n<p>Dependiendo del resultado de la solicitud, la API puede devolver una respuesta exitosa o fallida.</p>\n<p>A continuación se describen ambos escenarios:</p>\n<hr />\n<h3 id=\"¿qué-es-el-http-code\">¿Qué es el HTTP code?</h3>\n<p>El HTTP code (código de estado HTTP) es un número que indica el resultado de una solicitud HTTP:</p>\n<ul>\n<li>Un código 200 significa que la solicitud fue exitosa.</li>\n<li>Cualquier código diferente a 200 (por ejemplo, 400, 401, 404, 500, etc.) indica que la solicitud falló por algún motivo.</li>\n</ul>\n<hr />\n<h3 id=\"respuesta-exitosa-http-code-200\">Respuesta Exitosa (HTTP code 200)</h3>\n<p>Cuando la preautorización es exitosa, la API responde con un código HTTP 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"statusCode\": 200,\n    \"jwt\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0cmFuc2FjdGlvbl9pZCI6IjhlMzJiNzYwLTA0Y2ItNDk3Ny05NzFmLWI5YjJmYjcwZDExMCIsImlhdCI6MTcxNjMwOTA4MywiZXhwIjoxNzE2MzEyNjgzfQ.qd39KMvng-ja31aCWQM8afVKZZVOEHW5uOagIQT5lno\"\n}\n\n</code></pre>\n<ul>\n<li>jwt: Token JWT con la información de la preautorización.</li>\n</ul>\n<p>Este campo <code>jwt</code> debe ser utilizado posteriormente en el endpoint de confirmación de preautorización para completar el proceso de cobro.</p>\n<hr />\n<h3 id=\"respuesta-fallida-http-code-diferente-de-200\">Respuesta Fallida (HTTP code diferente de 200)</h3>\n<p>Cuando la preautorización falla, la API responde con un código HTTP distinto de 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"message\": \"Error: Transaccion fraudulenta\",\n    \"status\": \"fail\"\n}\n\n</code></pre>\n<ul>\n<li>message: Descripción del motivo de la falla.</li>\n<li>status: Siempre será \"fail\" en caso de error.</li>\n</ul>\n<hr />\n<h2 id=\"webhook-de-respuesta\">Webhook de Respuesta</h2>\n<p>⚡ ¿Cómo funciona el Webhook?</p>\n<p>La URL del webhook debe ser configurada previamente desde el dashboard de GreenPay.</p>\n<p>Para este endpoint de preautorizaciones, la respuesta será enviada a la URL raíz del webhook que hayas configurado para tu comercio, agregando el path /preauthorize.</p>\n<p>Ejemplo:Si tu webhook es <a href=\"https://mywebhook.com/\">https://mywebhook.com/</a>, la respuesta de la preautorización por API llegará a la url <a href=\"https://mywebhook.com/preauthorize\">https://mywebhook.com/preauthorize</a>.</p>\n<p>GreenPay agregará el path /preauthorize, esa url debe existir en tu backend.El campo status en la respuesta del webhook indica el resultado de la transacción:</p>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-exitosa\">Ejemplo de respuesta exitosa</h3>\n<p>🟢 status: 200 en el campo status de la respuesta del webhook indica una transacción exitosa.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 200,\n  \"orderId\": \"compra-2024-10-24-USD-352\",\n  \"authorization\": \"831000\",\n  \"amount\": 318,\n  \"currency\": \"USD\",\n  \"token\": \"1f702dc0-9227-11ef-8a48-19ee98944b83\",\n  \"internalRef\": 10725057520759,\n  \"transactionId\": \"5f4914e0-6b3d-4369-982a-ed423b1bf9f4\",\n  \"errors\": [],\n  \"last4\": \"1815\",\n  \"quota\": 0,\n  \"brand\": \"Mastercard\"\n}\n\n</code></pre>\n<ul>\n<li>El campo <code>status</code> con valor 200 indica una transacción exitosa en la respuesta del webhook.</li>\n<li>El campo <code>quota</code> es para transacciones a plazos, se establece por defecto en 0 en la respuesta exitosa. Omitir este campo si no hace uso de transacciones a plazos.</li>\n</ul>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-fallida\">Ejemplo de respuesta fallida</h3>\n<p>🔴 status diferente de 200 en el campo status de la respuesta del webhook indica una transacción fallida.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 500,\n  \"orderId\": \"compra-2024-10-24-USD-353\",\n  \"authorization\": null,\n  \"amount\": 53,\n  \"currency\": \"USD\",\n  \"token\": null,\n  \"internalRef\": 8139382378302,\n  \"transactionId\": \"2d3af6f7-e610-4854-82ee-fb576da23cec\",\n  \"errors\": [\n    \"All other response codes received\"\n  ],\n  \"last4\": \"1815\",\n  \"brand\": \"Mastercard\"\n}\n\n</code></pre>\n<ul>\n<li>Si el campo <code>status</code> es diferente de 200, la transacción es considerada fallida en la respuesta del webhook.</li>\n</ul>\n<hr />\n","urlObject":{"path":["preauthorize"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"42b23e08-403c-4b79-af63-5a28a919c409","name":"Transacción exitosa","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n    \"ed\": \"{{Objeto JSON de la tarjeta con un hash base64 aplicado}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/preauthorize"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":""}],"cookie":[],"responseTime":null,"body":"{\n    \"statusCode\": 200,\n    \"jwt\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0cmFuc2FjdGlvbl9pZCI6IjhlMzJiNzYwLTA0Y2ItNDk3Ny05NzFmLWI5YjJmYjcwZDExMCIsImlhdCI6MTcxNjMwOTA4MywiZXhwIjoxNzE2MzEyNjgzfQ.qd39KMvng-ja31aCWQM8afVKZZVOEHW5uOagIQT5lno\"\n}"},{"id":"3cf4f046-e58a-4513-8fa9-ef5be9928d68","name":"Transacción fallida","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n    \"ed\": \"{{Objeto JSON de la tarjeta con un hash base64 aplicado}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/preauthorize"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":""}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Error: Transaccion fraudulenta\",\n    \"status\": \"fail\"\n}"}],"_postman_id":"cd6c1a07-c4fe-4f34-bbce-fd55eb9c6dd1"},{"name":"Confirm preauthorization","id":"06313d68-acc2-4a4f-af4e-d55cf373e62f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":""}]},"isInherited":false},"method":"POST","header":[],"url":"https://checkoutv2.greenpaysbx.me/confirm-pre-authorization","description":"<h1 id=\"confirmación-de-preautorización--api-v2\">Confirmación de Preautorización – API V2</h1>\n<p>Este endpoint es el último paso del flujo de pre-autorización de transacciones.</p>\n<p>Permite confirmar una preautorización previamente realizada, debitando el monto retenido en la tarjeta.</p>\n<hr />\n<h2 id=\"pasos-previos-realizar-una-preautorización\">Pasos Previos: Realizar una Preautorización</h2>\n<ol>\n<li>Realizar la preautorización:</li>\n</ol>\n<p>Debes haber realizado previamente una preautorización exitosa utilizando el endpoint de preautorización.</p>\n<ul>\n<li>Obtendrás un JWT (token) en la respuesta, que será necesario para este paso.</li>\n</ul>\n<ol>\n<li>Conservar el JWT:</li>\n</ol>\n<p>Guarda el JWT obtenido, ya que será requerido como Bearer Token en el header de la solicitud de confirmación.</p>\n<hr />\n<h2 id=\"endpoint-de-confirmación-de-preautorización\">Endpoint de Confirmación de Preautorización</h2>\n<ul>\n<li><p>Método: POST</p>\n</li>\n<li><p>Ambiente de desarrollo: <a href=\"https://checkoutv2.greenpaysbx.me/confirm-pre-authorization\">https://checkoutv2.greenpaysbx.me/confirm-pre-authorization</a></p>\n</li>\n<li><p>Ambiente productivo: <a href=\"https://checkoutv2.greenpay.me/confirm-pre-authorization\">https://checkoutv2.greenpay.me/confirm-pre-authorization</a></p>\n</li>\n<li><p>Descripción: Confirma una preautorización y debita el monto previamente retenido.</p>\n</li>\n<li><p>Requiere conexión segura: Sí, bajo TLS 1.2.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"headers\">Headers</h3>\n<p>⚠️ ¡Importante!</p>\n<p>El header de autenticación Bearer Token es obligatorio y debe ser enviado en cada solicitud a este endpoint.</p>\n<p>El valor del Bearer Token corresponde exactamente al JWT obtenido al realizar la preautorización.</p>\n<p>Si no se incluye este header, la confirmación será rechazada.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authorization</td>\n<td>String</td>\n<td>Bearer Token obtenido en la preautorización (formato: Bearer ).</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><p>Ejemplo de header Authorization:</p>\n<p>Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...</p>\n<hr />\n<h3 id=\"body-json\">Body (JSON)</h3>\n<p>No se requiere body en la solicitud. Toda la información necesaria se transmite en el JWT enviado en el header.</p>\n<hr />\n<h2 id=\"respuestas-de-la-confirmación-de-preautorización\">Respuestas de la Confirmación de Preautorización</h2>\n<p>Dependiendo del resultado de la solicitud, la API puede devolver una respuesta exitosa o fallida. A continuación se describen ambos escenarios:</p>\n<hr />\n<h3 id=\"¿qué-es-el-http-code\">¿Qué es el HTTP code?</h3>\n<p>El HTTP code (código de estado HTTP) es un número que indica el resultado de una solicitud HTTP:</p>\n<ul>\n<li><p>Un código 200 significa que la solicitud fue exitosa.</p>\n</li>\n<li><p>Cualquier código diferente a 200 (por ejemplo, 400, 401, 404, 500, etc.) indica que la solicitud falló por algún motivo.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"respuesta-exitosa-http-code-200\">Respuesta Exitosa (HTTP code 200)</h3>\n<p>Cuando la confirmación de preautorización es exitosa, la API responde con un código HTTP 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"statusCode\": 200,\n    \"status\": 200,\n    \"internalRef\": 57730533711,\n    \"orderId\": \"compra-2024-05-21-CRC-672\",\n    \"amount\": 12000,\n    \"currency\": \"CRC\",\n    \"token\": \"caae44d0-1791-11ef-9c9e-e3ed7042d9a8\",\n    \"transactionId\": \"d6e2ff9d-4ed2-4ed3-bab5-227953616199\",\n    \"webhook_url\": \"https://webhook.site/2fcc16c9-7c4f-4ac9-88d1-52d930ece6ec\",\n    \"authorization\": \"831000\"\n}\n\n</code></pre>\n<ul>\n<li><p>statusCode: Código HTTP de la respuesta (200 para éxito).</p>\n</li>\n<li><p>status: Código de estado de la transacción (200 para éxito).</p>\n</li>\n<li><p>internalRef: Referencia interna de la transacción.</p>\n</li>\n<li><p>orderId: Identificador de la orden de pago.</p>\n</li>\n<li><p>amount: Monto debitado.</p>\n</li>\n<li><p>currency: Moneda de la transacción.</p>\n</li>\n<li><p>token: Token de la transacción.</p>\n</li>\n<li><p>transactionId: Identificador único de la transacción.</p>\n</li>\n<li><p>webhook_url: URL a la que se notificó el resultado.</p>\n</li>\n<li><p>authorization: Código de autorización de la transacción.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"respuesta-fallida-http-code-diferente-de-200\">Respuesta Fallida (HTTP code diferente de 200)</h3>\n<p>Cuando la confirmación de preautorización falla, la API responde con un código HTTP distinto de 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"message\": \"No se ha enviado el token de autenticación\",\n    \"status\": \"fail\"\n}\n\n</code></pre>\n<ul>\n<li><p>message: Descripción del motivo de la falla.</p>\n</li>\n<li><p>status: Siempre será \"fail\" en caso de error.</p>\n</li>\n</ul>\n<hr />\n<h2 id=\"webhook-de-respuesta\">Webhook de Respuesta</h2>\n<p>⚡ ¿Cómo funciona el Webhook?</p>\n<p>La URL del webhook debe ser configurada previamente desde el dashboard de GreenPay.</p>\n<p>Para este endpoint de confirmación de preautorización, la respuesta será enviada a la URL raíz del webhook que hayas configurado para tu comercio, agregando el path /confirm-preauthorize.</p>\n<p>Ejemplo:Si tu webhook es <a href=\"https://mywebhook.com/\">https://mywebhook.com/</a>, la respuesta de la confirmación de preautorización por API llegará a la url <a href=\"https://mywebhook.com/confirm-preauthorize\">https://mywebhook.com/confirm-preauthorize</a>.</p>\n<p>GreenPay agregará el path /confirm-preauthorize, esa url debe existir en tu backend.</p>\n<p>El campo status en la respuesta del webhook indica el resultado de la transacción:</p>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-exitosa\">Ejemplo de respuesta exitosa</h3>\n<p>🟢 status: 200 en el campo status de la respuesta del webhook indica una transacción exitosa.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 200,\n  \"internalRef\": 13585077813588,\n  \"orderId\": \"compra-2024-10-25-USD-288\",\n  \"amount\": 613,\n  \"currency\": \"USD\",\n  \"token\": \"63947480-92ee-11ef-bd8e-177728d45168\",\n  \"transactionId\": \"6af91302-7993-4189-8fff-eaf55b47a4d4\",\n  \"webhook_url\": \"https://webhook.site/e8786529-8cbe-4463-8558-5c0aa3bd0963\",\n  \"authorization\": \"831000\"\n}\n\n</code></pre>\n<ul>\n<li>El campo status con valor 200 indica una transacción exitosa en la respuesta del webhook.</li>\n</ul>\n<hr />\n","urlObject":{"path":["confirm-pre-authorization"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"b3958c1a-7fb8-432d-a765-c69296ef615a","name":"Transacción exitosa","originalRequest":{"method":"POST","header":[],"url":"https://checkoutv2.greenpaysbx.me/confirm-pre-authorization"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":""}],"cookie":[],"responseTime":null,"body":"{\n    \"statusCode\": 200,\n    \"status\": 200,\n    \"internalRef\": 57730533711,\n    \"orderId\": \"compra-2024-05-21-CRC-672\",\n    \"amount\": 12000,\n    \"currency\": \"CRC\",\n    \"token\": \"caae44d0-1791-11ef-9c9e-e3ed7042d9a8\",\n    \"transactionId\": \"d6e2ff9d-4ed2-4ed3-bab5-227953616199\",\n    \"webhook_url\": \"https://webhook.site/2fcc16c9-7c4f-4ac9-88d1-52d930ece6ec\",\n    \"authorization\": \"831000\"\n}"},{"id":"b78a5c3d-c8c6-4e68-b7fa-68c2861c8e55","name":"Transacción fallida","originalRequest":{"method":"POST","header":[],"url":"https://checkoutv2.greenpaysbx.me/confirm-pre-authorization"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":""}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"No se ha enviado el token de autenticación\",\n    \"status\": \"fail\"\n}"}],"_postman_id":"06313d68-acc2-4a4f-af4e-d55cf373e62f"}],"id":"56975330-aa3e-478a-8d5c-af5884a4097c","description":"<p>Este servicio permite pre-autorizar un monto de una orden de pago, bloqueandolo en la cuenta del cliente para luego ser confirmado y debitado. Para utilizar el servicio de preautorización, es necesario <strong>crear una orden de pago antes de consumir este endpoint</strong>. Los valores de <strong>session y token</strong> generados al momento de crear la orden de pago son requeridos para el correcto funcionamiento de este servicio.</p>\n<p>El valor de \"ed\" corresponde a los datos de la tarjeta, estos datos deben enviarse en un objeto JSON y aplicar un hash con base64, el siguiente es un ejemplo de la estructura del objeto JSON:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">// Card data\nconst cardData = {\n  card: {\n    cardHolder: \"John Doe\",\n    expirationDate: {\n      month: \"12\",\n      year: \"31\",\n    },\n    cardNumber: \"4005529999000123\",\n    cvc: \"196\",\n  },\n  additional: { channelData: { channel: \"01\", source: \"API_CARD\" } },\n  kountSession: \"58218d22a34f42cda041789b3abc9d50\", // KOUNT SESSION ID FROM KOUNT SDK\n};\n\n</code></pre>\n<p><strong>Datos obligatorios:</strong></p>\n<ul>\n<li><p><code>card.cardHolder</code>: <strong>String</strong>. Nombre del dueño de la tarjeta. De 5 a 50 caracteres.</p>\n</li>\n<li><p><code>card.expirationDate.month</code>: <strong>String</strong>. Número que indica el mes de vencimiento de la tarjeta, este parámetro debe tener cifras entre 1 y 12.</p>\n</li>\n<li><p><code>card.expirationDate.year</code>: <strong>String</strong>. Número que indica el año de vencimiento de la tarjeta, este parámetro debe tener cifras de 2 dígitos, los últimos 2 dígitos del año en que vence la tarjeta.</p>\n</li>\n<li><p><code>card.cardNumber:</code><strong>String</strong>. Corresponde al número de la tarjeta</p>\n</li>\n<li><p><code>card.cvc</code> : <strong>String</strong>. Código de seguridad de la tarjeta.</p>\n</li>\n<li><p><code>additional</code>: <strong>Object</strong>. Debe ser la misma estructura del ejemplo, requerido por GreenPay</p>\n</li>\n<li><p><code>kountSession</code>: <strong>String.</strong> Es el valor <strong>params.MercSessId</strong> que se obtienen del Data Collector.</p>\n</li>\n</ul>\n<p>Por razones de seguridad, tanto para GreenPay como para proteger las transacciones de su comercio, se requiere que la información de la tarjeta o el token se envíe de forma segura, utilizando conexión segura bajo TLS 1.2.  Y cómo un método extra de seguridad, la información de la tarjeta se debe enviar codificada en base64.</p>\n<p>En <a href=\"https://bitbucket.org/greeenpay/checkout-v2-nodejs/src/main/\">greeenpay/checkout-v2-nodejs</a> podrá encontrar ejemplos de integración desarrollados en NodeJS.</p>\n","_postman_id":"56975330-aa3e-478a-8d5c-af5884a4097c"},{"name":"Revert","item":[{"name":"Revert Transaction","id":"9c37b771-0aec-4d43-8def-ef684708c4e0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"authorization\": \"{{Código de autorización de la transacción a revertir}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"transactionId\": \"{{ID de la transacción a revertir}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/revert","description":"<h1 id=\"reversión-de-transacción--api-v2\">Reversión de Transacción – API V2</h1>\n<p>Este endpoint permite revertir (anular) una transacción preautorizada.</p>\n<p>La posibilidad de realizar la reversión depende de la entidad bancaria emisora de la tarjeta: algunas entidades permiten la reversión inmediata, mientras que otras pueden rechazarla.</p>\n<hr />\n<h2 id=\"pasos-previos-haber-realizado-una-preautorización\">Pasos Previos: Haber Realizado una Preautorización</h2>\n<ol>\n<li>Realizar una preautorización:</li>\n</ol>\n<p>Debes haber realizado previamente una transacción exitosa (preautorización) utilizando los endpoints correspondientes.</p>\n<ul>\n<li><p>Obtendrás los siguientes datos necesarios para la reversión:</p>\n</li>\n<li><p>authorization: Código de autorización generado al realizar el pago.</p>\n</li>\n<li><p>merchantId: ID del comercio asignado por GreenPay.</p>\n</li>\n<li><p>transactionId: Identificador único de la transacción.</p>\n</li>\n</ul>\n<ol>\n<li>Considerar la entidad bancaria:</li>\n</ol>\n<p>La reversión solo será exitosa si la entidad bancaria emisora lo permite. Si la entidad no admite reversión, la operación será rechazada.</p>\n<hr />\n<h2 id=\"endpoint-de-reversión\">Endpoint de Reversión</h2>\n<ul>\n<li><p>Método: POST</p>\n</li>\n<li><p>Ambiente de desarrollo: <a href=\"https://checkoutv2.greenpaysbx.me/revert\">https://checkoutv2.greenpaysbx.me/revert</a></p>\n</li>\n<li><p>Ambiente productivo: <a href=\"https://checkoutv2.greenpay.me/revert\">https://checkoutv2.greenpay.me/revert</a></p>\n</li>\n<li><p>Descripción: Revierte una transacción previamente autorizada o preautorizada.</p>\n</li>\n<li><p>Requiere conexión segura: Sí, bajo TLS 1.2.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"body-json\">Body (JSON)</h3>\n<p>El cuerpo de la solicitud debe ser un objeto JSON con la siguiente estructura:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"authorization\": \"831000\",\n  \"merchantId\": \"6e792b4c-1f95-4895-9434-d6d4aa38d491\",\n  \"transactionId\": \"74f80564-d3f6-4738-bab2-d1d7fc91837f\"\n}\n\n</code></pre>\n<h4 id=\"campos-obligatorios-del-request\">Campos obligatorios del request</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>authorization</td>\n<td>String</td>\n<td>Código de autorización generado al realizar el pago.</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>merchantId</td>\n<td>String</td>\n<td>Merchant ID del comercio, provisto por GreenPay.</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>transactionId</td>\n<td>String</td>\n<td>Identificador único de la transacción generado al realizar el pago.</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"respuestas-de-la-reversión\">Respuestas de la Reversión</h2>\n<p>Dependiendo del resultado de la solicitud, la API puede devolver una respuesta exitosa o fallida.</p>\n<p>A continuación se describen ambos escenarios:</p>\n<hr />\n<h3 id=\"¿qué-es-el-http-code\">¿Qué es el HTTP code?</h3>\n<p>El HTTP code (código de estado HTTP) es un número que indica el resultado de una solicitud HTTP:</p>\n<ul>\n<li><p>Un código 200 significa que la solicitud fue exitosa.</p>\n</li>\n<li><p>Cualquier código diferente a 200 (por ejemplo, 400, 401, 404, 500, etc.) indica que la solicitud falló por algún motivo.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"respuesta-exitosa-http-code-200\">Respuesta Exitosa (HTTP code 200)</h3>\n<p>Cuando la reversión es exitosa, la API responde con un código HTTP 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"status\": 200,\n    \"errors\": [],\n    \"transactionId\": \"ff87e0ed-a796-4997-8dc4-3669d1201087\",\n    \"authorization\": \"831000\"\n}\n\n</code></pre>\n<ul>\n<li><p>status: Código de estado de la transacción (200 para éxito).</p>\n</li>\n<li><p>errors: Siempre es un arreglo vacío en respuestas exitosas.</p>\n</li>\n<li><p>transactionId: Identificador único de la transacción revertida.</p>\n</li>\n<li><p>authorization: Código de autorización de la transacción revertida.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"respuesta-fallida-http-code-diferente-de-200\">Respuesta Fallida (HTTP code diferente de 200)</h3>\n<p>Cuando la reversión falla, la API responde con un código HTTP distinto de 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"message\": \"Error: the transaction cannot be reversed\",\n    \"status\": \"fail\"\n}\n\n</code></pre>\n<ul>\n<li><p>message: Descripción del motivo de la falla.</p>\n</li>\n<li><p>status: Siempre será \"fail\" en caso de error.</p>\n</li>\n</ul>\n<hr />\n<h2 id=\"webhook-de-respuesta\">Webhook de Respuesta</h2>\n<p>⚡ ¿Cómo funciona el Webhook?</p>\n<p>La URL del webhook debe ser configurada previamente desde el dashboard de GreenPay.</p>\n<p>Para este endpoint de reversión, la respuesta será enviada a la URL raíz del webhook que hayas configurado para tu comercio, agregando el path <code>/revert</code>.</p>\n<p>Ejemplo:Si tu webhook es <code>https://mywebhook.com/</code>, la respuesta de la reversión por API llegará a la url <a href=\"https://mywebhook.com/revert\">https://mywebhook.com/revert</a>.</p>\n<p>GreenPay agregará el path <code>/revert</code>, esa url debe existir en tu backend.</p>\n<p>Nota: Actualmente, solo las respuestas exitosas de reversión llegan al webhook.</p>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-exitosa-al-webhook\">Ejemplo de respuesta exitosa al webhook</h3>\n<p>🟢 status: 200 en el campo status de la respuesta del webhook indica una reversión exitosa.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 200,\n  \"errors\": [],\n  \"transactionId\": \"ff87e0ed-a796-4997-8dc4-3669d1201087\",\n  \"authorization\": \"831000\"\n}\n\n</code></pre>\n<ul>\n<li>El campo status con valor 200 indica una reversión exitosa en la respuesta del webhook.</li>\n</ul>\n","urlObject":{"path":["revert"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"9e0eab81-5c53-49cd-bee8-624f4d195395","name":"Reversión exitosa","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"authorization\": \"{{Código de autorización de la transacción a revertir}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"transactionId\": \"{{ID de la transacción a revertir}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/revert"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": 200,\n    \"errors\": [],\n    \"transactionId\": \"ff87e0ed-a796-4997-8dc4-3669d1201087\",\n    \"authorization\": \"831000\"\n}"},{"id":"92fd306c-0190-4f9d-a5f5-a8ac5e15e0af","name":"Reversión fallida","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"authorization\": \"{{Código de autorización de la transacción a revertir}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"transactionId\": \"{{ID de la transacción a revertir}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/revert"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Error: the transaction cannot be reversed\",\n    \"status\": \"fail\"\n}"}],"_postman_id":"9c37b771-0aec-4d43-8def-ef684708c4e0"}],"id":"66a783a7-47ca-4bb4-99e9-f0bc676e9531","description":"<p>El método de reversión de transacciones le permite, como su nombre lo indica, reversar una transacción que ya fue procesada por GreenPay, para realizar una reversión, es necesario que la transacción aún no haya sido liquidada por la entidad bancaria, de lo contrario esta opción ya no va a estar disponible.</p>\n","_postman_id":"66a783a7-47ca-4bb4-99e9-f0bc676e9531"},{"name":"Tokenization","item":[{"name":"Create a Tokenization Order","id":"b0f04c12-e080-459b-bab7-3e2f6d5f40d2","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"secret\": \"{{Secret provisto por GreenPay}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"requestId\": \"204\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenizeOrder","description":"<h1 id=\"creación-de-orden-de-tokenización--api-v2\">Creación de Orden de Tokenización – API V2</h1>\n<p>Este endpoint recopila la información necesaria para ejecutar una orden de tokenización de tarjeta en GreenPay, permitiendo que la tarjeta sea utilizada posteriormente en transacciones de forma segura.</p>\n<p>Este paso es necesario para tokenizar una tarjeta, ya sea utilizando la API directamente o mediante el formulario de tokenización (tokenizeForm) provisto por GreenPay</p>\n<p>.Al ejecutar este request se genera un ID de sesión que será requerido en el siguiente paso del flujo.</p>\n<hr />\n<h2 id=\"endpoint-de-tokenización\">Endpoint de Tokenización</h2>\n<ul>\n<li><p>Método: POST</p>\n</li>\n<li><p>Sandbox: <a href=\"https://checkoutv2.greenpaysbx.me/tokenizeOrder\">https://checkoutv2.greenpaysbx.me/tokenizeOrder</a></p>\n</li>\n<li><p>Producción: <a href=\"https://checkoutv2.greenpay.me/tokenizeOrder\">https://checkoutv2.greenpay.me/tokenizeOrder</a></p>\n</li>\n<li><p>Descripción: Crea una orden de tokenización y retorna los identificadores necesarios para continuar el proceso.</p>\n</li>\n<li><p>Requiere conexión segura: Sí, bajo TLS 1.2.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"consideraciones\">Consideraciones</h3>\n<ul>\n<li><p>Una orden de tokenización genera una respuesta en formato JSON que contiene los campos statusCode, session y token.</p>\n</li>\n<li><p>Los valores de session y token tendrán una vigencia de 30 minutos desde su creación. Pasado ese plazo, será necesario crear una nueva orden.</p>\n</li>\n<li><p>Se recomienda que este proceso se realice en el backend del comercio para proteger los datos sensibles.</p>\n</li>\n<li><p>Este paso es obligatorio tanto si vas a tokenizar la tarjeta por API como si vas a utilizar el formulario de tokenización (tokenizeForm).</p>\n</li>\n</ul>\n<hr />\n<h2 id=\"body-json\">Body (JSON)</h2>\n<p>El cuerpo de la solicitud debe ser un objeto JSON con la siguiente estructura:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"secret\": \"secret provisto por GreenPay 2.0\",\n    \"merchantId\": \"merchant provisto por GreenPay 2.0\",\n    \"requestId\": \"número entero para identificar la orden\",\n    \"callback\": \"https://tudominio.com/callback\" // Opcional\n}\n\n</code></pre>\n<h3 id=\"campos-obligatorios-del-request\">Campos obligatorios del request</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>secret</td>\n<td>String</td>\n<td>Llave secreta provista por GreenPay 2.0</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>merchantId</td>\n<td>String</td>\n<td>Identificador único para el comercio, provisto por GreenPay 2.0</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>requestId</td>\n<td>Integer</td>\n<td>Número entero para identificar la orden</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>callback</td>\n<td>String</td>\n<td>URL para notificación de callback (5-200 caracteres)</td>\n<td>No</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"respuestas-de-la-api\">Respuestas de la API</h2>\n<p>Dependiendo del resultado de la solicitud, la API puede devolver una respuesta exitosa o fallida. A continuación se describen ambos escenarios:</p>\n<hr />\n<h3 id=\"¿qué-es-el-http-code\">¿Qué es el HTTP code?</h3>\n<p>El HTTP code (código de estado HTTP) es un número que indica el resultado de una solicitud HTTP:</p>\n<ul>\n<li><p>Un código 200 significa que la solicitud fue exitosa.</p>\n</li>\n<li><p>Cualquier código diferente a 200 (por ejemplo, 400, 401, 404, 500, etc.) indica que la solicitud falló por algún motivo.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"respuesta-exitosa-http-code-200\">Respuesta Exitosa (HTTP code 200)</h3>\n<p>Cuando la orden de tokenización es exitosa, la API responde con un código HTTP 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"statusCode\": 200,\n    \"session\": \"251da6a5-9cc1-4a8c-9b75-2fddc3627ae4\",\n    \"token\": \"84336c9a-32d3-4616-84f4-e78b344af60a\"\n}\n\n</code></pre>\n<ul>\n<li><p>statusCode: Código HTTP de la respuesta (200 para éxito).</p>\n</li>\n<li><p>session: Identificador de sesión generado para la orden de tokenización.</p>\n</li>\n<li><p>token: Token generado para la orden de tokenización.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"respuesta-fallida-http-code-diferente-de-200\">Respuesta Fallida (HTTP code diferente de 200)</h3>\n<p>Cuando la orden de tokenización falla, la API responde con un código HTTP distinto de 200 y un objeto JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"message\": \"Error al tokenizar la Información!\",\n    \"status\": \"fail\"\n}\n\n</code></pre>\n<ul>\n<li><p>message: Descripción del motivo de la falla.</p>\n</li>\n<li><p>status: Siempre será \"fail\" en caso de error.</p>\n</li>\n</ul>\n","urlObject":{"path":["tokenizeOrder"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"85f3a8c1-c4f6-4201-a902-c77b1208417f","name":"Creacion orden tokenizacion exitosa","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"secret\": \"{{Secret provisto por GreenPay}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"requestId\": \"321\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenizeOrder"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":""}],"cookie":[],"responseTime":null,"body":"{\n    \"statusCode\": 200,\n    \"session\": \"251da6a5-9cc1-4a8c-9b75-2fddc3627ae4\",\n    \"token\": \"84336c9a-32d3-4616-84f4-e78b344af60a\"\n}"},{"id":"50147777-bd4b-4465-b0b8-28a32f917ebb","name":"Creacion orden tokenizacion Fallida","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"secret\": \"{{Secret provisto por GreenPay}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"requestId\": \"633\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenizeOrder"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":""}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Error al tokenizar la Información!\",\n    \"status\": \"fail\"\n}"}],"_postman_id":"b0f04c12-e080-459b-bab7-3e2f6d5f40d2"},{"name":"Tokenize card","id":"6ac4f3a2-751d-454e-878a-14607ddd5458","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"session-token","value":"Valor obtenido de la sessión al momento de crear orden de tokenizacion","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n    \"ed\": \"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIs...\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenizeCard","description":"<h1 id=\"tokenización-de-tarjeta--api-v2\">Tokenización de Tarjeta – API V2</h1>\n<p>Este endpoint permite tokenizar una tarjeta de crédito o débito para su uso seguro en futuras transacciones.</p>\n<p>Antes de utilizar este servicio, primero debes crear una orden de tokenización.</p>\n<p>El valor de session generado al crear la orden es requerido para el correcto funcionamiento de este endpoint.</p>\n<hr />\n<h2 id=\"1-paso-previo-crear-orden-de-tokenización\">1. Paso Previo: Crear Orden de Tokenización</h2>\n<ol>\n<li>Crear la orden de tokenización:</li>\n</ol>\n<p>Realiza una solicitud al endpoint correspondiente para crear una orden de tokenización.</p>\n<ul>\n<li><p>Obtendrás el valor importante:</p>\n</li>\n<li><p><code>session</code>: Identificador de la sesión de la orden de tokenización (UUID).</p>\n</li>\n</ul>\n<ol>\n<li>Conservar el valor:</li>\n</ol>\n<p>Guarda el valor de <code>session</code>, ya que será requerido para la tokenización.</p>\n<hr />\n<h2 id=\"endpoint-de-tokenización\">Endpoint de Tokenización</h2>\n<ul>\n<li><p>Método: POST</p>\n</li>\n<li><p>Sandbox: <code>https://checkoutv2.greenpaysbx.me/tokenizeCard</code></p>\n</li>\n<li><p>Producción: <code>https://checkoutv2.greenpay.me/tokenizeCard</code></p>\n</li>\n<li><p>Requiere conexión segura: Sí, bajo TLS 1.2.</p>\n</li>\n<li><p>Cifrado de datos: Los datos de la tarjeta deben enviarse en formato JSON, codificados en base64.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"headers\">Headers</h3>\n<p>⚠️ ¡Importante!</p>\n<p>El header session-token es obligatorio y debe ser enviado en cada solicitud a este endpoint.El valor de session-token corresponde exactamente al session obtenido al crear la orden de tokenización.Si no se incluye este header, la tokenización será rechazada.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>session-token</td>\n<td>String</td>\n<td>Token obtenido en la creación de la orden de tokenización.</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><p>Ejemplo de session-token (UUID):b1249250-e620-11ee-a8be-d1e162aad25c</p>\n<hr />\n<h3 id=\"body-json\">Body (JSON)</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"session\": \"b1249250-e620-11ee-a8be-d1e162aad25c\",\n  \"ed\": \"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMTIiLCJ5ZWFyIjoiMzEifSwiY2FyZE51bWJlciI6IjU1OTcyNzAwMDAwMDE4MTUiLCJjdmMiOiIxOTYifX0=\"\n}\n\n</code></pre>\n<ul>\n<li><p><code>session</code>: UUID obtenido al crear la orden de tokenización (requerido).</p>\n</li>\n<li><p><code>ed</code>: Datos de la tarjeta cifrados en base64 (requerido, ver estructura y ejemplo abajo).</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"campos-obligatorios-del-request\">Campos obligatorios del request</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>session</td>\n<td>String</td>\n<td>Sesión obtenida al crear la orden de tokenización (UUID)</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>ed</td>\n<td>String</td>\n<td>Datos de la tarjeta cifrados en base64</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"estructura-del-objeto-antes-de-codificar-en-base64-ed\">Estructura del objeto antes de codificar en base64 (ed)</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Restricciones / Ejemplo</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>card.cardHolder</td>\n<td>String</td>\n<td>Nombre del titular de la tarjeta</td>\n<td>5-50 caracteres, Ej: \"John Doe\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.month</td>\n<td>String</td>\n<td>Mes de vencimiento de la tarjeta</td>\n<td>2 caracteres, \"01\" a \"12\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.year</td>\n<td>String</td>\n<td>Año de vencimiento (últimos 2 dígitos)</td>\n<td>2 caracteres, Ej: \"31\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cardNumber</td>\n<td>String</td>\n<td>Número de la tarjeta</td>\n<td></td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cvc</td>\n<td>String</td>\n<td>Código de seguridad de la tarjeta</td>\n<td></td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"ejemplo-de-objeto-antes-de-base64\">Ejemplo de objeto antes de base64</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"card\": {\n    \"cardHolder\": \"John Doe\",\n    \"expirationDate\": { \"month\": \"12\", \"year\": \"31\" },\n    \"cardNumber\": \"5597270000001815\",\n    \"cvc\": \"196\"\n  }\n}\n\n</code></pre>\n<h4 id=\"ejemplo-de-datos-cifrados-en-base64-ed\">Ejemplo de datos cifrados en base64 (ed)</h4>\n<p>eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIsImV4cGlyYXRpb25EYXRlIjp7Im1vbnRoIjoiMTIiLCJ5ZWFyIjoiMzEifSwiY2FyZE51bWJlciI6IjU1OTcyNzAwMDAwMDE4MTUiLCJjdmMiOiIxOTYifX0=</p>\n<p>¿Cómo cifrar los datos de la tarjeta?Por seguridad, la información de la tarjeta debe enviarse codificada en base64 y a través de una conexión segura (TLS 1.2).</p>\n<p>Ejemplo en JavaScript:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">const cardData = {\n  card: {\n    cardHolder: \"John Doe\",\n    expirationDate: {\n      month: \"12\",\n      year: \"31\"\n    },\n    cardNumber: \"5597270000001815\",\n    cvc: \"196\"\n  }\n};\nconst base64 = Buffer.from(JSON.stringify(cardData)).toString(\"base64\");\nconsole.log(base64);\n\n</code></pre>\n<p>El valor resultante (base64) se debe enviar en el campo ed del cuerpo de la petición.</p>\n<hr />\n<h2 id=\"ejemplo-de-respuesta-exitosa\">Ejemplo de Respuesta Exitosa</h2>\n<p>HTTP 200</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"statusCode\": 200,\n    \"result\": {\n        \"cardHolder\": \"John Doe\",\n        \"brand\": \"Visa\",\n        \"bin\": \"455676\",\n        \"last4\": \"6446\",\n        \"khash\": \"455676SNB18A5F1T3QWC\",\n        \"token\": \"b1249250-e620-11ee-a8be-d1e162aad25c\",\n        \"cardMasked\": \"455676******6446\"\n    }\n}\n\n</code></pre>\n<p>&gt; El campo <code>result.token</code> es el valor que debe guardarse en su base de datos para identificar la tarjeta de forma segura.</p>\n<p>&gt; Para realizar pagos futuros con esta tarjeta, deberá utilizar este token en el endpoint correspondiente a pagos con token, siguiendo el flujo y la documentación específica para pagos con token.</p>\n<hr />\n<h2 id=\"ejemplo-de-respuesta-fallida\">Ejemplo de Respuesta Fallida</h2>\n<p>HTTP diferente de 200</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"message\": \"Encabezado invalido: Session-Token es requerido\",\n    \"status\": \"fail\"\n}\n\n</code></pre>\n<hr />\n<h2 id=\"webhook-de-respuesta\">Webhook de Respuesta</h2>\n<p>⚡ ¿Cómo funciona el Webhook?</p>\n<p>La URL del webhook debe ser configurada previamente desde el dashboard de GreenPay.</p>\n<p>Para este endpoint de tokenización de tarjeta, la respuesta será enviada a la URL raíz del webhook que hayas configurado para tu comercio, agregando el path /tokenizeCard.</p>\n<p>Ejemplo:Si tu webhook es <a href=\"https://mywebhook.com/\">https://mywebhook.com/</a>, la respuesta de la tokenización por API llegará a la url <a href=\"https://mywebhook.com/tokenizeCard\">https://mywebhook.com/tokenizeCard</a>.</p>\n<p>GreenPay agregará el path /tokenizeCard, esa url debe existir en tu backend.Nota: Actualmente, solo las respuestas exitosas de tokenización llegan al webhook.</p>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-exitosa-al-webhook\">Ejemplo de respuesta exitosa al webhook</h3>\n<p>🟢 statusCode: 200 en el campo statusCode de la respuesta del webhook indica una tokenización exitosa.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"statusCode\": 200,\n    \"result\": {\n        \"cardHolder\": \"John Doe\",\n        \"brand\": \"Visa\",\n        \"bin\": \"455676\",\n        \"last4\": \"6446\",\n        \"khash\": \"455676SNB18A5F1T3QWC\",\n        \"token\": \"b1249250-e620-11ee-a8be-d1e162aad25c\",\n        \"cardMasked\": \"455676******6446\"\n    }\n}\n\n</code></pre>\n<ul>\n<li>El campo statusCode con valor 200 indica una tokenización exitosa en la respuesta del webhook.</li>\n</ul>\n","urlObject":{"path":["tokenizeCard"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"bea60873-ca34-4905-97ad-32da1bd3414a","name":"Tokenizacion exitosa","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n    \"ed\": \"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIs...\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenizeOrder"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":""}],"cookie":[],"responseTime":null,"body":"{\n    \"statusCode\": 200,\n    \"result\": {\n        \"cardHolder\": \"John Doe\",\n        \"brand\": \"Visa\",\n        \"bin\": \"455676\",\n        \"last4\": \"6446\",\n        \"khash\": \"455676SNB18A5F1T3QWC\",\n        \"token\": \"b1249250-e620-11ee-a8be-d1e162aad25c\",\n        \"cardMasked\": \"455676******6446\"\n    }\n}"},{"id":"3320cb00-bd66-4e86-8620-8a2895778073","name":"Tokenizacion fallida","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"Valor obtenido de la sessión al momento de crear orden de tokenizacion","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n    \"ed\": \"eyJjYXJkIjp7ImNhcmRIb2xkZXIiOiJKb2huIERvZSIs...\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenizeCard"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Encabezado invalido: Session-Token es requerido\",\n    \"status\": \"fail\"\n}"}],"_postman_id":"6ac4f3a2-751d-454e-878a-14607ddd5458"}],"id":"05069ad2-33c9-44e0-927a-356368b274e7","description":"<p>Los siguientes métodos son utilizados para la tokenización de tarjetas y su posterior uso en las compras que se realizan utilizando el ecosistema de GreenPay. Estos métodos permiten crear un token de una tarjeta utilizando algoritmos de cifrado, permitiendo guardar la información de las tarjetas de forma segura, para luego utilizarse para realizar transacciones usando únicamente el ID del token.</p>\n<p>En <a href=\"https://bitbucket.org/greeenpay/tokenize-v2-nodejs/src/main/\">greenpay/tokenization-v2</a> puede encontrar un ejemplo desarrollado con NodeJs.</p>\n<p>Para utilizar este servicio es necesario crear una orden de tokenización y luego ejecutarla con los datos de la tarjeta hasheados según se muestra en los ejemplos siguientes:</p>\n","_postman_id":"05069ad2-33c9-44e0-927a-356368b274e7"},{"name":"3DS","item":[{"name":"PA SETUP","event":[{"listen":"test","script":{"id":"aead09e8-1a83-440c-95ef-791e25ca15e4","exec":["var jsonData = JSON.parse(responseBody);","postman.setEnvironmentVariable(\"referenceId\", jsonData.result.referenceId);","postman.setEnvironmentVariable(\"transactionId\", jsonData.result.transaction.id);"],"type":"text/javascript","packages":{}}}],"id":"22830e44-251b-422d-ba36-cd9ab44a5848","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/3ds/setup","description":"<h1 id=\"setup-3ds--api-v2\">Setup 3DS – API V2</h1>\n<p>&gt; Descripción: Este endpoint permite realizar el Setup o Configuración Inicial de la Autenticación del Pago utilizando los servicios de Cybersource 3DS.</p>\n<h2 id=\"resumen\">Resumen</h2>\n<p>El Setup 3DS retorna un objeto JSON con la información devuelta por Cybersource para ejecutar el proceso de recolección de información del tarjeta habiente y su dispositivo; y también devuelve la información de la transacción creada en GreenPay para su posterior procesamiento.</p>\n<h3 id=\"requisitos-obligatorios\">Requisitos Obligatorios</h3>\n<ul>\n<li>Ejecutar correctamente el script de recolección de información recibido en la respuesta</li>\n<li>Crear una orden de pago previamente</li>\n<li>Codificar datos en formato base64</li>\n</ul>\n<hr />\n<h2 id=\"pasos-previos-crear-una-orden-de-pago\">Pasos Previos: Crear una Orden de Pago</h2>\n<h3 id=\"1-crear-la-orden-de-pago\">1. Crear la Orden de Pago</h3>\n<p>Realiza una solicitud al endpoint correspondiente para crear una orden de pago.Valores que obtendrás:</p>\n<ul>\n<li><code>session</code>: Identificador de la sesión de la orden de pago (UUID)</li>\n<li><code>token:</code> Token de seguridad para la sesión (UUID)</li>\n</ul>\n<h3 id=\"2-conservar-los-valores\">2. Conservar los Valores</h3>\n<p>Guarda los valores de <code>session</code> y <code>token</code>, ya que serán requeridos para el setup 3DS.</p>\n<hr />\n<h2 id=\"endpoint-de-setup-3ds\">Endpoint de Setup 3DS</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Propiedad</th>\n<th>Valor</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Método</td>\n<td>POST</td>\n</tr>\n<tr>\n<td>Descripción</td>\n<td>Configuración inicial de la autenticación 3DS</td>\n</tr>\n<tr>\n<td>Conexión Segura</td>\n<td>Sí, bajo TLS 1.2</td>\n</tr>\n<tr>\n<td>Cifrado de Datos</td>\n<td>JSON codificado en base64</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"headers\">Headers</h2>\n<h3 id=\"header-obligatorio\">Header Obligatorio</h3>\n<p>El header <code>session-token</code> es obligatorio y debe ser enviado en cada solicitud a este endpoint.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>session-token</td>\n<td>String</td>\n<td>Token obtenido en la creación de la orden de pago</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><p>Ejemplo de session-token (UUID):</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>79b9b0-917d-11ef-8a48-19ee98944b83\n\n</code></pre><hr />\n<h2 id=\"body-json\">Body (JSON)</h2>\n<h3 id=\"estructura-del-request\">Estructura del Request</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"cardData\": {\n        \"session\": \"\",\n        \"ed\": \"\"\n    }\n}\n\n</code></pre>\n<h3 id=\"campos-obligatorios\">Campos Obligatorios</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>cardData.session</td>\n<td>String</td>\n<td>Sesión obtenida al crear la orden de pago (UUID)</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>cardData.ed</td>\n<td>String</td>\n<td>Datos de la tarjeta cifrados en base64</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"estructura-del-objeto-ed-antes-de-base64\">Estructura del Objeto ed (antes de base64)</h2>\n<h3 id=\"formato-json\">Formato JSON</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n   \"card\": {\n    \"cardHolder\": \"John Doe\",\n    \"expirationDate\": {\n      \"month\": \"12\",\n      \"year\": \"31\"\n    },\n    \"cardNumber\": \"5597270000001815\",\n    \"cvc\": \"196\"\n  },\n   \"additional\": { \n     \"channelData\": { \n       \"channel\": \"01\", \n       \"source\": \"API_CARD\" \n     } \n   }\n}\n\n</code></pre>\n<h3 id=\"campos-detallados\">Campos Detallados</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Restricciones</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>card.cardHolder</td>\n<td>String</td>\n<td>Nombre del dueño de la tarjeta</td>\n<td>5-50 caracteres</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.month</td>\n<td>String</td>\n<td>Mes de vencimiento</td>\n<td>2 caracteres, \"01\" a \"12\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.year</td>\n<td>String</td>\n<td>Año de vencimiento (últimos 2 dígitos)</td>\n<td>2 caracteres, Ej: \"31\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cardNumber</td>\n<td>String</td>\n<td>Número de la tarjeta</td>\n<td>-</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cvc</td>\n<td>String</td>\n<td>Código de seguridad de la tarjeta</td>\n<td>-</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.channel</td>\n<td>String</td>\n<td>Canal</td>\n<td>Debe ser \"01\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.source</td>\n<td>String</td>\n<td>Fuente</td>\n<td>Debe ser \"API_CARD\"</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"respuestas-del-setup-3ds\">Respuestas del Setup 3DS</h2>\n<h3 id=\"¿qué-es-el-http-code\">¿Qué es el HTTP Code?</h3>\n<p>El HTTP code (código de estado HTTP) es un número que indica el resultado de una solicitud HTTP:</p>\n<ul>\n<li>200 = Solicitud exitosa</li>\n<li>400, 401, 404, 500, etc. = Solicitud fallida</li>\n</ul>\n<hr />\n<h2 id=\"respuesta-exitosa-http-code-200\">Respuesta Exitosa (HTTP Code 200)</h2>\n<h3 id=\"ejemplo-de-respuesta\">Ejemplo de Respuesta</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"statusCode\": 200,\n    \"result\": {\n        \"id\": \"7497614919326700604807\",\n        \"status\": \"COMPLETED\",\n        \"jwt\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0N2Q5MDIxYy01MjFkLTRhMzMtODU4Ny0wMjBiMWU1MzFlMGQiLCJpYXQiOjE3NDk3NjE0OTIsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTc0OTc2NTA5MiwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUmVmZXJlbmNlSWQiOiJiOGViNjdlNy1iNTVhLTQyNzgtOGIwYi0yYjlkZDc1MDZlZjAifQ.E6WmdgsAErA58FGya7ezOqwvo8M6ipCBkGZHfXtww7s\",\n        \"referenceId\": \"b8eb67e7-b55a-4278-8b0b-2b9dd7506ef0\",\n        \"deviceDataCollectionUrl\": \"https://centinelapistag.cardinalcommerce.com/V1/Cruise/Collect\",\n        \"code\": \"aa6b2d21-3775-4d40-a59b-714873b3afe1\",\n        \"transaction\": {\n            \"id\": \"aa6b2d21-3775-4d40-a59b-714873b3afe1\",\n            \"status\": \"CYBS_PA_SETUP\",\n            \"description\": \"Demo Payment 97592\",\n            \"authorization\": \"\",\n            \"webhook_url\": \"https://webhook.site/940cf625-447e-4da3-8eac-be7c2470ee0f\",\n            \"customer\": {\n                \"name\": \"John Doe\",\n                \"email\": \"john.doe@example.com\",\n                \"identification\": \"123456789\",\n                \"billingAddress\": {\n                    \"country\": \"US\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"zip\": \"90001\"\n                },\n                \"shippingAddress\": {\n                    \"country\": \"US\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"zip\": \"90001\"\n                }\n            },\n            \"entity_response\": \"\",\n            \"card\": {\n                \"bin\": \"445653\",\n                \"brand\": \"Visa\",\n                \"last4\": \"1096\"\n            },\n            \"quota\": 0\n        }\n    }\n}\n\n</code></pre>\n<h3 id=\"campos-importantes\">Campos Importantes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Descripción</th>\n<th>Validación</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>result.transaction.status</td>\n<td>Estado de la transacción</td>\n<td>Debe ser 'CYBS_PA_SETUP'</td>\n</tr>\n<tr>\n<td>result.deviceDataCollectionUrl</td>\n<td>URL para recolección de datos</td>\n<td>Requerida para el siguiente paso</td>\n</tr>\n<tr>\n<td>result.jwt</td>\n<td>Token JWT para recolección</td>\n<td>Incluir en el formulario</td>\n</tr>\n<tr>\n<td>result.code</td>\n<td>Código de referencia 3DS</td>\n<td>Usar en el enrollment</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"⚠️-consideraciones-importantes\">⚠️ Consideraciones Importantes</h3>\n<p>&gt; IMPORTANTE:</p>\n<p>Siempre validar <code>result.transaction.status === 'CYBS_PA_SETUP'</code></p>\n<p>&gt; Si el setup es exitoso, el estado a validar es <code>result.transaction.status === 'CYBS_PA_SETUP'</code></p>\n<p>&gt; Si el setup es exitoso, se debe recolectar los datos del navegador tal como pide 3DS</p>\n<p>&gt; Para ejecutar el enrollment se debe esperar la respuesta de recolección de datos</p>\n<p>&gt; Tener en consideración que el HTTP status puede ser 200 pero siempre validar el <code>result.transaction.status</code> como se menciona</p>\n<hr />\n<h2 id=\"respuesta-fallida-http-code-200-pero-status-failed\">Respuesta Fallida (HTTP Code 200 pero Status FAILED)</h2>\n<h3 id=\"ejemplo-de-respuesta-1\">Ejemplo de Respuesta</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"result\": {\n        \"error\": {\n            \"status\": 400,\n            \"reason\": \"undefined - undefined\",\n            \"message\": \"Error al realizar la operación\"\n        },\n        \"statusCode\": 400,\n        \"status\": \"fail\",\n        \"orderId\": \"Prueba\",\n        \"token\": \"20d74179-b30b-474a-827c-de361a6d3260\",\n        \"transactionId\": \"1c738200-c322-4f22-864c-8af39aeedebb\",\n        \"amount\": 2000,\n        \"currency\": \"CRC\",\n        \"transaction\": {\n            \"id\": \"1c738200-c322-4f22-864c-8af39aeedebb\",\n            \"currency\": \"CRC\",\n            \"amount\": 2000,\n            \"reference_number\": \"prueba\",\n            \"merchant_id\": \"d079b971-26ec-4833-80bb-7f2de5d63f56\",\n            \"terminal\": \"bb37db9f-26f0-4e4f-9d74-c70f9be4ef9f\",\n            \"internal_ref\": 6207483762900,\n            \"quota\": 0,\n            \"status\": \"FAILED\",\n            \"created_at\": \"2025-06-19T13:54:07.880Z\",\n            \"updated_at\": \"2025-06-19T13:54:07.880Z\",\n            \"merchant_name\": \"3DS prueba\",\n            \"statusCode\": 201,\n            \"entity_response\": {},\n            \"orderReference\": \"Test\"\n        },\n        \"quota\": 0,\n        \"cause\": {\n            \"origin\": \"AFPASETUP3DS\"\n        }\n    }\n}\n\n</code></pre>\n<h3 id=\"⚠️-consideraciones-de-error\">⚠️ Consideraciones de Error</h3>\n<p>&gt; IMPORTANTE:</p>\n<p>Validar siempre <code>result.transaction.status === 'FAILED</code>' significa error</p>\n<p>&gt; Para obtener el string de error recomendamos:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\"> let errorMessage = result?.error?.message ?? result.error\n\n</code></pre>\n<p>&gt; Tener en consideración que el HTTP status puede ser 200 pero siempre validar el <code>result.transaction.status</code> como se menciona</p>\n<hr />\n<h2 id=\"respuesta-fallida-http-code-400---error-de-validaciones\">Respuesta Fallida (HTTP Code 400 - Error de Validaciones)</h2>\n<h3 id=\"ejemplo-de-respuesta-2\">Ejemplo de Respuesta</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"message\": \"Event object failed validation\",\n    \"status\": 400\n}\n\n</code></pre>\n<h3 id=\"⚠️-consideraciones-importantes-1\">⚠️ Consideraciones Importantes</h3>\n<p>&gt; En este caso:</p>\n<p>&gt; Cuando es este caso, tener en cuenta que la estructura de error cambia y el mensaje de error viene en <code>message</code></p>\n<p>&gt; En este caso el HTTP code es 400 y es el único caso</p>\n<p>&gt; Validar que esté mandando bien las keys del objeto</p>\n<hr />\n<h2 id=\"creación-del-iframe-y-recolección-de-datos\">Creación del iFrame y Recolección de Datos</h2>\n<h3 id=\"descripción\">Descripción</h3>\n<p>Después de recibir una respuesta exitosa del setup 3DS, es obligatorio crear un iFrame para la recolección de datos del dispositivo del usuario. Esta recolección debe completarse antes de continuar con el proceso de enrollment.</p>\n<h3 id=\"datos-utilizados-de-la-respuesta-exitosa\">Datos Utilizados de la Respuesta Exitosa</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>deviceDataCollectionUrl</td>\n<td>URL donde se enviará el formulario</td>\n</tr>\n<tr>\n<td>jwt</td>\n<td>Token JWT que se incluye en el formulario</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"proceso-de-creación-del-iframe\">Proceso de Creación del iFrame</h3>\n<ol>\n<li>Crear un iFrame oculto para la recolección de datos</li>\n<li>Crear un formulario que se enviará a la URL de recolección</li>\n<li>Incluir el JWT en el formulario</li>\n<li>Enviar el formulario automáticamente</li>\n<li>Esperar el evento que indica que la recolección fue exitosa</li>\n</ol>\n<hr />\n<h2 id=\"ejemplo-de-código\">Ejemplo de Código</h2>\n<h3 id=\"crear-y-enviar-el-iframe\">Crear y Enviar el iFrame</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">const createiFrameSetup3DS = async (data: Setup3dsResponseInterface) =&gt; {\n    // Crear el iframe para la recolección de datos del navegador\n    const iframe = document.createElement('iframe')\n    iframe.width = '10'\n    iframe.height = '10'\n    iframe.id = 'cardinal_collection_iframe'\n    iframe.name = 'collectionIframe'\n    iframe.style.display = 'none'\n    document.body.appendChild(iframe)\n    // Crear el formulario para enviar los datos\n    const form = document.createElement('form')\n    form.method = 'POST'\n    form.id = 'cardinal_collection_form'\n    form.target = 'collectionIframe'\n    form.action = data?.result?.deviceDataCollectionUrl\n    // Crear el input con el JWT\n    const input = document.createElement('input')\n    input.id = 'cardinal_collection_form_input'\n    input.type = 'hidden'\n    input.name = 'JWT'\n    input.value = data?.result?.jwt\n    form.appendChild(input)\n    document.body.appendChild(form)\n    // Enviar el formulario para la recolección de datos del navegador\n    const cardinalCollectionForm = document.querySelector('#cardinal_collection_form')\n    if (cardinalCollectionForm) {\n        (cardinalCollectionForm as HTMLFormElement).submit()\n    }\n}\n\n</code></pre>\n<h3 id=\"esperar-la-recolección-de-datos\">Esperar la Recolección de Datos</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">useEffect(() =&gt; {\n    const handleMessage = async (event: MessageEvent) =&gt; {\n        if (event.origin === process.env.NEXT_PUBLIC_CARDINAL_COMMERCE_URL) {\n            console.log('event recollection', event)\n            // Continuar con el proceso después de la recolección exitosa\n            await handleContinueAfterRecollection()\n        }\n    }\n    window.addEventListener('message', handleMessage, { once: true })\n    return () =&gt; {\n        window.removeEventListener('message', handleMessage)\n    }\n}, [setup3dsData, handleContinueAfterRecollection])\n\n</code></pre>\n<h3 id=\"configuración-de-next_public_cardinal_commerce_url\">Configuración de NEXT_PUBLIC_CARDINAL_COMMERCE_URL</h3>\n<p>Para validar correctamente el origen del evento de recolección de datos, debes configurar la variable de entorno NEXT_PUBLIC_CARDINAL_COMMERCE_URL con los siguientes valores:</p>\n<p>Para Pruebas (Staging):</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>NEXT_PUBLIC_CARDINAL_COMMERCE_URL=https://centinelapistag.cardinalcommerce.com\n\n</code></pre><p>Para Producción:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>NEXT_PUBLIC_CARDINAL_COMMERCE_URL=https://centinelapi.cardinalcommerce.com\n\n</code></pre><hr />\n<h3 id=\"pasos-detallados\">Pasos Detallados</h3>\n<ol>\n<li>Setup 3DS exitoso → Se recibe respuesta con deviceDataCollectionUrl y jwt</li>\n<li>Crear iFrame → Se crea el iFrame oculto y el formulario</li>\n<li>Enviar formulario → Se envía automáticamente a Cardinal Commerce</li>\n<li>Esperar evento → Se escucha el evento de recolección exitosa</li>\n<li>Continuar proceso → Una vez recibido el evento, continuar con el enrollment</li>\n</ol>\n<hr />\n<h2 id=\"consideraciones-importantes\">Consideraciones Importantes</h2>\n<h3 id=\"seguridad\">Seguridad</h3>\n<ul>\n<li>La recolección de datos es obligatoria y no se puede omitir</li>\n<li>El iFrame debe permanecer oculto durante todo el proceso</li>\n<li>Solo se puede continuar con el enrollment después de recibir el evento de recolección exitosa</li>\n</ul>\n<h3 id=\"experiencia-de-usuario\">Experiencia de Usuario</h3>\n<ul>\n<li>El proceso de recolección es transparente para el usuario final</li>\n<li>No requiere interacción del usuario</li>\n<li>Se ejecuta automáticamente en segundo plano</li>\n</ul>\n<h3 id=\"implementación\">Implementación</h3>\n<ul>\n<li>Usar el dominio correcto de Cardinal Commerce para validar el origen del evento</li>\n<li>Manejar correctamente la limpieza de event listeners</li>\n<li>Implementar manejo de errores para casos de fallo en la recolección</li>\n</ul>\n<hr />\n<h2 id=\"ejemplo-completo-de-implementación\">Ejemplo Completo de Implementación</h2>\n<p>Para ver un ejemplo completo de implementación del Setup 3DS con NextJS, incluyendo la creación de iFrames, manejo de eventos y flujo completo, puedes consultar el repositorio oficial:</p>\n<p><a href=\"https://bitbucket.org/greeenpay/3ds-tokenization-nextjs/src/main/\">Ejemplo 3DS</a></p>\n<p>Este repositorio contiene:</p>\n<ul>\n<li>Implementación completa del Setup 3DS</li>\n<li>Creación y manejo de iFrames</li>\n<li>Eventos de recolección de datos</li>\n<li>Flujo completo de enrollment y validación</li>\n<li>Ejemplos de código TypeScript/React</li>\n<li>Manejo de errores y validaciones</li>\n</ul>\n","urlObject":{"path":["3ds","setup"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"cb5d81da-fa0d-4647-abcd-613de1869c25","name":"PA Setup exitoso","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/af_pa_setup"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 11 Jun 2024 14:22:16 GMT"},{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"},{"key":"Content-Length","value":"1046"},{"key":"Connection","value":"keep-alive"},{"key":"Apigw-Requestid","value":"ZNOOih6noAMEavg="}],"cookie":[],"responseTime":null,"body":"{\n    \"statusCode\": 200,\n    \"result\": {\n        \"id\": \"7365177584066914304953\",\n        \"code\": \"b7e17514-188b-4174-9a9a-5af9b87532cb\",\n        \"status\": \"PENDING_AUTHENTICATION\",\n        \"authenticationTransactionId\": \"Tuc9dc7m2uxABa1bqG80\",\n        \"jwt\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNjgyZWVmNi0zYTk1LTRhMzItYTE5Ni0xYmIxZWNjYWU0MmYiLCJpYXQiOjE3MzY1MTc3NTgsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTczNjUyMTM1OCwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUGF5bG9hZCI6eyJBQ1NVcmwiOiJodHRwczovLzBtZXJjaGFudGFjc3N0YWcuY2FyZGluYWxjb21tZXJjZS5jb20vTWVyY2hhbnRBQ1NXZWIvY3JlcS5qc3AiLCJQYXlsb2FkIjoiZXlKdFpYTnpZV2RsVkhsd1pTSTZJa05TWlhFaUxDSnRaWE56WVdkbFZtVnljMmx2YmlJNklqSXVNaTR3SWl3aWRHaHlaV1ZFVTFObGNuWmxjbFJ5WVc1elNVUWlPaUk1TWpNeFlqWTBOaTB4TkRNeExUUXhOR1l0WVdVek5DMDNZV05tT1RkaE5tTTBOMlFpTENKaFkzTlVjbUZ1YzBsRUlqb2laREU1T1dRMk5XVXRaR0ZrT0MwMFkySTJMVGsyWkRjdE9USm1PRGMzWTJWak1UaGxJaXdpWTJoaGJHeGxibWRsVjJsdVpHOTNVMmw2WlNJNklqQXlJbjAiLCJUcmFuc2FjdGlvbklkIjoiVHVjOWRjN20ydXhBQmExYnFHODAifSwiT2JqZWN0aWZ5UGF5bG9hZCI6dHJ1ZSwiUmV0dXJuVXJsIjoiaHR0cHM6Ly9jaGVja291dHYyLmdyZWVucGF5c2J4Lm1lLzNkcy9yZWRpcmVjdCJ9.fewHhM-u2kteEHOr_JhrgS_R6-bkCRsEakH2gtjXsro\",\n        \"acsTransactionId\": \"d199d65e-dad8-4cb6-96d7-92f877cec18e\",\n        \"acsUrl\": \"https://0merchantacsstag.cardinalcommerce.com/MerchantACSWeb/creq.jsp\",\n        \"challengeRequired\": \"N\",\n        \"pareq\": \"eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI5MjMxYjY0Ni0xNDMxLTQxNGYtYWUzNC03YWNmOTdhNmM0N2QiLCJhY3NUcmFuc0lEIjoiZDE5OWQ2NWUtZGFkOC00Y2I2LTk2ZDctOTJmODc3Y2VjMThlIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0\",\n        \"stepUpUrl\": \"https://centinelapistag.cardinalcommerce.com/V2/Cruise/StepUp\",\n        \"threeDSServerTransactionId\": \"9231b646-1431-414f-ae34-7acf97a6c47d\",\n        \"veresEnrolled\": \"Y\",\n        \"directoryServerTransactionId\": \"94f17d98-5711-49f4-8b08-bd52315dca94\",\n        \"error\": {\n            \"code\": \"CONSUMER_AUTHENTICATION_REQUIRED\",\n            \"message\": \"The cardholder is enrolled in Payer Authentication. Please authenticate the cardholder before continuing with the transaction.\"\n        },\n        \"consumerAuthenticationInformation\": {\n            \"accessToken\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNjgyZWVmNi0zYTk1LTRhMzItYTE5Ni0xYmIxZWNjYWU0MmYiLCJpYXQiOjE3MzY1MTc3NTgsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTczNjUyMTM1OCwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUGF5bG9hZCI6eyJBQ1NVcmwiOiJodHRwczovLzBtZXJjaGFudGFjc3N0YWcuY2FyZGluYWxjb21tZXJjZS5jb20vTWVyY2hhbnRBQ1NXZWIvY3JlcS5qc3AiLCJQYXlsb2FkIjoiZXlKdFpYTnpZV2RsVkhsd1pTSTZJa05TWlhFaUxDSnRaWE56WVdkbFZtVnljMmx2YmlJNklqSXVNaTR3SWl3aWRHaHlaV1ZFVTFObGNuWmxjbFJ5WVc1elNVUWlPaUk1TWpNeFlqWTBOaTB4TkRNeExUUXhOR1l0WVdVek5DMDNZV05tT1RkaE5tTTBOMlFpTENKaFkzTlVjbUZ1YzBsRUlqb2laREU1T1dRMk5XVXRaR0ZrT0MwMFkySTJMVGsyWkRjdE9USm1PRGMzWTJWak1UaGxJaXdpWTJoaGJHeGxibWRsVjJsdVpHOTNVMmw2WlNJNklqQXlJbjAiLCJUcmFuc2FjdGlvbklkIjoiVHVjOWRjN20ydXhBQmExYnFHODAifSwiT2JqZWN0aWZ5UGF5bG9hZCI6dHJ1ZSwiUmV0dXJuVXJsIjoiaHR0cHM6Ly9jaGVja291dHYyLmdyZWVucGF5c2J4Lm1lLzNkcy9yZWRpcmVjdCJ9.fewHhM-u2kteEHOr_JhrgS_R6-bkCRsEakH2gtjXsro\",\n            \"acsTransactionId\": \"d199d65e-dad8-4cb6-96d7-92f877cec18e\",\n            \"acsUrl\": \"https://0merchantacsstag.cardinalcommerce.com/MerchantACSWeb/creq.jsp\",\n            \"authenticationTransactionId\": \"Tuc9dc7m2uxABa1bqG80\",\n            \"challengeRequired\": \"N\",\n            \"pareq\": \"eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI5MjMxYjY0Ni0xNDMxLTQxNGYtYWUzNC03YWNmOTdhNmM0N2QiLCJhY3NUcmFuc0lEIjoiZDE5OWQ2NWUtZGFkOC00Y2I2LTk2ZDctOTJmODc3Y2VjMThlIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0\",\n            \"specificationVersion\": \"2.2.0\",\n            \"stepUpUrl\": \"https://centinelapistag.cardinalcommerce.com/V2/Cruise/StepUp\",\n            \"threeDSServerTransactionId\": \"9231b646-1431-414f-ae34-7acf97a6c47d\",\n            \"veresEnrolled\": \"Y\",\n            \"directoryServerTransactionId\": \"94f17d98-5711-49f4-8b08-bd52315dca94\",\n            \"acsOperatorID\": \"MerchantACS\",\n            \"acsReferenceNumber\": \"Cardinal ACS\"\n        },\n        \"transaction\": {\n            \"id\": \"b7e17514-188b-4174-9a9a-5af9b87532cb\",\n            \"status\": \"CYBS_PA_ENROLLMENT\",\n            \"description\": \"API-V2-USD\",\n            \"authorization\": \"\",\n            \"webhook_url\": \"https://webhook.site/c30917eb-812e-4305-bc5c-085b998f57aa\",\n            \"customer\": {\n                \"name\": \"Angel Gonzalez\",\n                \"email\": \"agonzalez@greenpay.me\",\n                \"identification\": \"124444\",\n                \"billingAddress\": {\n                    \"country\": \"CR\",\n                    \"province\": \"Nombre de la provincia\",\n                    \"city\": \"Ciudad\",\n                    \"street1\": \"Dirección Calle 1\",\n                    \"street2\": \"Dirección Calle 2\",\n                    \"zip\": \"10801\"\n                },\n                \"shippingAddress\": {\n                    \"country\": \"CR\",\n                    \"province\": \"Nombre de la provincia\",\n                    \"city\": \"Ciudad\",\n                    \"street1\": \"Dirección Calle 1\",\n                    \"street2\": \"Dirección Calle 2\",\n                    \"zip\": \"10801\"\n                }\n            },\n            \"entity_response\": \"\",\n            \"orderReference\": \"API-V2-CRC-4791\"\n        }\n    }\n}"},{"id":"ff0a4d20-1de6-40bf-9f29-78935aa2ae34","name":"PA SETUP fallido","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/af_pa_setup"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 11 Jun 2024 14:31:07 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"57"},{"key":"Connection","value":"keep-alive"},{"key":"Apigw-Requestid","value":"ZNPiii2zoAMEY2w="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"\\\"callback\\\" is not allowed\",\n    \"status\": \"fail\"\n}"},{"id":"6d07e593-5a65-4271-8b53-b5643fd6e61a","name":"PA SETUP Sesión Expirada","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/af_pa_setup"},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 11 Jun 2024 15:33:22 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"51"},{"key":"Connection","value":"keep-alive"},{"key":"Apigw-Requestid","value":"ZNYqEhwPoAMEaDQ="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Sesion no encontrada!\",\n    \"status\": \"fail\"\n}"}],"_postman_id":"22830e44-251b-422d-ba36-cd9ab44a5848"},{"name":"PA ENROLLMENT","event":[{"listen":"test","script":{"id":"1b215bed-b64f-4ed4-9fae-4f6162db6d6d","exec":["var jsonData = JSON.parse(responseBody);","postman.setEnvironmentVariable(\"authenticationTransactionId\", jsonData.result.authenticationTransactionId);"],"type":"text/javascript","packages":{}}}],"id":"ce98c96a-1f0f-4f84-b975-d307c9482f6a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    },\n    \"referenceId\": \"{{ID de referencia obtenido al momento de ejecutar el proceso PA SETUP}}\",\n    \"transactionId\": \"{{ID de transacción obtenido al momento de ejecutar el proceso PA SETUP}}\",\n    \"redirectURL\": \"{{redirectURL}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/3ds/enrollment","description":"<h1 id=\"enrollment-3ds--api-v2\">Enrollment 3DS – API V2</h1>\n<p>&gt; Descripción:</p>\n<p>Este endpoint permite realizar el procesamiento de verificación de la información del tarjeta habiente y su dispositivo, para autenticar dicha información o en su debido caso, solicitar un código de autorización enviado por el emisor de la tarjeta.</p>\n<h2 id=\"resumen\">Resumen</h2>\n<p>El Enrollment 3DS retorna un objeto JSON que permite mostrar un cuadro de diálogo para ingresar el código de autorización enviado por el emisor de la tarjeta o la información de la autenticidad de la transacción.</p>\n<h3 id=\"requisitos-obligatorios\">Requisitos Obligatorios</h3>\n<ul>\n<li><p>Ejecutar correctamente el PA SETUP</p>\n</li>\n<li><p>Ejecutar correctamente el script de recolección de información recibido en la respuesta del PA SETUP</p>\n</li>\n<li><p>Codificar datos en formato base64</p>\n</li>\n</ul>\n<hr />\n<h2 id=\"pasos-previos-setup-3ds\">Pasos Previos: Setup 3DS</h2>\n<h3 id=\"1-setup-3ds\">1. Setup 3DS</h3>\n<p>Realiza una solicitud al endpoint de Setup 3DS para obtener la configuración inicial.Valores que obtendrás:</p>\n<ul>\n<li><p><code>referenceId</code>: Identificador de referencia del setup</p>\n</li>\n<li><p><code>code</code>: Código de transacción del setup</p>\n</li>\n<li><p><code>deviceDataCollectionUrl</code>: URL para recolección de datos del navegador</p>\n</li>\n</ul>\n<hr />\n<h2 id=\"endpoint-de-enrollment-3ds\">Endpoint de Enrollment 3DS</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Propiedad</th>\n<th>Valor</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Método</td>\n<td>POST</td>\n</tr>\n<tr>\n<td>Descripción</td>\n<td>Procesamiento de verificación 3DS</td>\n</tr>\n<tr>\n<td>Conexión Segura</td>\n<td>Sí, bajo TLS 1.2</td>\n</tr>\n<tr>\n<td>Cifrado de Datos</td>\n<td>JSON codificado en base64</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"headers\">Headers</h2>\n<h3 id=\"header-obligatorio\">Header Obligatorio</h3>\n<p>El header session-token es obligatorio y debe ser enviado en cada solicitud a este endpoint.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>session-token</td>\n<td>String</td>\n<td>Token obtenido en la creación de la orden de pago</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><p>Ejemplo de session-token (UUID):</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>ad79b9b0-917d-11ef-8a48-19ee98944b83\n\n</code></pre><hr />\n<h2 id=\"body-json\">Body (JSON)</h2>\n<h3 id=\"estructura-del-request\">Estructura del Request</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"cardData\": {\n        \"session\": \"\",\n        \"ed\": \"\"\n    },\n    \"referenceId\": \"\",\n    \"transactionId\": \"\",\n    \"redirectURL\": \"\"\n}\n\n</code></pre>\n<h3 id=\"campos-obligatorios\">Campos Obligatorios</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>cardData.session</td>\n<td>String</td>\n<td>Sesión generada al crear la orden de pago</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>cardData.ed</td>\n<td>String</td>\n<td>Datos de la tarjeta en formato base64</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>referenceId</td>\n<td>String</td>\n<td>Campo obtenido de la respuesta del setup result.referenceId</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>transactionId</td>\n<td>String</td>\n<td>Campo obtenido de la respuesta del setup result.transaction.id</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>redirectURL</td>\n<td>String</td>\n<td>URL donde está alojada su página de pagos</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"estructura-del-objeto-ed-antes-de-base64\">Estructura del Objeto ed (antes de base64)</h2>\n<h3 id=\"formato-json\">Formato JSON</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n   \"card\": {\n    \"cardHolder\": \"John Doe\",\n    \"expirationDate\": {\n      \"month\": \"12\",\n      \"year\": \"31\"\n    },\n    \"cardNumber\": \"4456530000001096\",\n    \"cvc\": \"196\"\n  },\n   \"additional\": { \n     \"channelData\": { \n       \"channel\": \"01\", \n       \"source\": \"API_CARD\" \n     } \n   },\n   // solo aplica para planes \n   // campos requeridos para pagos con planes\n  \"plan\": \"06ae4d6a-a55d-41b8-894e-be9b75c4f063\",\n  \"quota\": 6, // DEBE ser número entero, NO string\n}\n\n</code></pre>\n<h3 id=\"campos-detallados\">Campos Detallados</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Restricciones</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>card.cardHolder</td>\n<td>String</td>\n<td>Nombre del dueño de la tarjeta</td>\n<td>5-50 caracteres</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.month</td>\n<td>String</td>\n<td>Mes de vencimiento</td>\n<td>2 caracteres, \"01\" a \"12\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.year</td>\n<td>String</td>\n<td>Año de vencimiento (últimos 2 dígitos)</td>\n<td>2 caracteres, Ej: \"31\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cardNumber</td>\n<td>String</td>\n<td>Número de la tarjeta</td>\n<td>-</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cvc</td>\n<td>String</td>\n<td>Código de seguridad de la tarjeta</td>\n<td>-</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.channel</td>\n<td>String</td>\n<td>Canal</td>\n<td>Debe ser \"01\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.source</td>\n<td>String</td>\n<td>Fuente</td>\n<td>Debe ser \"API_CARD\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>plan</td>\n<td>String</td>\n<td>Identificador del plan</td>\n<td>Eje. 06ae4d6a-a55d-41b8-894e-be9b75c4f063</td>\n<td>Solo para pagos con planes</td>\n</tr>\n<tr>\n<td>quota</td>\n<td>Number</td>\n<td>Número de cuotas</td>\n<td>Eje. 6</td>\n<td>Solo para pagos con planes</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<p>ℹ️ Nota sobre <code>plan</code> y <code>quota</code>:</p>\n<p>Para realizar pagos con planes se deben enviar estos dos valores, estos valores los debe obtener mediante un endpoint que GreenPay Facilita, la documentacion del endpoint la puede encontrar en la Merchant/Plans en la documentacion de postman</p>\n<p>Estos datos los tiene que solicitar mediante interfaz gráfica en su frontend, para revisar una integración por código puede revisar el siguiente ejemplo en NextJS<br /><a href=\"https://bitbucket.org/greeenpay/3ds-tokenization-nextjs/src/main/\">3DS</a></p>\n<p>Sino utiliza pagos con Cuota y plan porfavor omitir estos campos.</p>\n<p>Su terminal debe estar configurada para aceptar pagos con planes</p>\n<h2 id=\"respuestas-del-enrollment-3ds\">Respuestas del Enrollment 3DS</h2>\n<h3 id=\"¿qué-es-el-http-code\">¿Qué es el HTTP Code?</h3>\n<p>El HTTP code (código de estado HTTP) es un número que indica el resultado de una solicitud HTTP:</p>\n<ul>\n<li><p>200 = Solicitud exitosa</p>\n</li>\n<li><p>400, 401, 404, 500, etc. = Solicitud fallida</p>\n</li>\n</ul>\n<hr />\n<h2 id=\"respuesta-exitosa-sin-fricción-http-code-200\">Respuesta Exitosa sin Fricción (HTTP Code 200)</h2>\n<h3 id=\"ejemplo-de-respuesta\">Ejemplo de Respuesta</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"statusCode\": 200,\n    \"result\": {\n        \"id\": \"7497628457976252404806\",\n        \"code\": \"90ee7b41-150e-44d8-83a2-bd19f2b67e77\",\n        \"status\": \"AUTHENTICATION_SUCCESSFUL\",\n        \"authenticationTransactionId\": \"qXw5s4DPNHxCUBSVmNY0\",\n        \"acsTransactionId\": \"4447c975-d203-433f-89b2-70efba2334ef\",\n        \"paresStatus\": \"Y\",\n        \"threeDSServerTransactionId\": \"b5df9086-ebb1-4ceb-b87a-1f755fd5e1be\",\n        \"veresEnrolled\": \"Y\",\n        \"directoryServerTransactionId\": \"45e5737f-5d79-4cc4-ba31-11af6fb5735f\",\n        \"error\": {},\n        \"consumerAuthenticationInformation\": {\n            \"acsTransactionId\": \"4447c975-d203-433f-89b2-70efba2334ef\",\n            \"authenticationTransactionId\": \"qXw5s4DPNHxCUBSVmNY0\",\n            \"cavv\": \"AJkBBkhgQQAAAE4gSEJydQAAAAA=\",\n            \"ecommerceIndicator\": \"vbv\",\n            \"eci\": \"05\",\n            \"eciRaw\": \"05\",\n            \"paresStatus\": \"Y\",\n            \"specificationVersion\": \"2.2.0\",\n            \"threeDSServerTransactionId\": \"b5df9086-ebb1-4ceb-b87a-1f755fd5e1be\",\n            \"veresEnrolled\": \"Y\",\n            \"xid\": \"AJkBBkhgQQAAAE4gSEJydQAAAAA=\",\n            \"directoryServerTransactionId\": \"45e5737f-5d79-4cc4-ba31-11af6fb5735f\",\n            \"acsOperatorID\": \"MerchantACS\",\n            \"acsReferenceNumber\": \"CardinalACS\"\n        },\n        \"transaction\": {\n            \"id\": \"90ee7b41-150e-44d8-83a2-bd19f2b67e77\",\n            \"status\": \"SUCCESSFUL\",\n            \"description\": \"Demo Payment 25447\",\n            \"authorization\": \"831000\",\n            \"webhook_url\": \"https://webhook.site/940cf625-447e-4da3-8eac-be7c2470ee0f\",\n            \"customer\": {\n                \"name\": \"John Doe\",\n                \"email\": \"john.doe@example.com\",\n                \"identification\": \"123456789\",\n                \"billingAddress\": {\n                    \"country\": \"US\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"zip\": \"90001\"\n                },\n                \"shippingAddress\": {\n                    \"country\": \"US\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"zip\": \"90001\"\n                }\n            },\n            \"entity_response\": {\n                \"_links\": {\n                    \"self\": {\n                        \"href\": \"/pts/v2/payments/7497628463896304604805\",\n                        \"method\": \"GET\"\n                    }\n                },\n                \"id\": \"7497628463896304604805\",\n                \"submitTimeUtc\": \"2025-06-12T21:14:06Z\",\n                \"status\": \"AUTHORIZED\",\n                \"reconciliationId\": \"7497628463896304604805\",\n                \"clientReferenceInformation\": {\n                    \"code\": \"90ee7b41-150e-44d8-83a2-bd19f2b67e77\"\n                },\n                \"processorInformation\": {\n                    \"approvalCode\": \"831000\",\n                    \"transactionId\": \"016153570198200\",\n                    \"networkTransactionId\": \"016153570198200\",\n                    \"responseCode\": \"00\",\n                    \"responseDetails\": \"ABC\",\n                    \"avs\": {\n                        \"code\": \"Y\",\n                        \"codeRaw\": \"Y\"\n                    },\n                    \"cardVerification\": {\n                        \"resultCode\": \"M\",\n                        \"resultCodeRaw\": \"M\"\n                    },\n                    \"merchantAdvice\": {\n                        \"code\": \"01\",\n                        \"codeRaw\": \"M001\"\n                    },\n                    \"consumerAuthenticationResponse\": {\n                        \"code\": \"2\",\n                        \"codeRaw\": \"2\"\n                    },\n                    \"systemTraceAuditNumber\": \"583908\",\n                    \"retrievalReferenceNumber\": \"516321583908\"\n                },\n                \"paymentAccountInformation\": {\n                    \"card\": {\n                        \"type\": \"001\"\n                    }\n                },\n                \"paymentInformation\": {\n                    \"card\": {\n                        \"type\": \"001\"\n                    },\n                    \"tokenizedCard\": {\n                        \"type\": \"001\"\n                    }\n                },\n                \"orderInformation\": {\n                    \"amountDetails\": {\n                        \"totalAmount\": \"212.00\",\n                        \"authorizedAmount\": \"212.00\",\n                        \"currency\": \"USD\"\n                    }\n                }\n            },\n            \"orderReference\": \"compra-demo-payment-1-20250612-8825\",\n            \"card\": {\n                \"bin\": \"445653\",\n                \"brand\": \"Visa\",\n                \"last4\": \"1005\"\n            },\n            \"quota\": 0\n        }\n    }\n}\n\n</code></pre>\n<h3 id=\"campos-importantes\">Campos Importantes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Descripción</th>\n<th>Validación</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>result.transaction.status</td>\n<td>Estado de la transacción</td>\n<td>Debe ser 'SUCCESSFUL'</td>\n</tr>\n<tr>\n<td>result.paresStatus</td>\n<td>Estado de autenticación</td>\n<td>Debe ser 'Y'</td>\n</tr>\n<tr>\n<td>result.veresEnrolled</td>\n<td>Estado de inscripción</td>\n<td>Debe ser 'Y'</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"⚠️-consideraciones-importantes\">⚠️ Consideraciones Importantes</h3>\n<p>&gt; IMPORTANTE: Siempre <code>validar result.transaction.status === 'SUCCESSFUL'</code></p>\n<p>&gt; Si el enrollment es exitoso sin fricción, el estado a validar es <code>result.transaction.status === 'SUCCESSFUL'</code></p>\n<p>&gt; En este caso, la transacción está completa y no requiere validación adicional</p>\n<hr />\n<h2 id=\"respuesta-exitosa-con-fricción-http-code-200\">Respuesta Exitosa con Fricción (HTTP Code 200)</h2>\n<h3 id=\"ejemplo-de-respuesta-1\">Ejemplo de Respuesta</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"statusCode\": 200,\n    \"result\": {\n        \"id\": \"7497614952716702204807\",\n        \"code\": \"aa6b2d21-3775-4d40-a59b-714873b3afe1\",\n        \"status\": \"PENDING_AUTHENTICATION\",\n        \"authenticationTransactionId\": \"36qIQUyJWCTEYnrVCvl0\",\n        \"jwt\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0OGE5MTMxYy1iN2M3LTQwMGEtYmIyYS1jN2U2ZTkzYmRlMzAiLCJpYXQiOjE3NDk3NjE0OTUsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTc0OTc2NTA5NSwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUGF5bG9hZCI6eyJBQ1NVcmwiOiJodHRwczovLzBtZXJjaGFudGFjc3N0YWcuY2FyZGluYWxjb21tZXJjZS5jb20vTWVyY2hhbnRBQ1NXZWIvY3JlcS5qc3AiLCJQYXlsb2FkIjoiZXlKdFpYTnpZV2RsVkhsd1pTSTZJa05TWlhFaUxDSnRaWE56WVdkbFZtVnljMmx2YmlJNklqSXVNaTR3SWl3aWRHaHlaV1ZFVTFObGNuWmxjbFJ5WVc1elNVUWlPaUkwWkRSa01UVTNPQzFtT1RneUxUUmtaVEF0WWpsaU9DMHpPVE5oTUdVNFpETTJaR01pTENKaFkzTlVjbUZ1YzBsRUlqb2lORFptWWpRMVlqa3ROR1l6TkMwMFpXUmhMV0ZtTURNdE1UZGhNamhtWlRVeE5XUTBJaXdpWTJoaGJHeGxibWRsVjJsdVpHOTNVMmw2WlNJNklqQXlJbjAiLCJUcmFuc2FjdGlvbklkIjoiMzZxSVFVeUpXQ1RFWW5yVkN2bDAifSwiT2JqZWN0aWZ5UGF5bG9hZCI6dHJ1ZSwiUmV0dXJuVXJsIjoiaHR0cHM6Ly9jaGVja291dHYyLmdyZWVucGF5c2J4Lm1lLzNkcy9yZWRpcmVjdCJ9.ugtYZ83sb4huZ9zo7HrSL3xVrj802aZ6iIOKWDPxtGs\",\n        \"acsTransactionId\": \"46fb45b9-4f34-4eda-af03-17a28fe515d4\",\n        \"acsUrl\": \"https://0merchantacsstag.cardinalcommerce.com/MerchantACSWeb/creq.jsp\",\n        \"challengeRequired\": \"N\",\n        \"pareq\": \"eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI0ZDRkMTU3OC1mOTgyLTRkZTAtYjliOC0zOTNhMGU4ZDM2ZGMiLCJhY3NUcmFuc0lEIjoiNDZmYjQ1YjktNGYzNC00ZWRhLWFmMDMtMTdhMjhmZTUxNWQ0IiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0\",\n        \"paresStatus\": \"C\",\n        \"stepUpUrl\": \"https://centinelapistag.cardinalcommerce.com/V2/Cruise/StepUp\",\n        \"threeDSServerTransactionId\": \"4d4d1578-f982-4de0-b9b8-393a0e8d36dc\",\n        \"veresEnrolled\": \"Y\",\n        \"directoryServerTransactionId\": \"9b4c63ac-59ba-4b29-b13c-0b0fd3149c59\",\n        \"error\": {\n            \"code\": \"CONSUMER_AUTHENTICATION_REQUIRED\",\n            \"message\": \"The cardholder is enrolled in Payer Authentication. Please authenticate the cardholder before continuing with the transaction.\"\n        },\n        \"consumerAuthenticationInformation\": {\n            \"accessToken\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0OGE5MTMxYy1iN2M3LTQwMGEtYmIyYS1jN2U2ZTkzYmRlMzAiLCJpYXQiOjE3NDk3NjE0OTUsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTc0OTc2NTA5NSwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUGF5bG9hZCI6eyJBQ1NVcmwiOiJodHRwczovLzBtZXJjaGFudGFjc3N0YWcuY2FyZGluYWxjb21tZXJjZS5jb20vTWVyY2hhbnRBQ1NXZWIvY3JlcS5qc3AiLCJQYXlsb2FkIjoiZXlKdFpYTnpZV2RsVkhsd1pTSTZJa05TWlhFaUxDSnRaWE56WVdkbFZtVnljMmx2YmlJNklqSXVNaTR3SWl3aWRHaHlaV1ZFVTFObGNuWmxjbFJ5WVc1elNVUWlPaUkwWkRSa01UVTNPQzFtT1RneUxUUmtaVEF0WWpsaU9DMHpPVE5oTUdVNFpETTJaR01pTENKaFkzTlVjbUZ1YzBsRUlqb2lORFptWWpRMVlqa3ROR1l6TkMwMFpXUmhMV0ZtTURNdE1UZGhNamhtWlRVeE5XUTBJaXdpWTJoaGJHeGxibWRsVjJsdVpHOTNVMmw2WlNJNklqQXlJbjAiLCJUcmFuc2FjdGlvbklkIjoiMzZxSVFVeUpXQ1RFWW5yVkN2bDAifSwiT2JqZWN0aWZ5UGF5bG9hZCI6dHJ1ZSwiUmV0dXJuVXJsIjoiaHR0cHM6Ly9jaGVja291dHYyLmdyZWVucGF5c2J4Lm1lLzNkcy9yZWRpcmVjdCJ9.ugtYZ83sb4huZ9zo7HrSL3xVrj802aZ6iIOKWDPxtGs\",\n            \"acsTransactionId\": \"46fb45b9-4f34-4eda-af03-17a28fe515d4\",\n            \"acsUrl\": \"https://0merchantacsstag.cardinalcommerce.com/MerchantACSWeb/creq.jsp\",\n            \"authenticationTransactionId\": \"36qIQUyJWCTEYnrVCvl0\",\n            \"challengeRequired\": \"N\",\n            \"pareq\": \"eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI0ZDRkMTU3OC1mOTgyLTRkZTAtYjliOC0zOTNhMGU4ZDM2ZGMiLCJhY3NUcmFuc0lEIjoiNDZmYjQ1YjktNGYzNC00ZWRhLWFmMDMtMTdhMjhmZTUxNWQ0IiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0\",\n            \"paresStatus\": \"C\",\n            \"specificationVersion\": \"2.2.0\",\n            \"stepUpUrl\": \"https://centinelapistag.cardinalcommerce.com/V2/Cruise/StepUp\",\n            \"threeDSServerTransactionId\": \"4d4d1578-f982-4de0-b9b8-393a0e8d36dc\",\n            \"veresEnrolled\": \"Y\",\n            \"directoryServerTransactionId\": \"9b4c63ac-59ba-4b29-b13c-0b0fd3149c59\",\n            \"acsOperatorID\": \"MerchantACS\",\n            \"acsReferenceNumber\": \"CardinalACS\"\n        },\n        \"transaction\": {\n            \"id\": \"aa6b2d21-3775-4d40-a59b-714873b3afe1\",\n            \"status\": \"CYBS_PA_ENROLLMENT\",\n            \"description\": \"Demo Payment 97592\",\n            \"authorization\": \"\",\n            \"webhook_url\": \"https://webhook.site/940cf625-447e-4da3-8eac-be7c2470ee0f\",\n            \"customer\": {\n                \"name\": \"John Doe\",\n                \"email\": \"john.doe@example.com\",\n                \"identification\": \"123456789\",\n                \"billingAddress\": {\n                    \"country\": \"US\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"zip\": \"90001\"\n                },\n                \"shippingAddress\": {\n                    \"country\": \"US\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"zip\": \"90001\"\n                }\n            },\n            \"entity_response\": \"\",\n            \"orderReference\": \"compra-demo-payment-1-20250612-4738\",\n            \"card\": {\n                \"bin\": \"445653\",\n                \"brand\": \"Visa\",\n                \"last4\": \"1096\"\n            },\n            \"quota\": 0\n        }\n    }\n}\n\n</code></pre>\n<h3 id=\"campos-importantes-1\">Campos Importantes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Descripción</th>\n<th>Validación</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>result.transaction.status</td>\n<td>Estado de la transacción</td>\n<td>Debe ser 'CYBS_PA_ENROLLMENT'</td>\n</tr>\n<tr>\n<td>result.stepUpUrl</td>\n<td>URL para el challenge 3DS</td>\n<td>Requerida para crear el iframe</td>\n</tr>\n<tr>\n<td>result.jwt</td>\n<td>Token JWT para el challenge</td>\n<td>Incluir en el formulario del iframe</td>\n</tr>\n<tr>\n<td>result.pareq</td>\n<td>Datos del challenge en base64</td>\n<td>Contiene información del tamaño de ventana</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"⚠️-consideraciones-importantes-1\">⚠️ Consideraciones Importantes</h3>\n<p>&gt; IMPORTANTE:</p>\n<p>Siempre validar <code>result.transaction.status === 'CYBS_PA_ENROLLMENT'</code></p>\n<p>&gt; Si el enrollment requiere fricción, el estado a validar es <code>result.transaction.status === 'CYBS_PA_ENROLLMENT'</code></p>\n<p>&gt; En este caso, se debe crear un iframe con los datos de la respuesta para que el usuario complete el challenge</p>\n<p>&gt; Se debe esperar la respuesta del orquestador de GreenPay en un evento específico para poder realizar el validate</p>\n<hr />\n<h2 id=\"respuesta-de-error-http-code-200-con-status-failed\">Respuesta de Error (HTTP Code 200 con status FAILED)</h2>\n<h3 id=\"ejemplo-de-respuesta-2\">Ejemplo de Respuesta</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"result\": {\n        \"error\": {\n            \"status\": 400,\n            \"reason\": \"AFPAENROLLMENT3DS\",\n            \"message\": \"Error to authorize Transaction veresEnrolled or paresStatus, please try again later.\"\n        },\n        \"statusCode\": 400,\n        \"status\": \"fail\",\n        \"orderId\": \"compra-demo-payment-1-20250612-7040\",\n        \"token\": \"872d2033-ec0e-4c38-a119-a2920e55e8ca\",\n        \"transactionId\": \"ffd8076a-6863-42aa-85eb-74a4b7e5b4c0\",\n        \"amount\": 590,\n        \"currency\": \"USD\",\n        \"transaction\": {\n            \"terminal\": \"e044afee-8861-4b9d-946b-1643656c82a5\",\n            \"currency\": \"USD\",\n            \"entity_response\": {},\n            \"created_at\": \"2025-06-12T21:21:58.405Z\",\n            \"reference_number\": \"compra-demo-payment-1-20250612-7040\",\n            \"status\": \"FAILED\",\n            \"merchant_name\": \"Comercio Pruebas 3DS\",\n            \"source\": \"API_CARD\",\n            \"cybersource_threeds_pa_setup\": {\n                \"id\": \"7497633213356406204805\",\n                \"code\": \"ffd8076a-6863-42aa-85eb-74a4b7e5b4c0\",\n                \"deviceDataCollectionUrl\": \"https://centinelapistag.cardinalcommerce.com/V1/Cruise/Collect\",\n                \"jwt\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0MzE5ZjVlZS02ZTA3LTQwZGEtYjc0My02ODBhMmViZmE3NmQiLCJpYXQiOjE3NDk3NjMzMjEsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTc0OTc2NjkyMSwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUmVmZXJlbmNlSWQiOiI3MTAyYjgyNS00OGUwLTRjMjItYTExNS0wYzZlOWViOTIwYTMifQ.5q0S90C8bUKmPheGQoj6H23Q4lusaFooq6CZCNvT3CI\",\n                \"referenceId\": \"7102b825-48e0-4c22-a115-0c6e9eb920a3\",\n                \"status\": \"COMPLETED\"\n            },\n            \"updated_at\": \"2025-06-12T21:22:03.776Z\",\n            \"redirectURL\": \"\",\n            \"quota\": 0,\n            \"webhook_url\": \"https://webhook.site/940cf625-447e-4da3-8eac-be7c2470ee0f\",\n            \"internal_ref\": 16504873736157,\n            \"amount\": 590,\n            \"merchant_id\": \"004a16ef-1be2-4ada-91ef-6222a7c1930e\",\n            \"customer\": {\n                \"name\": \"John Doe\",\n                \"shippingAddress\": {\n                    \"zip\": \"90001\",\n                    \"country\": \"US\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\"\n                },\n                \"identification\": \"123456789\",\n                \"billingAddress\": {\n                    \"zip\": \"90001\",\n                    \"country\": \"US\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\"\n                },\n                \"email\": \"john.doe@example.com\"\n            },\n            \"authorizer\": \"cybersource\",\n            \"id\": \"ffd8076a-6863-42aa-85eb-74a4b7e5b4c0\",\n            \"description\": \"Demo Payment 12432\",\n            \"authorization\": \"\",\n            \"card\": {\n                \"last4\": \"1815\",\n                \"cardnumber\": \"559727******1815\",\n                \"brand\": \"Mastercard\",\n                \"khash\": \"559727ZKF70RXEIDPU2B\",\n                \"bin\": \"559727\"\n            },\n            \"orderReference\": \"compra-demo-payment-1-20250612-7040\"\n        },\n        \"quota\": 0,\n        \"last4\": \"1815\",\n        \"brand\": \"Mastercard\",\n        \"bin\": \"559727\",\n        \"cause\": {\n            \"origin\": \"AFPAENROLLMENT3DS\"\n        }\n    }\n}\n\n</code></pre>\n<h3 id=\"⚠️-consideraciones-importantes-2\">⚠️ Consideraciones Importantes</h3>\n<p>&gt; IMPORTANTE:</p>\n<p>Siempre validar <code>result.transaction.status === 'FAILED'</code></p>\n<p>&gt; Para obtener el mensaje de error: <code>errorMessage = result?.error?.message ?? result.error</code></p>\n<p>&gt; Tener en consideración que el HTTP status puede ser 200 pero siempre validar el <code>result.transaction.status</code></p>\n<hr />\n<h2 id=\"respuesta-de-error-de-validación-http-code-400\">Respuesta de Error de Validación (HTTP Code 400)</h2>\n<h3 id=\"ejemplo-de-respuesta-3\">Ejemplo de Respuesta</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"message\": \"Event object failed validation\",\n    \"status\": 400\n}\n\n</code></pre>\n<h3 id=\"⚠️-consideraciones-importantes-3\">⚠️ Consideraciones Importantes</h3>\n<p>&gt; IMPORTANTE: Cuando es este caso, tener en cuenta que la estructura de error cambia</p>\n<p>&gt; El mensaje de error viene en message</p>\n<p>&gt; En este caso el HTTP code es 400 y es el único caso</p>\n<hr />\n<h2 id=\"flujo-con-fricción-creación-del-iframe\">Flujo con Fricción: Creación del iFrame</h2>\n<p>Cuando el enrollment requiere fricción <code>(result.transaction.status === 'CYBS_PA_ENROLLMENT'</code>), se debe crear un iframe para que el usuario complete el challenge de autenticación.</p>\n<h3 id=\"1-determinar-el-tamaño-de-la-ventana\">1. Determinar el Tamaño de la Ventana</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">const getWindowSize3DSChallenge = async (data: string | '') =&gt; {\n    const decodedData = atob(data)\n    const parsedData = JSON.parse(decodedData) as {\n        challengeWindowSize: string\n    }\n    return parsedData?.challengeWindowSize\n}\n\n</code></pre>\n<h3 id=\"2-tamaños-de-ventana-disponibles\">2. Tamaños de Ventana Disponibles</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">const windowsSize = {\n    '01': { width: '250px', height: '400px' },\n    '02': { width: '390px', height: '400px' },\n    '03': { width: '500px', height: '600px' },\n    '04': { width: '600px', height: '400px' },\n    '05': { width: '100%', height: '100%' }\n}\n\n</code></pre>\n<h3 id=\"3-crear-el-iframe-y-formulario\">3. Crear el iFrame y Formulario</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">const createiFrame3DSEnrollment = async (data: Enrollment3DsResponseInterface) =&gt; {\n    console.log('createiFrame3DSEnrollment', data)\n    // Obtener el tamaño de la ventana del challenge\n    const challengeWindowSize = await getWindowSize3DSChallenge(data?.result?.pareq)\n    const ws = windowsSize[challengeWindowSize as keyof typeof windowsSize]\n    // Crear el contenedor del iframe\n    const div = document.createElement('div')\n    div.className = 'div-iframe'\n    // Crear el iframe\n    const iframe = document.createElement('iframe')\n    iframe.width = ws.width\n    iframe.height = ws.height\n    iframe.id = 'step_up_iframe'\n    iframe.name = 'stepUpIframe'\n    div.appendChild(iframe)\n    document.body.appendChild(div)\n    // Crear el formulario\n    const form = document.createElement('form')\n    form.method = 'POST'\n    form.id = 'step_up_form'\n    form.target = 'stepUpIframe'\n    form.action = data?.result?.stepUpUrl || ''\n    // Crear el input JWT\n    const input = document.createElement('input')\n    input.id = 'JWT'\n    input.type = 'hidden'\n    input.name = 'JWT'\n    input.value = data?.result?.jwt || ''\n    // Crear el input MD\n    const input2 = document.createElement('input')\n    input2.id = 'MD'\n    input2.type = 'hidden'\n    input2.name = 'MD'\n    input2.value = data?.result?.code || ''\n    form.appendChild(input)\n    form.appendChild(input2)\n    document.body.appendChild(form)\n}\n\n</code></pre>\n<h3 id=\"4-enviar-el-formulario\">4. Enviar el Formulario</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">// Enviar el formulario para iniciar el challenge\nconst script = document.createElement('script')\nscript.type = 'text/javascript'\ndocument.head.appendChild(script)\nconst stepUpForm = document.getElementById('step_up_form') as HTMLFormElement\nif (stepUpForm) {\n    stepUpForm.submit()\n}\n\n</code></pre>\n<hr />\n<h2 id=\"manejo-de-eventos-del-iframe\">Manejo de Eventos del iFrame</h2>\n<h3 id=\"1-escuchar-el-evento-de-cierre\">1. Escuchar el Evento de Cierre</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">useEffect(() =&gt; {\n    const handleMessage = async (event: MessageEvent) =&gt; {\n        // Verificar que el mensaje proviene del dominio de GP\n        if (event.origin !== process.env.NEXT_PUBLIC_ORCHESTRATOR_URL) {\n            return\n        }\n        console.log('handleMessage', event)\n        // Comprobar el contenido del mensaje para cerrar el iframe\n        if (event.data === 'closeIframe') {\n            const iframe = document.getElementById('step_up_iframe')\n            const divIframe = document.querySelector('.div-iframe') as HTMLDivElement\n            if (iframe) {\n                iframe.style.display = 'none'\n                divIframe.style.display = 'none'\n                // Continuar con la validación\n                handleValidate3DS()\n            }\n        }\n    }\n    window.addEventListener('message', handleMessage, { once: true })\n    return () =&gt; {\n        window.removeEventListener('message', handleMessage)\n    }\n}, [enrollment3dsData, handleValidate3DS])\n\n</code></pre>\n<h3 id=\"2-limpiar-iframes-y-formularios\">2. Limpiar iFrames y Formularios</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">const cleanupIframesAndForms = () =&gt; {\n    const divIframe = document.querySelector('.div-iframe') as HTMLDivElement\n    if (divIframe) {\n        divIframe.remove()\n    }\n    const stepUpForm = document.getElementById('step_up_form')\n    if (stepUpForm) {\n        stepUpForm.remove()\n    }\n    const cardinalCollectionIframe = document.getElementById('cardinal_collection_iframe')\n    if (cardinalCollectionIframe) {\n        cardinalCollectionIframe.remove()\n    }\n    const cardinalCollectionForm = document.getElementById('cardinal_collection_form')\n    if (cardinalCollectionForm) {\n        cardinalCollectionForm.remove()\n    }\n}\n\n</code></pre>\n<hr />\n<h2 id=\"variables-de-entorno\">Variables de Entorno</h2>\n<h3 id=\"configuración-del-orquestador\">Configuración del Orquestador</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code># Staging\nNEXT_PUBLIC_ORCHESTRATOR_URL=https://checkoutv2.greenpaysbx.me\n# Production\nNEXT_PUBLIC_ORCHESTRATOR_URL=https://checkoutv2.greenpay.com\n\n</code></pre><h3 id=\"configuración-de-cardinal-commerce\">Configuración de Cardinal Commerce</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code># Staging\nNEXT_PUBLIC_CARDINAL_COMMERCE_URL=https://centinelapistag.cardinalcommerce.com\n# Production\nNEXT_PUBLIC_CARDINAL_COMMERCE_URL=https://centinelapi.cardinalcommerce.com\n\n</code></pre><hr />\n<h2 id=\"ejemplo-completo-de-implementación\">Ejemplo Completo de Implementación</h2>\n<h3 id=\"flujo-principal-del-enrollment\">Flujo Principal del Enrollment</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">const handleContinueAfterRecollection = useCallback(async () =&gt; {\n    try {\n        setIsLoading(true)\n        // Transformar datos de la tarjeta para 3DS\n        const encryptedData = await paymentService.transformCardDataFor3DS(\n            cardFormData as CardFormData,\n            orderResponseData as OrderResponse\n        )\n        // Realizar el enrollment 3DS\n        const enrollmentResponse = await paymentService.processEnrollment3DS(\n            encryptedData,\n            orderResponseData?.token as string,\n            setup3dsData as Setup3dsResponseInterface\n        )\n        // Validar si la transacción fue exitosa y no hay fricción\n        if (enrollmentResponse?.result?.transaction?.status === 'SUCCESSFUL') {\n            if (cardFormData?.card.isFavorite) {\n                await handleTokenizeCard(cardFormData)\n            }\n            return onSubmit(cardFormData!)\n        }\n        // Validar si hay error en el enrollment 3DS\n        if (enrollmentResponse.result?.transaction.status === 'FAILED') {\n            throw new Error(enrollmentResponse?.result?.error?.message ?? '')\n        }\n        // Validar si hay fricción en el enrollment 3DS\n        if (\n            enrollmentResponse?.result?.transaction.status === 'CYBS_PA_ENROLLMENT' &amp;&amp;\n            enrollmentResponse?.result?.stepUpUrl\n        ) {\n            await createiFrame3DSEnrollment(enrollmentResponse)\n            const script = document.createElement('script')\n            script.type = 'text/javascript'\n            document.head.appendChild(script)\n            const stepUpForm = document.getElementById('step_up_form') as HTMLFormElement\n            if (stepUpForm) {\n                stepUpForm.submit()\n            }\n            return setEnrollment3dsData(enrollmentResponse)\n        }\n    } catch (error: any) {\n        console.error('Error al procesar el pago:', error)\n        setError(\n            'Ocurrió un error al procesar el pago. Por favor, intente nuevamente. ' +\n            error?.message\n        )\n    } finally {\n        setIsLoading(false)\n    }\n}, [\n    cardFormData,\n    orderResponseData,\n    setup3dsData,\n    handleTokenizeCard,\n    onSubmit,\n    createiFrame3DSEnrollment\n])\n\n</code></pre>\n<hr />\n<h2 id=\"repositorio-de-ejemplo-completo\">Repositorio de Ejemplo Completo</h2>\n<p>Para ver una implementación completa del flujo 3DS con enrollment, visita el repositorio de ejemplo:Repositorio: <a href=\"https://bitbucket.org/greeenpay/3ds-tokenization-nextjs/src/main/Este\">https://bitbucket.org/greeenpay/3ds-tokenization-nextjs/src/main/Este</a> repositorio contiene una implementación completa en Next.js que demuestra:</p>\n<ul>\n<li><p>Setup 3DS</p>\n</li>\n<li><p>Recolección de datos del navegador</p>\n</li>\n<li><p>Enrollment 3DS con y sin fricción</p>\n</li>\n<li><p>Manejo de iframes para challenges</p>\n</li>\n<li><p>Validación 3DS</p>\n</li>\n<li><p>Tokenización de tarjetas</p>\n</li>\n</ul>\n","urlObject":{"path":["3ds","enrollment"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"9a2e297d-1370-44d5-abca-531336e0e39f","name":"PA ENROLLMENT fricción exitoso","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    },\n    \"referenceId\": \"{{ID de referencia obtenido al momento de ejecutar el proceso PA SETUP}}\",\n    \"transactionId\": \"{{ID de transacción obtenido al momento de ejecutar el proceso PA SETUP}}\",\n    \"redirectURL\": \"{{redirectURL}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/af_pa_enrollment"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 11 Jun 2024 14:59:49 GMT"},{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"},{"key":"Content-Length","value":"390"},{"key":"Connection","value":"keep-alive"},{"key":"Apigw-Requestid","value":"ZNTuwj3eIAMEY6w="}],"cookie":[],"responseTime":null,"body":"{\n    \"statusCode\": 200,\n    \"result\": {\n        \"id\": \"7365177584066914304953\",\n        \"code\": \"b7e17514-188b-4174-9a9a-5af9b87532cb\",\n        \"status\": \"PENDING_AUTHENTICATION\",\n        \"authenticationTransactionId\": \"Tuc9dc7m2uxABa1bqG80\",\n        \"jwt\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNjgyZWVmNi0zYTk1LTRhMzItYTE5Ni0xYmIxZWNjYWU0MmYiLCJpYXQiOjE3MzY1MTc3NTgsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTczNjUyMTM1OCwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUGF5bG9hZCI6eyJBQ1NVcmwiOiJodHRwczovLzBtZXJjaGFudGFjc3N0YWcuY2FyZGluYWxjb21tZXJjZS5jb20vTWVyY2hhbnRBQ1NXZWIvY3JlcS5qc3AiLCJQYXlsb2FkIjoiZXlKdFpYTnpZV2RsVkhsd1pTSTZJa05TWlhFaUxDSnRaWE56WVdkbFZtVnljMmx2YmlJNklqSXVNaTR3SWl3aWRHaHlaV1ZFVTFObGNuWmxjbFJ5WVc1elNVUWlPaUk1TWpNeFlqWTBOaTB4TkRNeExUUXhOR1l0WVdVek5DMDNZV05tT1RkaE5tTTBOMlFpTENKaFkzTlVjbUZ1YzBsRUlqb2laREU1T1dRMk5XVXRaR0ZrT0MwMFkySTJMVGsyWkRjdE9USm1PRGMzWTJWak1UaGxJaXdpWTJoaGJHeGxibWRsVjJsdVpHOTNVMmw2WlNJNklqQXlJbjAiLCJUcmFuc2FjdGlvbklkIjoiVHVjOWRjN20ydXhBQmExYnFHODAifSwiT2JqZWN0aWZ5UGF5bG9hZCI6dHJ1ZSwiUmV0dXJuVXJsIjoiaHR0cHM6Ly9jaGVja291dHYyLmdyZWVucGF5c2J4Lm1lLzNkcy9yZWRpcmVjdCJ9.fewHhM-u2kteEHOr_JhrgS_R6-bkCRsEakH2gtjXsro\",\n        \"acsTransactionId\": \"d199d65e-dad8-4cb6-96d7-92f877cec18e\",\n        \"acsUrl\": \"https://0merchantacsstag.cardinalcommerce.com/MerchantACSWeb/creq.jsp\",\n        \"challengeRequired\": \"N\",\n        \"pareq\": \"eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI5MjMxYjY0Ni0xNDMxLTQxNGYtYWUzNC03YWNmOTdhNmM0N2QiLCJhY3NUcmFuc0lEIjoiZDE5OWQ2NWUtZGFkOC00Y2I2LTk2ZDctOTJmODc3Y2VjMThlIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0\",\n        \"stepUpUrl\": \"https://centinelapistag.cardinalcommerce.com/V2/Cruise/StepUp\",\n        \"threeDSServerTransactionId\": \"9231b646-1431-414f-ae34-7acf97a6c47d\",\n        \"veresEnrolled\": \"Y\",\n        \"directoryServerTransactionId\": \"94f17d98-5711-49f4-8b08-bd52315dca94\",\n        \"error\": {\n            \"code\": \"CONSUMER_AUTHENTICATION_REQUIRED\",\n            \"message\": \"The cardholder is enrolled in Payer Authentication. Please authenticate the cardholder before continuing with the transaction.\"\n        },\n        \"consumerAuthenticationInformation\": {\n            \"accessToken\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNjgyZWVmNi0zYTk1LTRhMzItYTE5Ni0xYmIxZWNjYWU0MmYiLCJpYXQiOjE3MzY1MTc3NTgsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTczNjUyMTM1OCwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUGF5bG9hZCI6eyJBQ1NVcmwiOiJodHRwczovLzBtZXJjaGFudGFjc3N0YWcuY2FyZGluYWxjb21tZXJjZS5jb20vTWVyY2hhbnRBQ1NXZWIvY3JlcS5qc3AiLCJQYXlsb2FkIjoiZXlKdFpYTnpZV2RsVkhsd1pTSTZJa05TWlhFaUxDSnRaWE56WVdkbFZtVnljMmx2YmlJNklqSXVNaTR3SWl3aWRHaHlaV1ZFVTFObGNuWmxjbFJ5WVc1elNVUWlPaUk1TWpNeFlqWTBOaTB4TkRNeExUUXhOR1l0WVdVek5DMDNZV05tT1RkaE5tTTBOMlFpTENKaFkzTlVjbUZ1YzBsRUlqb2laREU1T1dRMk5XVXRaR0ZrT0MwMFkySTJMVGsyWkRjdE9USm1PRGMzWTJWak1UaGxJaXdpWTJoaGJHeGxibWRsVjJsdVpHOTNVMmw2WlNJNklqQXlJbjAiLCJUcmFuc2FjdGlvbklkIjoiVHVjOWRjN20ydXhBQmExYnFHODAifSwiT2JqZWN0aWZ5UGF5bG9hZCI6dHJ1ZSwiUmV0dXJuVXJsIjoiaHR0cHM6Ly9jaGVja291dHYyLmdyZWVucGF5c2J4Lm1lLzNkcy9yZWRpcmVjdCJ9.fewHhM-u2kteEHOr_JhrgS_R6-bkCRsEakH2gtjXsro\",\n            \"acsTransactionId\": \"d199d65e-dad8-4cb6-96d7-92f877cec18e\",\n            \"acsUrl\": \"https://0merchantacsstag.cardinalcommerce.com/MerchantACSWeb/creq.jsp\",\n            \"authenticationTransactionId\": \"Tuc9dc7m2uxABa1bqG80\",\n            \"challengeRequired\": \"N\",\n            \"pareq\": \"eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI5MjMxYjY0Ni0xNDMxLTQxNGYtYWUzNC03YWNmOTdhNmM0N2QiLCJhY3NUcmFuc0lEIjoiZDE5OWQ2NWUtZGFkOC00Y2I2LTk2ZDctOTJmODc3Y2VjMThlIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0\",\n            \"specificationVersion\": \"2.2.0\",\n            \"stepUpUrl\": \"https://centinelapistag.cardinalcommerce.com/V2/Cruise/StepUp\",\n            \"threeDSServerTransactionId\": \"9231b646-1431-414f-ae34-7acf97a6c47d\",\n            \"veresEnrolled\": \"Y\",\n            \"directoryServerTransactionId\": \"94f17d98-5711-49f4-8b08-bd52315dca94\",\n            \"acsOperatorID\": \"MerchantACS\",\n            \"acsReferenceNumber\": \"Cardinal ACS\"\n        },\n        \"transaction\": {\n            \"id\": \"b7e17514-188b-4174-9a9a-5af9b87532cb\",\n            \"status\": \"CYBS_PA_ENROLLMENT\",\n            \"description\": \"API-V2-USD\",\n            \"authorization\": \"\",\n            \"webhook_url\": \"https://webhook.site/c30917eb-812e-4305-bc5c-085b998f57aa\",\n            \"customer\": {\n                \"name\": \"Angel Gonzalez\",\n                \"email\": \"agonzalez@greenpay.me\",\n                \"identification\": \"124444\",\n                \"billingAddress\": {\n                    \"country\": \"CR\",\n                    \"province\": \"Nombre de la provincia\",\n                    \"city\": \"Ciudad\",\n                    \"street1\": \"Dirección Calle 1\",\n                    \"street2\": \"Dirección Calle 2\",\n                    \"zip\": \"10801\"\n                },\n                \"shippingAddress\": {\n                    \"country\": \"CR\",\n                    \"province\": \"Nombre de la provincia\",\n                    \"city\": \"Ciudad\",\n                    \"street1\": \"Dirección Calle 1\",\n                    \"street2\": \"Dirección Calle 2\",\n                    \"zip\": \"10801\"\n                }\n            },\n            \"entity_response\": \"\",\n            \"orderReference\": \"API-V2-CRC-4791\"\n        }\n    }\n}"},{"id":"b13c6d7e-5518-4c66-b0e1-885b28c4e044","name":"PA ENROLLMENT sin friccion exitoso","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    },\n    \"referenceId\": \"{{ID de referencia obtenido al momento de ejecutar el proceso PA SETUP}}\",\n    \"transactionId\": \"{{ID de transacción obtenido al momento de ejecutar el proceso PA SETUP}}\",\n    \"redirectURL\": \"{{redirectURL}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/af_pa_enrollment"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 11 Jun 2024 14:59:49 GMT"},{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"},{"key":"Content-Length","value":"390"},{"key":"Connection","value":"keep-alive"},{"key":"Apigw-Requestid","value":"ZNTuwj3eIAMEY6w="}],"cookie":[],"responseTime":null,"body":"{\n    \"statusCode\": 200,\n    \"result\": {\n        \"id\": \"7365177764686917804953\",\n        \"code\": \"b7e17514-188b-4174-9a9a-5af9b87532cb\",\n        \"status\": \"AUTHENTICATION_SUCCESSFUL\",\n        \"acsTransactionId\": \"d199d65e-dad8-4cb6-96d7-92f877cec18e\",\n        \"threeDSServerTransactionId\": \"9231b646-1431-414f-ae34-7acf97a6c47d\",\n        \"directoryServerTransactionId\": \"94f17d98-5711-49f4-8b08-bd52315dca94\",\n        \"paresStatus\": \"Y\",\n        \"consumerAuthenticationInformation\": {\n            \"acsTransactionId\": \"d199d65e-dad8-4cb6-96d7-92f877cec18e\",\n            \"authenticationResult\": \"0\",\n            \"authenticationStatusMsg\": \"Success\",\n            \"cavv\": \"AAIBBYNoEwAAACcKhAJkdQAAAAA=\",\n            \"indicator\": \"vbv\",\n            \"eci\": \"05\",\n            \"eciRaw\": \"05\",\n            \"paresStatus\": \"Y\",\n            \"specificationVersion\": \"2.2.0\",\n            \"threeDSServerTransactionId\": \"9231b646-1431-414f-ae34-7acf97a6c47d\",\n            \"xid\": \"AAIBBYNoEwAAACcKhAJkdQAAAAA=\",\n            \"directoryServerTransactionId\": \"94f17d98-5711-49f4-8b08-bd52315dca94\"\n        },\n        \"error\": {},\n        \"transaction\": {\n            \"id\": \"b7e17514-188b-4174-9a9a-5af9b87532cb\",\n            \"status\": \"SUCCESSFUL\",\n            \"description\": \"API-V2-USD\",\n            \"authorization\": \"831000\",\n            \"webhook_url\": \"https://webhook.site/c30917eb-812e-4305-bc5c-085b998f57aa\",\n            \"customer\": {\n                \"name\": \"Angel Gonzalez\",\n                \"email\": \"agonzalez@greenpay.me\",\n                \"identification\": \"124444\",\n                \"billingAddress\": {\n                    \"country\": \"CR\",\n                    \"province\": \"Nombre de la provincia\",\n                    \"city\": \"Ciudad\",\n                    \"street1\": \"Dirección Calle 1\",\n                    \"street2\": \"Dirección Calle 2\",\n                    \"zip\": \"10801\"\n                },\n                \"shippingAddress\": {\n                    \"country\": \"CR\",\n                    \"province\": \"Nombre de la provincia\",\n                    \"city\": \"Ciudad\",\n                    \"street1\": \"Dirección Calle 1\",\n                    \"street2\": \"Dirección Calle 2\",\n                    \"zip\": \"10801\"\n                }\n            },\n            \"entity_response\": {\n                \"_links\": {\n                    \"self\": {\n                        \"href\": \"/pts/v2/payments/7365177795756918404953\",\n                        \"method\": \"GET\"\n                    }\n                },\n                \"id\": \"7365177795756918404953\",\n                \"submitTimeUtc\": \"2025-01-10T14:02:59Z\",\n                \"status\": \"AUTHORIZED\",\n                \"reconciliationId\": \"7365177795756918404953\",\n                \"clientReferenceInformation\": {\n                    \"code\": \"b7e17514-188b-4174-9a9a-5af9b87532cb\"\n                },\n                \"processorInformation\": {\n                    \"approvalCode\": \"831000\",\n                    \"transactionId\": \"016153570198200\",\n                    \"networkTransactionId\": \"016153570198200\",\n                    \"responseCode\": \"00\",\n                    \"responseDetails\": \"ABC\",\n                    \"avs\": {\n                        \"code\": \"Y\",\n                        \"codeRaw\": \"Y\"\n                    },\n                    \"merchantAdvice\": {\n                        \"code\": \"01\",\n                        \"codeRaw\": \"M001\"\n                    },\n                    \"consumerAuthenticationResponse\": {\n                        \"code\": \"2\",\n                        \"codeRaw\": \"2\"\n                    },\n                    \"systemTraceAuditNumber\": \"142887\",\n                    \"retrievalReferenceNumber\": \"501014142887\"\n                },\n                \"paymentAccountInformation\": {\n                    \"card\": {\n                        \"type\": \"001\"\n                    }\n                },\n                \"paymentInformation\": {\n                    \"card\": {\n                        \"type\": \"001\"\n                    },\n                    \"tokenizedCard\": {\n                        \"type\": \"001\"\n                    }\n                },\n                \"orderInformation\": {\n                    \"amountDetails\": {\n                        \"totalAmount\": \"10.00\",\n                        \"authorizedAmount\": \"10.00\",\n                        \"currency\": \"CRC\"\n                    }\n                }\n            },\n            \"orderReference\": \"API-V2-CRC-4791\"\n        }\n    }\n}"},{"id":"bb6ee4f9-f3b3-4c7f-9e72-418f5e07056c","name":"PA ENROLLMENT Sesión Expirada","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    },\n    \"referenceId\": \"{{ID de referencia obtenido al momento de ejecutar el proceso PA SETUP}}\",\n    \"transactionId\": \"{{ID de transacción obtenido al momento de ejecutar el proceso PA SETUP}}\",\n    \"redirectURL\": \"{{redirectURL}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/af_pa_enrollment"},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 11 Jun 2024 15:32:53 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"51"},{"key":"Connection","value":"keep-alive"},{"key":"Apigw-Requestid","value":"ZNYlhgt3IAMES9A="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Sesion no encontrada!\",\n    \"status\": \"fail\"\n}"}],"_postman_id":"ce98c96a-1f0f-4f84-b975-d307c9482f6a"},{"name":"PA VALIDATE","id":"4de6b20f-47f1-45d9-b3fe-9f0f98c6a152","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    },\n    \"authenticationTransactionId\": \"{{ID de autenticación de la transacción obtenido al momento de ejecutar el proceso PA ENROLLMENT}}\",\n    \"transactionId\": \"{{ID de transacción obtenido al momento de ejecutar el proceso PA SETUP}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/3ds/validate","description":"<h1 id=\"validate-3ds--api-v2\">Validate 3DS – API V2</h1>\n<p>&gt; Descripción: Este endpoint permite realizar la validación respectiva del código de autorización enviado por el emisor de la tarjeta, ingresado por el tarjeta habiente en el proceso anterior (PA ENROLLMENT).</p>\n<p>Este endpoint solo aplica para transacciones donde el enrrolment requiere verificacion(challenge o desafio)</p>\n<h2 id=\"resumen\">Resumen</h2>\n<p>El Validate 3DS retorna un objeto JSON con el resultado de la validación del código de autorización enviado por el banco emisor de la tarjeta.</p>\n<h3 id=\"requisitos-obligatorios\">Requisitos Obligatorios</h3>\n<ul>\n<li>Ejecutar correctamente el PA ENROLLMENT</li>\n<li>Esperar la respuesta del evento de GreenPay después de que el usuario ejecute el challenge de 3DS</li>\n<li>Validar siempre <code>result.transaction.status</code> para determinar el resultado real de la transacción</li>\n</ul>\n<hr />\n<h2 id=\"pasos-previos-enrollment-3ds\">Pasos Previos: Enrollment 3DS</h2>\n<h3 id=\"1-enrollment-3ds\">1. Enrollment 3DS</h3>\n<p>Realiza una solicitud al endpoint de Enrollment 3DS para obtener la configuración inicial.Valores que obtendrás:</p>\n<ul>\n<li>authenticationTransactionId: ID de transacción de autenticación</li>\n<li>code: Código de transacción del enrollment</li>\n</ul>\n<hr />\n<h2 id=\"endpoint-de-validate-3ds\">Endpoint de Validate 3DS</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Propiedad</th>\n<th>Valor</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Método</td>\n<td>POST</td>\n</tr>\n<tr>\n<td>Descripción</td>\n<td>Validación del código de autorización 3DS</td>\n</tr>\n<tr>\n<td>Conexión Segura</td>\n<td>Sí, bajo TLS 1.2</td>\n</tr>\n<tr>\n<td>Cifrado de Datos</td>\n<td>JSON codificado en base64</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"headers\">Headers</h2>\n<h3 id=\"header-obligatorio\">Header Obligatorio</h3>\n<p>El header session-token es obligatorio y debe ser enviado en cada solicitud a este endpoint.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>session-token</td>\n<td>String</td>\n<td>Token obtenido en la creación de la orden de pago</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><p>Ejemplo de session-token (UUID):</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>ad79b9b0-917d-11ef-8a48-19ee98944b83\n\n</code></pre><hr />\n<h2 id=\"body-json\">Body (JSON)</h2>\n<h3 id=\"estructura-del-request\">Estructura del Request</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"cardData\": {\n        \"session\": \"\",\n        \"ed\": \"\"\n    },\n    \"authenticationTransactionId\": \"\",\n    \"transactionId\": \"\"\n}\n\n</code></pre>\n<h3 id=\"campos-obligatorios\">Campos Obligatorios</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>cardData.session</td>\n<td>String</td>\n<td>Sesión generada al crear la orden de pago</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>cardData.ed</td>\n<td>String</td>\n<td>Datos de la tarjeta en formato base64</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>authenticationTransactionId</td>\n<td>String</td>\n<td>Valor de la respuesta del enrollment <code>result.authenticationTransactionId</code></td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>transactionId</td>\n<td>String</td>\n<td>Valor de la respuesta del setup <code>result.transaction.id</code></td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"estructura-del-objeto-ed-antes-de-base64\">Estructura del Objeto ed (antes de base64)</h2>\n<h3 id=\"formato-json\">Formato JSON</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n   \"card\": {\n    \"cardHolder\": \"John Doe\",\n    \"expirationDate\": {\n      \"month\": \"12\",\n      \"year\": \"31\"\n    },\n    \"cardNumber\": \"5597270000001815\",\n    \"cvc\": \"196\"\n  },\n   \"additional\": { \n     \"channelData\": { \n       \"channel\": \"01\", \n       \"source\": \"API_CARD\" \n     } \n   }\n}\n\n</code></pre>\n<h3 id=\"campos-detallados\">Campos Detallados</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Restricciones</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>card.cardHolder</td>\n<td>String</td>\n<td>Nombre del dueño de la tarjeta</td>\n<td>5-50 caracteres</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.month</td>\n<td>String</td>\n<td>Mes de vencimiento</td>\n<td>2 caracteres, \"01\" a \"12\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.expirationDate.year</td>\n<td>String</td>\n<td>Año de vencimiento (últimos 2 dígitos)</td>\n<td>2 caracteres, Ej: \"31\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cardNumber</td>\n<td>String</td>\n<td>Número de la tarjeta</td>\n<td>-</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>card.cvc</td>\n<td>String</td>\n<td>Código de seguridad de la tarjeta</td>\n<td>-</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.channel</td>\n<td>String</td>\n<td>Canal</td>\n<td>Debe ser \"01\"</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>additional.channelData.source</td>\n<td>String</td>\n<td>Fuente</td>\n<td>Debe ser \"API_CARD\"</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"respuestas-del-validate-3ds\">Respuestas del Validate 3DS</h2>\n<h3 id=\"importante-validación-del-status\">Importante: Validación del Status</h3>\n<p>CRÍTICO: Siempre validar <code>result.transaction.status</code> para determinar el resultado real:</p>\n<ul>\n<li>SUCCESSFUL = Transacción validada y exitosa</li>\n<li>FAILED = Transacción fallida (error)</li>\n</ul>\n<p>El HTTP status puede ser 200, pero la transacción puede haber fallado. Siempre verificar el status de la transacción.</p>\n<h3 id=\"obtención-del-mensaje-de-error\">Obtención del Mensaje de Error</h3>\n<p>Para obtener el mensaje de error, usar:</p>\n<p><code>const errorMessage = result?.error?.message ?? result.error</code></p>\n<hr />\n<h2 id=\"respuesta-exitosa-http-code-200\">Respuesta Exitosa (HTTP Code 200)</h2>\n<h3 id=\"ejemplo-de-respuesta\">Ejemplo de Respuesta</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"result\": {\n        \"statusCode\": 200,\n        \"status\": \"success\",\n        \"orderId\": \"compra-demo-payment-1-20250612-7040\",\n        \"token\": \"872d2033-ec0e-4c38-a119-a2920e55e8ca\",\n        \"transactionId\": \"ffd8076a-6863-42aa-85eb-74a4b7e5b4c0\",\n        \"amount\": 590,\n        \"currency\": \"USD\",\n        \"transaction\": {\n            \"terminal\": \"e044afee-8861-4b9d-946b-1643656c82a5\",\n            \"currency\": \"USD\",\n            \"entity_response\": {},\n            \"created_at\": \"2025-06-12T21:21:58.405Z\",\n            \"reference_number\": \"compra-demo-payment-1-20250612-7040\",\n            \"status\": \"SUCCESSFUL\",\n            \"merchant_name\": \"Comercio Pruebas 3DS\",\n            \"source\": \"API_CARD\",\n            \"cybersource_threeds_pa_setup\": {\n                \"id\": \"7497633213356406204805\",\n                \"code\": \"ffd8076a-6863-42aa-85eb-74a4b7e5b4c0\",\n                \"deviceDataCollectionUrl\": \"https://centinelapistag.cardinalcommerce.com/V1/Cruise/Collect\",\n                \"jwt\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n                \"referenceId\": \"7102b825-48e0-4c22-a115-0c6e9eb920a3\",\n                \"status\": \"COMPLETED\"\n            },\n            \"updated_at\": \"2025-06-12T21:22:03.776Z\",\n            \"redirectURL\": \"\",\n            \"quota\": 0,\n            \"webhook_url\": \"https://webhook.site/940cf625-447e-4da3-8eac-be7c2470ee0f\",\n            \"internal_ref\": 16504873736157,\n            \"amount\": 590,\n            \"merchant_id\": \"004a16ef-1be2-4ada-91ef-6222a7c1930e\",\n            \"customer\": {\n                \"name\": \"John Doe\",\n                \"shippingAddress\": {\n                    \"zip\": \"90001\",\n                    \"country\": \"US\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\"\n                },\n                \"identification\": \"123456789\",\n                \"billingAddress\": {\n                    \"zip\": \"90001\",\n                    \"country\": \"US\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\"\n                },\n                \"email\": \"john.doe@example.com\"\n            },\n            \"authorizer\": \"cybersource\",\n            \"id\": \"ffd8076a-6863-42aa-85eb-74a4b7e5b4c0\",\n            \"description\": \"Demo Payment 12432\",\n            \"authorization\": \"831000\",\n            \"card\": {\n                \"last4\": \"1815\",\n                \"cardnumber\": \"559727******1815\",\n                \"brand\": \"Mastercard\",\n                \"khash\": \"559727ZKF70RXEIDPU2B\",\n                \"bin\": \"559727\"\n            },\n            \"orderReference\": \"compra-demo-payment-1-20250612-7040\"\n        },\n        \"quota\": 0,\n        \"last4\": \"1815\",\n        \"brand\": \"Mastercard\",\n        \"bin\": \"559727\"\n    }\n}\n\n</code></pre>\n<h3 id=\"campos-de-respuesta-exitosa\">Campos de Respuesta Exitosa</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>result.statusCode</td>\n<td>Number</td>\n<td>Código de estado HTTP (200)</td>\n</tr>\n<tr>\n<td>result.status</td>\n<td>String</td>\n<td>Estado de la respuesta (\"success\")</td>\n</tr>\n<tr>\n<td>result.orderId</td>\n<td>String</td>\n<td>ID de la orden</td>\n</tr>\n<tr>\n<td>result.token</td>\n<td>String</td>\n<td>Token de la transacción</td>\n</tr>\n<tr>\n<td>result.transactionId</td>\n<td>String</td>\n<td>ID de la transacción</td>\n</tr>\n<tr>\n<td>result.amount</td>\n<td>Number</td>\n<td>Monto de la transacción</td>\n</tr>\n<tr>\n<td>result.currency</td>\n<td>String</td>\n<td>Moneda de la transacción</td>\n</tr>\n<tr>\n<td>result.transaction.status</td>\n<td>String</td>\n<td>CRÍTICO: Estado de la transacción (\"SUCCESSFUL\")</td>\n</tr>\n<tr>\n<td>result.transaction.authorization</td>\n<td>String</td>\n<td>Código de autorización bancario</td>\n</tr>\n<tr>\n<td>result.transaction.description</td>\n<td>String</td>\n<td>Descripción de la transacción</td>\n</tr>\n<tr>\n<td>result.last4</td>\n<td>String</td>\n<td>Últimos 4 dígitos de la tarjeta</td>\n</tr>\n<tr>\n<td>result.brand</td>\n<td>String</td>\n<td>Marca de la tarjeta</td>\n</tr>\n<tr>\n<td>result.bin</td>\n<td>String</td>\n<td>BIN de la tarjeta</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"respuesta-fallida-http-code-200\">Respuesta Fallida (HTTP Code 200)</h2>\n<h3 id=\"ejemplo-de-respuesta-fallida\">Ejemplo de Respuesta Fallida</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"result\": {\n        \"error\": {\n            \"status\": 400,\n            \"reason\": \"AFPAENROLLMENT3DS\",\n            \"message\": \"Error to authorize Transaction veresEnrolled or paresStatus, please try again later.\"\n        },\n        \"statusCode\": 400,\n        \"status\": \"fail\",\n        \"orderId\": \"compra-demo-payment-1-20250612-7040\",\n        \"token\": \"872d2033-ec0e-4c38-a119-a2920e55e8ca\",\n        \"transactionId\": \"ffd8076a-6863-42aa-85eb-74a4b7e5b4c0\",\n        \"amount\": 590,\n        \"currency\": \"USD\",\n        \"transaction\": {\n            \"terminal\": \"e044afee-8861-4b9d-946b-1643656c82a5\",\n            \"currency\": \"USD\",\n            \"entity_response\": {},\n            \"created_at\": \"2025-06-12T21:21:58.405Z\",\n            \"reference_number\": \"compra-demo-payment-1-20250612-7040\",\n            \"status\": \"FAILED\",\n            \"merchant_name\": \"Comercio Pruebas 3DS\",\n            \"source\": \"API_CARD\",\n            \"cybersource_threeds_pa_setup\": {\n                \"id\": \"7497633213356406204805\",\n                \"code\": \"ffd8076a-6863-42aa-85eb-74a4b7e5b4c0\",\n                \"deviceDataCollectionUrl\": \"https://centinelapistag.cardinalcommerce.com/V1/Cruise/Collect\",\n                \"jwt\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n                \"referenceId\": \"7102b825-48e0-4c22-a115-0c6e9eb920a3\",\n                \"status\": \"COMPLETED\"\n            },\n            \"updated_at\": \"2025-06-12T21:22:03.776Z\",\n            \"redirectURL\": \"\",\n            \"quota\": 0,\n            \"webhook_url\": \"https://webhook.site/940cf625-447e-4da3-8eac-be7c2470ee0f\",\n            \"internal_ref\": 16504873736157,\n            \"amount\": 590,\n            \"merchant_id\": \"004a16ef-1be2-4ada-91ef-6222a7c1930e\",\n            \"customer\": {\n                \"name\": \"John Doe\",\n                \"shippingAddress\": {\n                    \"zip\": \"90001\",\n                    \"country\": \"US\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\"\n                },\n                \"identification\": \"123456789\",\n                \"billingAddress\": {\n                    \"zip\": \"90001\",\n                    \"country\": \"US\",\n                    \"street1\": \"123 Main St\",\n                    \"street2\": \"Apt 4B\",\n                    \"province\": \"California\",\n                    \"city\": \"Los Angeles\"\n                },\n                \"email\": \"john.doe@example.com\"\n            },\n            \"authorizer\": \"cybersource\",\n            \"id\": \"ffd8076a-6863-42aa-85eb-74a4b7e5b4c0\",\n            \"description\": \"Demo Payment 12432\",\n            \"authorization\": \"\",\n            \"card\": {\n                \"last4\": \"1815\",\n                \"cardnumber\": \"559727******1815\",\n                \"brand\": \"Mastercard\",\n                \"khash\": \"559727ZKF70RXEIDPU2B\",\n                \"bin\": \"559727\"\n            },\n            \"orderReference\": \"compra-demo-payment-1-20250612-7040\"\n        },\n        \"quota\": 0,\n        \"last4\": \"1815\",\n        \"brand\": \"Mastercard\",\n        \"bin\": \"559727\",\n        \"cause\": {\n            \"origin\": \"AFPAENROLLMENT3DS\"\n        }\n    }\n}\n\n</code></pre>\n<h3 id=\"campos-de-respuesta-fallida\">Campos de Respuesta Fallida</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>result.transaction.status</td>\n<td>String</td>\n<td>CRÍTICO: Estado de la transacción (\"FAILED\")</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"error-de-validación-http-code-400\">Error de Validación (HTTP Code 400)</h2>\n<h3 id=\"ejemplo-de-error-de-validación\">Ejemplo de Error de Validación</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"message\": \"Event object failed validation\",\n    \"status\": 400\n}\n\n</code></pre>\n<h3 id=\"descripción\">Descripción</h3>\n<p>Este error ocurre cuando:</p>\n<ul>\n<li>HTTP Status: 400</li>\n<li>Causa: Validaciones de estructura del objeto fallaron</li>\n<li>Solución: Verificar que se estén enviando correctamente las keys del objeto</li>\n</ul>\n<hr />\n<h2 id=\"manejo-de-errores\">Manejo de Errores</h2>\n<h3 id=\"obtención-del-mensaje-de-error-1\">Obtención del Mensaje de Error</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">// Forma recomendada para obtener el mensaje de error\nconst errorMessage = result?.error?.message ?? result.error;\n\n</code></pre>\n<hr />\n<h2 id=\"variables-de-entorno\">Variables de Entorno</h2>\n<h3 id=\"configuración-del-endpoint\">Configuración del Endpoint</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code># URL del endpoint de Validate 3DS\nVALIDATE_3DS_URL=https://api.greenpay.com/v2/3ds/validate\n# Token de sesión (obtenido al crear la orden)\nSESSION_TOKEN=ad79b9b0-917d-11ef-8a48-19ee98944b83\n\n</code></pre><hr />\n<h2 id=\"ejemplo-de-implementación\">Ejemplo de Implementación</h2>\n<h3 id=\"código-de-ejemplo\">Código de Ejemplo</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-typescript\">// En 3ds-tokenization-nextjs/src/services/paymentService.ts\nasync processValidate3DS({\n    encryptedData,\n    sessionToken,\n    setup3dsResponse,\n    enrollment3dsResponse\n}: {\n    encryptedData: CardEncryptedRequestData\n    sessionToken: string\n    setup3dsResponse: Setup3dsResponseInterface\n    enrollment3dsResponse: Enrollment3DsResponseInterface\n}): Promise&lt;Validate3DSResponseInterface&gt; {\n    try {\n        const validateData = {\n            cardDataa: {\n                session: encryptedData.session,\n                ed: encryptedData.ed\n            },\n            authenticationTransactionId:\n                enrollment3dsResponse?.result.authenticationTransactionId,\n            transactionId: setup3dsResponse.result?.transaction?.id,\n            additional: {\n                channelData: {\n                    channel: '01',\n                    source: 'API_CARD'\n                }\n            }\n        }\n        // Mostrar el JSON que se va a enviar\n        console.log('JSON a enviar:', JSON.stringify(validateData, null, 2))\n        const { data: response } = await axios({\n            method: 'post',\n            url: process.env.NEXT_PUBLIC_VALIDATE_ENDPOINT_V2,\n            headers: {,\n                'session-token': sessionToken\n            },\n            data: validateData\n        })\n        console.log('Respuesta validate 3DS:', response)\n        return response\n    } catch (error) {\n        mapHttpError(error)\n        throw error\n    }\n}\n\n</code></pre>\n<hr />\n<h2 id=\"consideraciones-importantes\">Consideraciones Importantes</h2>\n<h3 id=\"1-validación-del-status\">1. Validación del Status</h3>\n<ul>\n<li>Siempre validar result.transaction.status</li>\n<li>HTTP 200 no garantiza transacción exitosa</li>\n<li>SUCCESSFUL = Transacción validada</li>\n<li>FAILED = Transacción fallida</li>\n</ul>\n<h3 id=\"2-espera-del-challenge\">2. Espera del Challenge</h3>\n<ul>\n<li>Esperar la respuesta del evento de GreenPay</li>\n<li>No ejecutar validate inmediatamente después del enrollment</li>\n<li>Verificar que el usuario haya completado el challenge</li>\n</ul>\n<h3 id=\"3-manejo-de-errores\">3. Manejo de Errores</h3>\n<ul>\n<li>Usar result?.error?.message ?? result.error para obtener mensajes</li>\n<li>Validar estructura del objeto antes del envío</li>\n<li>Manejar errores de validación (HTTP 400)</li>\n</ul>\n<h3 id=\"4-seguridad\">4. Seguridad</h3>\n<ul>\n<li>Codificar datos en base64</li>\n<li>Usar TLS 1.2 para conexiones seguras</li>\n<li>Validar tokens de sesión</li>\n</ul>\n<hr />\n<h2 id=\"repositorio-de-ejemplo\">Repositorio de Ejemplo</h2>\n<p>Para ver una implementación completa del flujo 3DS, incluyendo Validate, visita: <a href=\"https://bitbucket.org/greeenpay/3ds-tokenization-nextjs/src/main/\">https://bitbucket.org/greeenpay/3ds-tokenization-nextjs/src/main/</a> Este repositorio incluye ejemplos completos de:</p>\n<ul>\n<li>Setup 3DS</li>\n<li>Enrollment 3DS</li>\n<li>Validate 3DS</li>\n<li>Manejo de errores</li>\n<li>Interfaz de usuario</li>\n</ul>\n","urlObject":{"path":["3ds","validate"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"3f81fdc4-1d23-4c3c-a474-3571328c4cc3","name":"PA VALIDATE Sesión Expirada","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    },\n    \"authenticationTransactionId\": \"{{ID de autenticación de la transacción obtenido al momento de ejecutar el proceso PA ENROLLMENT}}\",\n    \"transactionId\": \"{{ID de transacción obtenido al momento de ejecutar el proceso PA SETUP}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/af_pa_validate"},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 11 Jun 2024 15:32:34 GMT"},{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"51"},{"key":"Connection","value":"keep-alive"},{"key":"Apigw-Requestid","value":"ZNYiohBpoAMESRg="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Sesion no encontrada!\",\n    \"status\": \"fail\"\n}"},{"id":"ab581fc5-2d09-4feb-8d91-6ef6c2a6c441","name":"PA VALIDATE exitoso","originalRequest":{"method":"POST","header":[{"key":"session-token","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}"}],"body":{"mode":"raw","raw":"{\n    \"cardData\": {\n        \"session\": \"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}\",\n        \"ed\": \"{{Información de la tarjeta codificada en base64}}\"\n    },\n    \"authenticationTransactionId\": \"{{ID de autenticación de la transacción obtenido al momento de ejecutar el proceso PA ENROLLMENT}}\",\n    \"transactionId\": \"{{ID de transacción obtenido al momento de ejecutar el proceso PA SETUP}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/3ds/validate"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n   \"statusCode\": 200,\n   \"result\":{\n   \"id\":\"7365177584066914304953\",\n   \"code\":\"b7e17514-188b-4174-9a9a-5af9b87532cb\",\n   \"status\":\"PENDING_AUTHENTICATION\",\n   \"authenticationTransactionId\":\"Tuc9dc7m2uxABa1bqG80\",\n   \"jwt\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNjgyZWVmNi0zYTk1LTRhMzItYTE5Ni0xYmIxZWNjYWU0MmYiLCJpYXQiOjE3MzY1MTc3NTgsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTczNjUyMTM1OCwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUGF5bG9hZCI6eyJBQ1NVcmwiOiJodHRwczovLzBtZXJjaGFudGFjc3N0YWcuY2FyZGluYWxjb21tZXJjZS5jb20vTWVyY2hhbnRBQ1NXZWIvY3JlcS5qc3AiLCJQYXlsb2FkIjoiZXlKdFpYTnpZV2RsVkhsd1pTSTZJa05TWlhFaUxDSnRaWE56WVdkbFZtVnljMmx2YmlJNklqSXVNaTR3SWl3aWRHaHlaV1ZFVTFObGNuWmxjbFJ5WVc1elNVUWlPaUk1TWpNeFlqWTBOaTB4TkRNeExUUXhOR1l0WVdVek5DMDNZV05tT1RkaE5tTTBOMlFpTENKaFkzTlVjbUZ1YzBsRUlqb2laREU1T1dRMk5XVXRaR0ZrT0MwMFkySTJMVGsyWkRjdE9USm1PRGMzWTJWak1UaGxJaXdpWTJoaGJHeGxibWRsVjJsdVpHOTNVMmw2WlNJNklqQXlJbjAiLCJUcmFuc2FjdGlvbklkIjoiVHVjOWRjN20ydXhBQmExYnFHODAifSwiT2JqZWN0aWZ5UGF5bG9hZCI6dHJ1ZSwiUmV0dXJuVXJsIjoiaHR0cHM6Ly9jaGVja291dHYyLmdyZWVucGF5c2J4Lm1lLzNkcy9yZWRpcmVjdCJ9.fewHhM-u2kteEHOr_JhrgS_R6-bkCRsEakH2gtjXsro\",\n   \"acsTransactionId\":\"d199d65e-dad8-4cb6-96d7-92f877cec18e\",\n   \"acsUrl\":\"https://0merchantacsstag.cardinalcommerce.com/MerchantACSWeb/creq.jsp\",\n   \"challengeRequired\":\"N\",\n   \"pareq\":\"eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI5MjMxYjY0Ni0xNDMxLTQxNGYtYWUzNC03YWNmOTdhNmM0N2QiLCJhY3NUcmFuc0lEIjoiZDE5OWQ2NWUtZGFkOC00Y2I2LTk2ZDctOTJmODc3Y2VjMThlIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0\",\n   \"stepUpUrl\":\"https://centinelapistag.cardinalcommerce.com/V2/Cruise/StepUp\",\n   \"threeDSServerTransactionId\":\"9231b646-1431-414f-ae34-7acf97a6c47d\",\n   \"veresEnrolled\":\"Y\",\n   \"directoryServerTransactionId\":\"94f17d98-5711-49f4-8b08-bd52315dca94\",\n   \"error\":{\n      \"code\":\"CONSUMER_AUTHENTICATION_REQUIRED\",\n      \"message\":\"The cardholder is enrolled in Payer Authentication. Please authenticate the cardholder before continuing with the transaction.\"\n   },\n   \"consumerAuthenticationInformation\":{\n      \"accessToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNjgyZWVmNi0zYTk1LTRhMzItYTE5Ni0xYmIxZWNjYWU0MmYiLCJpYXQiOjE3MzY1MTc3NTgsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTczNjUyMTM1OCwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUGF5bG9hZCI6eyJBQ1NVcmwiOiJodHRwczovLzBtZXJjaGFudGFjc3N0YWcuY2FyZGluYWxjb21tZXJjZS5jb20vTWVyY2hhbnRBQ1NXZWIvY3JlcS5qc3AiLCJQYXlsb2FkIjoiZXlKdFpYTnpZV2RsVkhsd1pTSTZJa05TWlhFaUxDSnRaWE56WVdkbFZtVnljMmx2YmlJNklqSXVNaTR3SWl3aWRHaHlaV1ZFVTFObGNuWmxjbFJ5WVc1elNVUWlPaUk1TWpNeFlqWTBOaTB4TkRNeExUUXhOR1l0WVdVek5DMDNZV05tT1RkaE5tTTBOMlFpTENKaFkzTlVjbUZ1YzBsRUlqb2laREU1T1dRMk5XVXRaR0ZrT0MwMFkySTJMVGsyWkRjdE9USm1PRGMzWTJWak1UaGxJaXdpWTJoaGJHeGxibWRsVjJsdVpHOTNVMmw2WlNJNklqQXlJbjAiLCJUcmFuc2FjdGlvbklkIjoiVHVjOWRjN20ydXhBQmExYnFHODAifSwiT2JqZWN0aWZ5UGF5bG9hZCI6dHJ1ZSwiUmV0dXJuVXJsIjoiaHR0cHM6Ly9jaGVja291dHYyLmdyZWVucGF5c2J4Lm1lLzNkcy9yZWRpcmVjdCJ9.fewHhM-u2kteEHOr_JhrgS_R6-bkCRsEakH2gtjXsro\",\n      \"acsTransactionId\":\"d199d65e-dad8-4cb6-96d7-92f877cec18e\",\n      \"acsUrl\":\"https://0merchantacsstag.cardinalcommerce.com/MerchantACSWeb/creq.jsp\",\n      \"authenticationTransactionId\":\"Tuc9dc7m2uxABa1bqG80\",\n      \"challengeRequired\":\"N\",\n      \"pareq\":\"eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI5MjMxYjY0Ni0xNDMxLTQxNGYtYWUzNC03YWNmOTdhNmM0N2QiLCJhY3NUcmFuc0lEIjoiZDE5OWQ2NWUtZGFkOC00Y2I2LTk2ZDctOTJmODc3Y2VjMThlIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0\",\n      \"specificationVersion\":\"2.2.0\",\n      \"stepUpUrl\":\"https://centinelapistag.cardinalcommerce.com/V2/Cruise/StepUp\",\n      \"threeDSServerTransactionId\":\"9231b646-1431-414f-ae34-7acf97a6c47d\",\n      \"veresEnrolled\":\"Y\",\n      \"directoryServerTransactionId\":\"94f17d98-5711-49f4-8b08-bd52315dca94\",\n      \"acsOperatorID\":\"MerchantACS\",\n      \"acsReferenceNumber\":\"Cardinal ACS\"\n   },\n   \"transaction\":{\n      \"id\":\"b7e17514-188b-4174-9a9a-5af9b87532cb\",\n      \"status\":\"CYBS_PA_ENROLLMENT\",\n      \"description\":\"API-V2-USD\",\n      \"authorization\":\"\",\n      \"webhook_url\":\"https://webhook.site/c30917eb-812e-4305-bc5c-085b998f57aa\",\n      \"customer\":{\n         \"name\":\"Angel Gonzalez\",\n         \"email\":\"agonzalez@greenpay.me\",\n         \"identification\":\"124444\",\n         \"billingAddress\":{\n            \"country\":\"CR\",\n            \"province\":\"Nombre de la provincia\",\n            \"city\":\"Ciudad\",\n            \"street1\":\"Dirección Calle 1\",\n            \"street2\":\"Dirección Calle 2\",\n            \"zip\":\"10801\"\n         },\n         \"shippingAddress\":{\n            \"country\":\"CR\",\n            \"province\":\"Nombre de la provincia\",\n            \"city\":\"Ciudad\",\n            \"street1\":\"Dirección Calle 1\",\n            \"street2\":\"Dirección Calle 2\",\n            \"zip\":\"10801\"\n         }\n      },\n      \"entity_response\":\"\",\n      \"orderReference\":\"API-V2-CRC-4791\"\n   }\n}\n}\n"}],"_postman_id":"4de6b20f-47f1-45d9-b3fe-9f0f98c6a152"}],"id":"6432edfb-65a7-4cdd-93ea-4168864b1ae8","description":"<p>Los siguientes métodos son utilizados para 3DS y liquidación de transacciones con 3DS</p>\n<p>Puede revisar el ejemplo de código creado con NodeJS y Javascript en nuestro repositorio de código <a href=\"https://bitbucket.org/greeenpay/3ds-checkout-v2-nodejs/src/main/\">Ejemplo 3DS API</a></p>\n","_postman_id":"6432edfb-65a7-4cdd-93ea-4168864b1ae8"},{"name":"Token Payment","item":[{"name":"checkout payment with token","id":"66fd379f-f4ee-4c63-a7f3-7f0ce5900ac9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"secret\": \"{{Secret provisto por GreenPay}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"terminal\": \"\",\n    \"amount\": 176,\n    \"currency\": \"CRC\",\n    \"description\": \"Compra producto 912\",\n    \"orderReference\": \"compra-token-19-CRC-626\",\n    \"token\": \"8a655ae0-34c3-11ef-91b4-6b798695d25d\",\n    \"additional\": {\n        \"customer\": {\n            \"email\": \"agonzalez@greenpay.me\",\n            \"name\": \"Angel Gonzalez\",\n            \"billingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Alajuela\",\n                \"city\": \"Alajuela\"\n            }\n        }\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenPayment","description":"<h1 id=\"pago-con-token--api-v2\">Pago con Token – API V2</h1>\n<p>Este endpoint permite realizar un pago/autorización utilizando un token de tarjeta generado previamente mediante el proceso de tokenización.</p>\n<hr />\n<h2 id=\"paso-previo-tokenización-de-la-tarjeta\">Paso Previo: Tokenización de la Tarjeta</h2>\n<p>Antes de poder realizar un pago con token, es necesario haber tokenizado la tarjeta del cliente utilizando el endpoint de tokenización.</p>\n<ul>\n<li><p>Obtendrás el valor importante:</p>\n</li>\n<li><p>token: Token de la tarjeta generado por GreenPay.</p>\n</li>\n</ul>\n<p>Guarda el valor de token, ya que será requerido para realizar el pago con token.</p>\n<hr />\n<h2 id=\"endpoint-de-pago-con-token\">Endpoint de Pago con Token</h2>\n<ul>\n<li><p>Método: POST</p>\n</li>\n<li><p>Sandbox: <a href=\"https://checkoutv2.greenpaysbx.me/tokenPayment\">https://checkoutv2.greenpaysbx.me/tokenPayment</a></p>\n</li>\n<li><p>Producción: <a href=\"https://checkoutv2.greenpay.me/tokenPayment\">https://checkoutv2.greenpay.me/tokenPayment</a></p>\n</li>\n<li><p>Requiere conexión segura: Sí, bajo TLS 1.2.</p>\n</li>\n</ul>\n<hr />\n<h3 id=\"body-json\">Body (JSON)</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"merchantId\": \"6e792b4c-1f95-4895-9434-d6d4aa38d491\",\n  \"terminal\": \"b1249250-e620-11ee-a8be-d1e162aad25c\",\n  \"amount\": 10.26,\n  \"currency\": \"USD\",\n  \"description\": \"Pago de orden 12345\",\n  \"orderReference\": \"orden-12345\",\n  \"token\": \"ecd78460-9318-11ef-8a48-19ee98944b83\",\n  \"additional\": {\n    \"customer\": {\n      \"name\": \"John Doe\",\n      \"email\": \"john.doe@email.com\",\n      \"billingAddress\": {\n        \"country\": \"CR\",\n        \"province\": \"San Jose\",\n        \"city\": \"San Jose\",\n        \"street1\": \"Calle 1\",\n        \"street2\": \"Apt 2\",\n        \"zip\": \"10101\"\n      },\n      \"shippingAddress\": {\n        \"country\": \"CR\",\n        \"city\": \"San Jose\",\n        \"street1\": \"Calle 1\",\n        \"street2\": \"Apt 2\",\n        \"zip\": \"10101\"\n      }\n    },\n    \"products\": [\n      {\n        \"description\": \"Producto 1\",\n        \"skuId\": \"SKU123\",\n        \"quantity\": 1,\n        \"price\": 10.26,\n        \"type\": \"servicio\"\n      }\n    ]\n  }\n}\n\n</code></pre>\n<h3 id=\"campos-obligatorios-del-request\">Campos obligatorios del request</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n<th>Restricciones / Ejemplo</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>merchantId</td>\n<td>String</td>\n<td>Identificador único del comercio (GreenPay)</td>\n<td>Sí</td>\n<td>UUID</td>\n</tr>\n<tr>\n<td>terminal</td>\n<td>String</td>\n<td>Terminal asignado por GreenPay</td>\n<td>Sí</td>\n<td>UUID</td>\n</tr>\n<tr>\n<td>amount</td>\n<td>Number</td>\n<td>Monto a cobrar</td>\n<td>Sí</td>\n<td>Dos decimales, ej: 10.26</td>\n</tr>\n<tr>\n<td>currency</td>\n<td>String</td>\n<td>Moneda (ISO 4217: USD o CRC)</td>\n<td>Sí</td>\n<td>3 caracteres</td>\n</tr>\n<tr>\n<td>description</td>\n<td>String</td>\n<td>Descripción de la orden</td>\n<td>Sí</td>\n<td>5-200 caracteres</td>\n</tr>\n<tr>\n<td>orderReference</td>\n<td>String</td>\n<td>Identificador único de la orden</td>\n<td>Sí</td>\n<td>5-100 caracteres</td>\n</tr>\n<tr>\n<td>token</td>\n<td>String</td>\n<td>Token de la tarjeta generado en tokenización</td>\n<td>Sí</td>\n<td></td>\n</tr>\n<tr>\n<td>additional.customer.name</td>\n<td>String</td>\n<td>Nombre del cliente</td>\n<td>Sí</td>\n<td>min 1 caracter</td>\n</tr>\n<tr>\n<td>additional.customer.email</td>\n<td>String</td>\n<td>Correo electrónico del cliente</td>\n<td>Sí</td>\n<td>min 5 caracteres, email válido</td>\n</tr>\n<tr>\n<td>additional.customer.billingAddress.country</td>\n<td>String</td>\n<td>País (ISO 3166-1 alpha-2)</td>\n<td>Sí</td>\n<td>2 caracteres, ej: CR</td>\n</tr>\n<tr>\n<td>additional.customer.billingAddress.province</td>\n<td>String</td>\n<td>Provincia</td>\n<td>Sí</td>\n<td>2-50 caracteres</td>\n</tr>\n<tr>\n<td>additional.customer.billingAddress.city</td>\n<td>String</td>\n<td>Ciudad</td>\n<td>Sí</td>\n<td>2-50 caracteres</td>\n</tr>\n<tr>\n<td>additional.customer.billingAddress.street1</td>\n<td>String</td>\n<td>Dirección 1</td>\n<td>Sí</td>\n<td>2-200 caracteres</td>\n</tr>\n<tr>\n<td>additional.customer.billingAddress.street2</td>\n<td>String</td>\n<td>Dirección 2</td>\n<td>Sí</td>\n<td>2-200 caracteres</td>\n</tr>\n<tr>\n<td>additional.customer.billingAddress.zip</td>\n<td>String</td>\n<td>Código postal</td>\n<td>Sí</td>\n<td>2-10 caracteres</td>\n</tr>\n<tr>\n<td>additional.customer.shippingAddress.country</td>\n<td>String</td>\n<td>País (ISO 3166-1 alpha-2)</td>\n<td>Sí</td>\n<td>2 caracteres, ej: CR</td>\n</tr>\n<tr>\n<td>additional.customer.shippingAddress.city</td>\n<td>String</td>\n<td>Ciudad</td>\n<td>Sí</td>\n<td>2-50 caracteres</td>\n</tr>\n<tr>\n<td>additional.customer.shippingAddress.street1</td>\n<td>String</td>\n<td>Dirección 1</td>\n<td>Sí</td>\n<td>2-200 caracteres</td>\n</tr>\n<tr>\n<td>additional.customer.shippingAddress.street2</td>\n<td>String</td>\n<td>Dirección 2</td>\n<td>Sí</td>\n<td>2-200 caracteres</td>\n</tr>\n<tr>\n<td>additional.customer.shippingAddress.zip</td>\n<td>String</td>\n<td>Código postal</td>\n<td>Sí</td>\n<td>2-10 caracteres</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"productos-opcional\">Productos (Opcional)</h3>\n<p>El campo <code>products</code> dentro de additional es opcional.</p>\n<p>Si se incluye la key <code>products</code>, todos los campos de cada producto son obligatorios.</p>\n<p>Ejemplo de uso de productos:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">\"products\": [\n  {\n    \"description\": \"Producto 1\",\n    \"skuId\": \"SKU123\",\n    \"quantity\": 1,\n    \"price\": 10.26,\n    \"type\": \"servicio\"\n  }\n]\n\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n<th>Restricciones / Ejemplo</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>description</td>\n<td>String</td>\n<td>Descripción del producto</td>\n<td>Sí</td>\n<td>2-50 caracteres</td>\n</tr>\n<tr>\n<td>skuId</td>\n<td>String</td>\n<td>SKU del producto</td>\n<td>Sí</td>\n<td>2-50 caracteres</td>\n</tr>\n<tr>\n<td>quantity</td>\n<td>Integer</td>\n<td>Cantidad</td>\n<td>Sí</td>\n<td></td>\n</tr>\n<tr>\n<td>price</td>\n<td>Decimal</td>\n<td>Precio unitario</td>\n<td>Sí</td>\n<td>Dos decimales, ej: 10.20</td>\n</tr>\n<tr>\n<td>type</td>\n<td>String</td>\n<td>Tipo de producto</td>\n<td>Sí</td>\n<td>2-50 caracteres</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"ejemplo-de-respuesta-exitosa\">Ejemplo de Respuesta Exitosa</h2>\n<p>HTTP 200</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 200,\n  \"orderId\": \"compra-token-19-CRC-185\",\n  \"authorization\": \"831000\",\n  \"amount\": 480,\n  \"currency\": \"USD\",\n  \"token\": \"ecd78460-9318-11ef-8a48-19ee98944b83\",\n  \"internalRef\": 12713163835292,\n  \"transactionId\": \"8b666759-555e-48dd-bfbf-2ef4123f37f9\",\n  \"errors\": [],\n  \"last4\": \"1815\",\n  \"brand\": \"Mastercard\"\n}\n\n</code></pre>\n<p>&gt; El campo <code>authorization</code> es el código de autorización bancaria de la transacción.</p>\n<hr />\n<h2 id=\"ejemplo-de-respuesta-fallida\">Ejemplo de Respuesta Fallida</h2>\n<p>HTTP diferente de 200</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 500,\n  \"orderId\": \"compra-token-19-CRC-776\",\n  \"authorization\": null,\n  \"amount\": 43,\n  \"currency\": \"CRC\",\n  \"token\": null,\n  \"internalRef\": 9431670795786,\n  \"transactionId\": \"41d7a4ed-1030-495e-ae35-ac32e667a4fa\",\n  \"errors\": [\n    \"Fondos insuficientes\"\n  ]\n}\n\n</code></pre>\n<hr />\n<h2 id=\"webhook-de-respuesta\">Webhook de Respuesta</h2>\n<p>⚡ ¿Cómo funciona el Webhook?</p>\n<p>La URL del webhook debe ser configurada previamente desde el dashboard de GreenPay.</p>\n<p>Para este endpoint de pago con token, la respuesta será enviada a la URL raíz del webhook que hayas configurado para tu comercio, agregando el path /tokenPayment.</p>\n<p>Ejemplo: Si tu webhook es <a href=\"https://mywebhook.com/\">https://mywebhook.com/</a>, la respuesta del pago con token por API llegará a la url <a href=\"https://mywebhook.com/tokenPayment\">https://mywebhook.com/tokenPayment</a>.</p>\n<p>GreenPay agregará el path /tokenPayment, esa url debe existir en tu backend.</p>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-exitosa-al-webhook\">Ejemplo de respuesta exitosa al webhook</h3>\n<p>🟢 status: 200 en el campo status de la respuesta del webhook indica un pago exitoso.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 200,\n  \"orderId\": \"compra-token-19-CRC-185\",\n  \"authorization\": \"831000\",\n  \"amount\": 480,\n  \"currency\": \"USD\",\n  \"token\": \"ecd78460-9318-11ef-8a48-19ee98944b83\",\n  \"internalRef\": 12713163835292,\n  \"transactionId\": \"8b666759-555e-48dd-bfbf-2ef4123f37f9\",\n  \"errors\": [],\n  \"last4\": \"1815\",\n  \"brand\": \"Mastercard\"\n}\n\n</code></pre>\n<ul>\n<li>El campo status con valor 200 indica un pago exitoso en la respuesta del webhook.</li>\n</ul>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-fallida-al-webhook\">Ejemplo de respuesta fallida al webhook</h3>\n<p>🔴 status: 400 en el campo status de la respuesta del webhook indica un pago fallido.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 400,\n  \"orderId\": \"compra-token-19-556\",\n  \"authorization\": null,\n  \"amount\": 394,\n  \"currency\": \"CRC\",\n  \"token\": \"aecef530-2b67-11f0-88c5-f347f8450491\",\n  \"internalRef\": 3227081501494,\n  \"transactionId\": \"4d874109-79a1-4930-9e59-93ddb9ce233a\",\n  \"errors\": [\n    \"token no encontrado\"\n  ],\n  \"last4\": null,\n  \"brand\": null\n}\n\n</code></pre>\n<p>El campo status con valor diferente de 200 indica un pago fallido en la respuesta del webhook.</p>\n","urlObject":{"path":["tokenPayment"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[{"id":"ffdbb681-80d6-46ed-bfd4-c71f493f76b4","name":"Transaccion Exitosa","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"secret\": \"{{Secret provisto por GreenPay}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"terminal\": \"\",\n    \"amount\": 359,\n    \"currency\": \"CRC\",\n    \"description\": \"Compra producto 315\",\n    \"orderReference\": \"compra-token-Sept-18-CRC-433\",\n    \"token\":\"8a655ae0-34c3-11ef-91b4-6b798695d25d\",\n    \"additional\": {\n        \"customer\": {\n            \"name\": \"Jairo Bonilla\",\n            \"email\": \"agonzalez@greenpay.com\",\n            \"billingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"código postal\"\n            },\n            \"shippingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"código postal\"\n            }\n        },\n        \"products\": [{\n            \"description\": \"Descripción de producto\",\n            \"skuId\": \"Identificador único en el comercio\",\n            \"quantity\": 1,\n            \"price\": 289,\n            \"type\": \"Tipo de producto\"\n        }]\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenPayment"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": 200,\n    \"orderId\": \"compra-token-19-CRC-409\",\n    \"authorization\": \"172012\",\n    \"amount\": 116,\n    \"currency\": \"CRC\",\n    \"token\": \"8a655ae0-34c3-11ef-91b4-6b798695d25d\",\n    \"internalRef\": 3924210174186,\n    \"transactionId\": \"5ebc599a-d3ef-413b-98a9-1548388a5501\",\n    \"errors\": [],\n    \"last4\": \"9358\",\n    \"brand\": \"Visa\",\n    \"quota\": 0\n}"},{"id":"7f4a69d0-8803-4814-b11c-ba5495be30cc","name":"Transaccion Exitosa solo campos requeridos","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"secret\": \"{{Secret provisto por GreenPay}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"terminal\": \"\",\n    \"amount\": 557,\n    \"currency\": \"CRC\",\n    \"description\": \"Compra producto 417\",\n    \"orderReference\": \"compra-token-Sept-18-CRC-724\",\n    \"token\":\"8a655ae0-34c3-11ef-91b4-6b798695d25d\",\n    \"additional\": {\n        \"customer\": {\n            \"name\": \"Jairo Bonilla\",\n            \"email\": \"agonzalez@greenpay.com\",\n            \"billingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"código postal\"\n            },\n            \"shippingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Nombre de la provincia\",\n                \"city\": \"Ciudad\",\n                \"street1\": \"Dirección Calle 1\",\n                \"street2\": \"Dirección Calle 2\",\n                \"zip\": \"código postal\"\n            }\n        },\n        \"products\": [{\n            \"description\": \"Descripción de producto\",\n            \"skuId\": \"Identificador único en el comercio\",\n            \"quantity\": 1,\n            \"price\": 449,\n            \"type\": \"Tipo de producto\"\n        }]\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenPayment"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"status\": 200,\n    \"orderId\": \"compra-token-19-CRC-409\",\n    \"authorization\": \"172012\",\n    \"amount\": 116,\n    \"currency\": \"CRC\",\n    \"token\": \"8a655ae0-34c3-11ef-91b4-6b798695d25d\",\n    \"internalRef\": 3924210174186,\n    \"transactionId\": \"5ebc599a-d3ef-413b-98a9-1548388a5501\",\n    \"errors\": [],\n    \"last4\": \"9358\",\n    \"brand\": \"Visa\",\n    \"quota\": 0\n}"},{"id":"b1796b28-ae93-4c26-aaa9-12ae0f8581f9","name":"Transaccion Fallida","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"secret\": \"{{Secret provisto por GreenPay}}\",\n    \"merchantId\": \"{{Merchant ID provisto por GreenPay}}\",\n    \"terminal\": \"\",\n    \"amount\": 100,\n    \"currency\": \"CRC\",\n    \"description\": \"Compra producto 214\",\n    \"orderReference\": \"compra-token-19-CRC-657\",\n    \"token\": \"8a655ae0-34c3-11ef-91b4-6b798695d25d\",\n    \"additional\": {\n        \"customer\": {\n            \"email\": \"agonzalez@greenpay.me\",\n            \"name\": \"Angel Gonzalez\",\n            \"billingAddress\": {\n                \"country\": \"CR\",\n                \"province\": \"Alajuela\",\n                \"city\": \"Alajuela\"\n            }\n        }\n    }\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/tokenPayment"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Error: invalid currency\",\n    \"status\": \"fail\"\n}"}],"_postman_id":"66fd379f-f4ee-4c63-a7f3-7f0ce5900ac9"}],"id":"0f4463c1-894a-4f80-9bfe-9bbb131e7e23","_postman_id":"0f4463c1-894a-4f80-9bfe-9bbb131e7e23","description":""},{"name":"CheckoutForm","item":[],"id":"9f1caf05-d27f-45a4-aab1-968379e31c67","description":"<h1 id=\"checkout-form-v2\">Checkout Form V2</h1>\n<p>En este apartado encontrará información acerca del checkoutform V2 y las respuestas del callback del checkoutform con 3DS y sin 3DS.</p>\n<h2 id=\"pasos-previos-crear-una-orden-de-pago\">Pasos Previos: Crear una Orden de Pago</h2>\n<ol>\n<li>Crear la orden de pago:</li>\n</ol>\n<p>Realiza una solicitud al endpoint correspondiente para crear una orden de pago.</p>\n<ul>\n<li><p>Obtendrás dos valores importantes:</p>\n</li>\n<li><p><code>session</code>: Identificador de la sesión de la orden de pago (UUID).</p>\n</li>\n<li><p><code>token</code>: Token de seguridad para la sesión (UUID).</p>\n</li>\n</ul>\n<ol>\n<li>Redireccionar al Checkout Form:</li>\n</ol>\n<p>Una vez creada la orden de pago y obtenido el session, el siguiente paso es redireccionar al usuario al Checkout Form de GreenPay.</p>\n<p>Esto le permitirá ingresar los datos de su tarjeta de forma segura y completar el pago.</p>\n<p>Para realizar la redirección, debes tomar el valor de session y agregarlo al final de la URL del Checkout Form, como se muestra a continuación.URLs del Checkout Form:</p>\n<ul>\n<li><p><code>Sandbox: https://checkoutform.greenpaysbx.me/v2/{session}</code></p>\n</li>\n<li><p><code>Producción: https://checkout-form.greenpay.me/v2/{session}</code></p>\n</li>\n</ul>\n<p>Donde {session} es el identificador de la sesión devuelto por GreenPay V2 al generar la orden de pago.</p>\n<h2 id=\"callback\">Callback</h2>\n<p>El checkoutform puede responder con los datos de la respuesta de la transacción por medio de un callback que se envia al crear la orden de pago.</p>\n<p>Al crear la orden debe agregar el campo <code>callback</code> en el objeto de la petición.</p>\n<p>El checkoutform esta disponible para funcionar con 3DS ó sin 3DS, las respuestas del <code>callback</code> en cada caso son diferentes, a continuación se mostrará ejemplos de cada uno.</p>\n<p>El <code>callback</code> responderá a la url que agrego como callback y agregará la respuesta en base64 de la siguiente manera:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>http://localhost:3000/eyJzdGF0dXMiOjIwMCwib3JkZXJJZCI6ImNvbXByYS0yMDI0LTEwLTI4LVVTRC05MjgiLCJhdXRob3JpemF0aW9uIjoiODMxMDAwIiwiYW1vdW50IjozMSwiY3VycmVuY3kiOiJVU0QiLCJ0b2tlbiI6ImY0NjUyOGMwLTk1NGYtMTFlZi04NTAwLTI3ZjFhZDY5MWY3MSIsImludGVybmFsUmVmIjo2NTg3NDA4MTY0MjY0LCJ0cmFuc2FjdGlvbklkIjoiMTc1OGFmNzQtMzAyYy00NjAyLThmNDAtNjljMzBkZmYzOWNjIiwiZXJyb3JzIjpbXSwibGFzdDQiOiIxODE1IiwiYnJhbmQiOiJNYXN0ZXJjYXJkIiwic3RhdHVzQ29kZSI6MjAwfQ==\n\n</code></pre><h3 id=\"respuesta-del-callback-sin-3ds\">Respuesta del callback sin 3DS</h3>\n<p>Si esta usando el servicio de checkoutform V2 de GreenPay la respuesta del callback tiene la siguiente estructura.</p>\n<h4 id=\"respuesta-exitosa\">Respuesta exitosa</h4>\n<p>j</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n   \"status\":200,\n   \"orderId\":\"compra-2024-10-28-USD-928\",\n   \"authorization\":\"831000\",\n   \"amount\":31,\n   \"currency\":\"USD\",\n   \"token\":\"f46528c0-954f-11ef-8500-27f1ad691f71\",\n   \"internalRef\":6587408164264,\n   \"transactionId\":\"1758af74-302c-4602-8f40-69c30dff39cc\",\n   \"errors\":[],\n   \"last4\":\"1815\",\n   \"brand\":\"Mastercard\",\n   \"statusCode\":200,\n   \"quota\":0\n}\n\n</code></pre>\n<p>&gt; Nota Importante: Si el <code>status</code> es 200, la transacción fue exitosa.</p>\n<p>El campo <code>quota</code> es para transacciones a plazos, se establece por defecto en 0 en la respuesta. omitir este campo sino hace uso de transacciones a plazos.</p>\n<h4 id=\"respuesta-fallida\">Respuesta fallida</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n   \"status\":400,\n   \"errors\":[\n      \"Error response here\"\n   ]\n}\n\n</code></pre>\n<p>&gt; Nota Importante: Si el <code>status</code> es diferente de 200, la transacción fue fallida.</p>\n<h3 id=\"respuesta-del-callback-con-3ds\">Respuesta del callback con 3DS</h3>\n<p>Debe tener en cuenta si utiliza el servicio de checkoutform con 3DS o no, porque las respuestas del callback son diferentes.</p>\n<h4 id=\"respuesta-exitosa-1\">Respuesta exitosa</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n   \"id\":\"7364531994186889604805\",\n   \"code\":\"1ef2ab78-da43-4dcf-a3fd-889cdfa2b117\",\n   \"status\":\"AUTHENTICATION_SUCCESSFUL\",\n   \"acsTransactionId\":\"57d34b40-39d9-48da-9eb8-9c883c18e977\",\n   \"threeDSServerTransactionId\":\"e6404bc1-7ebe-4180-98d9-064f3659b8f4\",\n   \"directoryServerTransactionId\":\"02eb689f-1405-4ffc-aee0-06f6db9347bf\",\n   \"paresStatus\":\"Y\",\n   \"consumerAuthenticationInformation\":{\n      \"acsTransactionId\":\"57d34b40-39d9-48da-9eb8-9c883c18e977\",\n      \"authenticationResult\":\"0\",\n      \"authenticationStatusMsg\":\"Success\",\n      \"cavv\":\"AAIBBYNoEwAAACcKhAJkdQAAAAA=\",\n      \"indicator\":\"vbv\",\n      \"eci\":\"05\",\n      \"eciRaw\":\"05\",\n      \"paresStatus\":\"Y\",\n      \"specificationVersion\":\"2.2.0\",\n      \"threeDSServerTransactionId\":\"e6404bc1-7ebe-4180-98d9-064f3659b8f4\",\n      \"xid\":\"AAIBBYNoEwAAACcKhAJkdQAAAAA=\",\n      \"directoryServerTransactionId\":\"02eb689f-1405-4ffc-aee0-06f6db9347bf\"\n   },\n   \"error\":{\n   },\n   \"transaction\":{\n      \"id\":\"1ef2ab78-da43-4dcf-a3fd-889cdfa2b117\",\n      \"status\":\"SUCCESSFUL\",\n      \"description\":\"API-V2-USD\",\n      \"authorization\":\"831000\",\n      \"webhook_url\":\"https://webhook.site/c30917eb-812e-4305-bc5c-085b998f57aa\",\n      \"customer\":{\n         \"name\":\"Angel Gonzalez\",\n         \"email\":\"agonzalez@greenpay.me\",\n         \"identification\":\"124444\",\n         \"billingAddress\":{\n            \"country\":\"CR\",\n            \"province\":\"Nombre de la provincia\",\n            \"city\":\"Ciudad\",\n            \"street1\":\"Direccin Calle 1\",\n            \"street2\":\"Direccin Calle 2\",\n            \"zip\":\"10801\"\n         },\n         \"shippingAddress\":{\n            \"country\":\"CR\",\n            \"province\":\"Nombre de la provincia\",\n            \"city\":\"Ciudad\",\n            \"street1\":\"Direccin Calle 1\",\n            \"street2\":\"Direccin Calle 2\",\n            \"zip\":\"10801\"\n         }\n      },\n      \"entity_response\":{\n         \"_links\":{\n            \"self\":{\n               \"href\":\"/pts/v2/payments/7364532025976890104805\",\n               \"method\":\"GET\"\n            }\n         },\n         \"id\":\"7364532025976890104805\",\n         \"submitTimeUtc\":\"2025-01-09T20:06:42Z\",\n         \"status\":\"AUTHORIZED\",\n         \"reconciliationId\":\"7364532025976890104805\",\n         \"clientReferenceInformation\":{\n            \"code\":\"1ef2ab78-da43-4dcf-a3fd-889cdfa2b117\"\n         },\n         \"processorInformation\":{\n            \"approvalCode\":\"831000\",\n            \"transactionId\":\"016153570198200\",\n            \"networkTransactionId\":\"016153570198200\",\n            \"responseCode\":\"00\",\n            \"responseDetails\":\"ABC\",\n            \"avs\":{\n               \"code\":\"Y\",\n               \"codeRaw\":\"Y\"\n            },\n            \"merchantAdvice\":{\n               \"code\":\"01\",\n               \"codeRaw\":\"M001\"\n            },\n            \"consumerAuthenticationResponse\":{\n               \"code\":\"2\",\n               \"codeRaw\":\"2\"\n            },\n            \"systemTraceAuditNumber\":\"122267\",\n            \"retrievalReferenceNumber\":\"500920122267\"\n         },\n         \"paymentAccountInformation\":{\n            \"card\":{\n               \"type\":\"001\"\n            }\n         },\n         \"paymentInformation\":{\n            \"card\":{\n               \"type\":\"001\"\n            },\n            \"tokenizedCard\":{\n               \"type\":\"001\"\n            }\n         },\n         \"orderInformation\":{\n            \"amountDetails\":{\n               \"totalAmount\":\"10.00\",\n               \"authorizedAmount\":\"10.00\",\n               \"currency\":\"CRC\"\n            }\n         }\n      },\n      \"orderReference\":\"API-V2-CRC-2429\"\n   }\n}\n\n</code></pre>\n<p>&gt; Nota Importante: <code>transaction.statu</code>s debe tener el valor <code>SUCCESSFUL</code> para que la transacción 3DS se considere exitosa.</p>\n<p>Cualquier otro estado significa que la transacción no fue exitosa.</p>\n<p>&gt; Mensaje de Error: El mensaje de error se puede obtener de la respuesta con la siguiente lógica: <code>error?.message ?? error.</code></p>\n<h4 id=\"respuesta-fallida-1\">Respuesta fallida</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n   \"id\":\"7364573344956430904805\",\n   \"status\":\"COMPLETED\",\n   \"jwt\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0OThiMzVkMS0zNjliLTQxODEtYWY2OC0wY2NmNWM3ZGRkMzciLCJpYXQiOjE3MzY0NTczMzQsImlzcyI6IjVkZDgzYmYwMGU0MjNkMTQ5OGRjYmFjYSIsImV4cCI6MTczNjQ2MDkzNCwiT3JnVW5pdElkIjoiNjYwYzBhOGRkYmYzZGUwMTZkNDc4ZWIxIiwiUmVmZXJlbmNlSWQiOiJmODljMWMyZS03OWExLTQ2MjYtOTkwZC05NmNkNTYyZDFkNTIifQ.j61dk5sG_6I10VnzXb8bdjR8-LPVfcW8zNa5eREDlMs\",\n   \"referenceId\":\"f89c1c2e-79a1-4626-990d-96cd562d1d52\",\n   \"deviceDataCollectionUrl\":\"https://centinelapistag.cardinalcommerce.com/V1/Cruise/Collect\",\n   \"code\":\"efbb1068-f1d6-48e9-b00f-f94cee4c2ceb\",\n   \"transaction\":{\n      \"id\":\"efbb1068-f1d6-48e9-b00f-f94cee4c2ceb\",\n      \"status\":\"CYBS_PA_SETUP\",\n      \"description\":\"API-V2-USD\",\n      \"authorization\":\"\",\n      \"webhook_url\":\"https://webhook.site/c30917eb-812e-4305-bc5c-085b998f57aa\",\n      \"customer\":{\n         \"name\":\"Angel Gonzalez\",\n         \"email\":\"agonzalez@greenpay.me\",\n         \"identification\":\"124444\",\n         \"billingAddress\":{\n            \"country\":\"CR\",\n            \"province\":\"Nombre de la provincia\",\n            \"city\":\"Ciudad\",\n            \"street1\":\"Direccin Calle 1\",\n            \"street2\":\"Direccin Calle 2\",\n            \"zip\":\"10801\"\n         },\n         \"shippingAddress\":{\n            \"country\":\"CR\",\n            \"province\":\"Nombre de la provincia\",\n            \"city\":\"Ciudad\",\n            \"street1\":\"Direccin Calle 1\",\n            \"street2\":\"Direccin Calle 2\",\n            \"zip\":\"10801\"\n         }\n      },\n      \"entity_response\":\"\"\n   }\n}\n\n</code></pre>\n<p>&gt; Nota Importante: transaction.status debe tener el valor <code>SUCCESSFUL</code> para que la transacción 3DS se considere exitosa.</p>\n<p>Cualquier otro estado significa que la transacción no fue exitosa.</p>\n<p>&gt; Mensaje de Error: El mensaje de error se puede obtener de la respuesta con la siguiente lógica: <code>error?.message ?? error</code>.</p>\n<h2 id=\"webhook\">Webhook</h2>\n<h3 id=\"respuestas-sin-3ds\">Respuestas sin 3DS</h3>\n<p>Si su webhook configurado es el siguiente <a href=\"https://mywebhook.com/\">https://mywebhook.com/</a> la respuesta del checkoutform sin 3DS llegará a la url <a href=\"https://mywebhook.com/\">https://mywebhook.com/</a>. Esa url debe existir en su backend.</p>\n<h4 id=\"respuesta-exitosa-2\">Respuesta exitosa</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 200,\n  \"orderId\": \"API-V2-CRC-8977\",\n  \"authorization\": \"831000\",\n  \"amount\": 10,\n  \"currency\": \"USD\",\n  \"token\": \"5ec57b60-d228-11ef-94e2-9dd36b69fec6\",\n  \"internalRef\": 20363874316090,\n  \"transactionId\": \"a22275c7-e327-4282-8c2e-727a60465eb2\",\n  \"errors\": [],\n  \"last4\": \"1815\",\n  \"brand\": \"Mastercard\",\n  \"quota\": 0\n}\n\n</code></pre>\n<p>&gt; Nota Importante: Si el <code>status</code> es 200, la transacción fue exitosa.</p>\n<h4 id=\"respuesta-fallida-2\">Respuesta fallida</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 500,\n  \"orderId\": \"compra-2024-10-28-USD-842\",\n  \"authorization\": null,\n  \"amount\": 37,\n  \"currency\": \"USD\",\n  \"token\": null,\n  \"internalRef\": 239443691564,\n  \"transactionId\": \"e6afefac-5aed-4deb-96af-784241addc38\",\n  \"errors\": [\n    \"invalid PAN\"\n  ],\n  \"last4\": \"1811\",\n  \"brand\": \"Mastercard\"\n}\n\n</code></pre>\n<p>&gt; Nota Importante: Si el status es diferente de 200, la transacción fue fallida.</p>\n<h3 id=\"respuestas-con-3ds\">Respuestas con 3DS</h3>\n<p>Si su webhook configurado es el siguiente <code>https://mywebhook.com/</code> la respuesta del checkoutform con 3DS llegará a la url <code>https://mywebhook.com</code>.</p>\n<p>Esa url debe existir en su backend.</p>\n<h4 id=\"respuesta-exitosa-3\">Respuesta exitosa</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n   \"id\":\"7369694598966319804807\",\n   \"code\":\"f1795abb-4a24-47ad-839f-4a3c807dff6b\",\n   \"status\":\"AUTHENTICATION_SUCCESSFUL\",\n   \"authenticationTransactionId\":\"mtrggLeSN0o3V7cXKmk0\",\n   \"acsTransactionId\":\"dab61d0b-258e-4b82-9ea3-853319541a90\",\n   \"paresStatus\":\"Y\",\n   \"threeDSServerTransactionId\":\"22737198-70ef-4332-b83e-a30351d896b4\",\n   \"veresEnrolled\":\"Y\",\n   \"directoryServerTransactionId\":\"7d501368-4ce6-4837-9d7f-87fe8f7191be\",\n   \"error\":{\n   },\n   \"consumerAuthenticationInformation\":{\n      \"acsTransactionId\":\"dab61d0b-258e-4b82-9ea3-853319541a90\",\n      \"authenticationTransactionId\":\"mtrggLeSN0o3V7cXKmk0\",\n      \"cavv\":\"AJkBBkhgQQAAAE4gSEJydQAAAAA=\",\n      \"ecommerceIndicator\":\"vbv\",\n      \"eci\":\"05\",\n      \"eciRaw\":\"05\",\n      \"paresStatus\":\"Y\",\n      \"specificationVersion\":\"2.2.0\",\n      \"threeDSServerTransactionId\":\"22737198-70ef-4332-b83e-a30351d896b4\",\n      \"veresEnrolled\":\"Y\",\n      \"xid\":\"AJkBBkhgQQAAAE4gSEJydQAAAAA=\",\n      \"directoryServerTransactionId\":\"7d501368-4ce6-4837-9d7f-87fe8f7191be\",\n      \"acsOperatorID\":\"MerchantACS\",\n      \"acsReferenceNumber\":\"Cardinal ACS\"\n   },\n   \"transaction\":{\n      \"id\":\"f1795abb-4a24-47ad-839f-4a3c807dff6b\",\n      \"status\":\"SUCCESSFUL\",\n      \"description\":\"API-V2-USD\",\n      \"authorization\":\"831000\",\n      \"webhook_url\":\"https://webhook.site/519b5827-82b9-49f6-9e78-1785d2c4d4da\",\n      \"customer\":{\n         \"name\":\"Angel Gonzalez\",\n         \"email\":\"agonzalez@greenpay.me\",\n         \"identification\":\"124444\",\n         \"billingAddress\":{\n            \"country\":\"CR\",\n            \"province\":\"Nombre de la provincia\",\n            \"city\":\"Ciudad\",\n            \"street1\":\"Direccin Calle 1\",\n            \"street2\":\"Direccin Calle 2\",\n            \"zip\":\"10801\"\n         },\n         \"shippingAddress\":{\n            \"country\":\"CR\",\n            \"province\":\"Nombre de la provincia\",\n            \"city\":\"Ciudad\",\n            \"street1\":\"Direccin Calle 1\",\n            \"street2\":\"Direccin Calle 2\",\n            \"zip\":\"10801\"\n         }\n      },\n      \"entity_response\":{\n         \"_links\":{\n            \"self\":{\n               \"href\":\"/pts/v2/payments/7369694629396427104805\",\n               \"method\":\"GET\"\n            }\n         },\n         \"id\":\"7369694629396427104805\",\n         \"submitTimeUtc\":\"2025-01-15T19:31:03Z\",\n         \"status\":\"AUTHORIZED\",\n         \"reconciliationId\":\"7369694629396427104805\",\n         \"clientReferenceInformation\":{\n            \"code\":\"f1795abb-4a24-47ad-839f-4a3c807dff6b\"\n         },\n         \"processorInformation\":{\n            \"approvalCode\":\"831000\",\n            \"transactionId\":\"016153570198200\",\n            \"networkTransactionId\":\"016153570198200\",\n            \"responseCode\":\"00\",\n            \"responseDetails\":\"ABC\",\n            \"avs\":{\n               \"code\":\"Y\",\n               \"codeRaw\":\"Y\"\n            },\n            \"merchantAdvice\":{\n               \"code\":\"01\",\n               \"codeRaw\":\"M001\"\n            },\n            \"consumerAuthenticationResponse\":{\n               \"code\":\"2\",\n               \"codeRaw\":\"2\"\n            },\n            \"systemTraceAuditNumber\":\"801618\",\n            \"retrievalReferenceNumber\":\"501519801618\"\n         },\n         \"paymentAccountInformation\":{\n            \"card\":{\n               \"type\":\"001\"\n            }\n         },\n         \"paymentInformation\":{\n            \"card\":{\n               \"type\":\"001\"\n            },\n            \"tokenizedCard\":{\n               \"type\":\"001\"\n            }\n         },\n         \"orderInformation\":{\n            \"amountDetails\":{\n               \"totalAmount\":\"10.00\",\n               \"authorizedAmount\":\"10.00\",\n               \"currency\":\"CRC\"\n            }\n         }\n      },\n      \"orderReference\":\"API-V2-CRC-7750\"\n   }\n}\n\n</code></pre>\n<p>&gt; Nota Importante: transaction.status debe tener el valor <code>SUCCESSFUL</code> para que la transacción 3DS se considere exitosa.</p>\n<p>Cualquier otro estado significa que la transacción no fue exitosa.</p>\n<p>&gt; Mensaje de Error: El mensaje de error se puede obtener de la respuesta con la siguiente lógica: <code>error?.message ?? error</code>.</p>\n<h4 id=\"respuesta-fallida-3\">Respuesta fallida</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"id\": \"7369699260036523404805\",\n  \"code\": \"46550695-8654-4334-9e89-62fc58971936\",\n  \"status\": \"AUTHENTICATION_SUCCESSFUL\",\n  \"authenticationTransactionId\": \"oDm1ptLsYro9vmcbyZF0\",\n  \"veresEnrolled\": \"U\",\n  \"error\": {},\n  \"consumerAuthenticationInformation\": {\n    \"authenticationTransactionId\": \"oDm1ptLsYro9vmcbyZF0\",\n    \"ecommerceIndicator\": \"internet\",\n    \"proofXml\": \"&lt;AuthProof&gt;&lt;Time&gt;2025 Jan 15 19:38:46&lt;/Time&gt;&lt;DSUrl&gt;https://1centineltest.cardinalcommerce.com/maps/txns.asp&lt;/DSUrl&gt;&lt;VEReqProof&gt;&lt;Message id=\\\"na\\\"&gt;&lt;VEReq&gt;&lt;version&gt;1.0.2&lt;/version&gt;&lt;pan&gt;XXXXXXXXXXXX1815&lt;/pan&gt;&lt;Merchant&gt;&lt;acqBIN&gt;&lt;/acqBIN&gt;&lt;merID&gt;&lt;/merID&gt;&lt;/Merchant&gt;&lt;Browser&gt;&lt;accept&gt;&lt;/accept&gt;&lt;userAgent&gt;&lt;/userAgent&gt;&lt;/Browser&gt;&lt;/VEReq&gt;&lt;/Message&gt;&lt;/VEReqProof&gt;&lt;VEResProof&gt;&lt;Message id=\\\"na\\\"&gt;&lt;VERes&gt;&lt;version&gt;1.0.2&lt;/version&gt;&lt;CH&gt;&lt;enrolled&gt;U&lt;/enrolled&gt;&lt;acctID&gt;&lt;/acctID&gt;&lt;/CH&gt;&lt;url&gt;&lt;/url&gt;&lt;protocol&gt;ThreeDSecure&lt;/protocol&gt;&lt;/VERes&gt;&lt;/Message&gt;&lt;/VEResProof&gt;&lt;/AuthProof&gt;\",\n    \"ucafCollectionIndicator\": \"0\",\n    \"veresEnrolled\": \"U\"\n  },\n  \"transaction\": {\n    \"id\": \"46550695-8654-4334-9e89-62fc58971936\",\n    \"status\": \"FAILED\",\n    \"description\": \"API-V2-USD\",\n    \"authorization\": \"\",\n    \"webhook_url\": \"https://webhook.site/519b5827-82b9-49f6-9e78-1785d2c4d4da\",\n    \"customer\": {\n      \"name\": \"Angel Gonzalez\",\n      \"email\": \"agonzalez@greenpay.me\",\n      \"identification\": \"124444\",\n      \"billingAddress\": {\n        \"country\": \"CR\",\n        \"province\": \"Nombre de la provincia\",\n        \"city\": \"Ciudad\",\n        \"street1\": \"Dirección Calle 1\",\n        \"street2\": \"Dirección Calle 2\",\n        \"zip\": \"10801\"\n      },\n      \"shippingAddress\": {\n        \"country\": \"CR\",\n        \"province\": \"Nombre de la provincia\",\n        \"city\": \"Ciudad\",\n        \"street1\": \"Dirección Calle 1\",\n        \"street2\": \"Dirección Calle 2\",\n        \"zip\": \"10801\"\n      }\n    },\n    \"entity_response\": {},\n    \"orderReference\": \"API-V2-CRC-1788\"\n  }\n}\n\n</code></pre>\n<p>&gt; Nota Importante: <code>transaction.status</code> debe tener el valor <code>SUCCESSFUL</code> para que la transacción 3DS se considere exitosa. Cualquier otro estado significa que la transacción no fue exitosa.</p>\n<p>&gt; Mensaje de Error: El mensaje de error se puede obtener de la respuesta con la siguiente lógica: <code>error?.message ?? error</code>.</p>\n","_postman_id":"9f1caf05-d27f-45a4-aab1-968379e31c67"},{"name":"TokenizeForm","item":[],"id":"d0764f61-42c5-4d1b-94cc-bc5378d87e35","description":"<h1 id=\"formulario-de-tokenización-de-tarjeta\">Formulario de Tokenización de Tarjeta</h1>\n<p>Este formulario permite tokenizar una tarjeta de crédito o débito de forma segura a través de una interfaz web proporcionada por GreenPay.</p>\n<hr />\n<h2 id=\"paso-previo-crear-una-orden-de-tokenización\">Paso Previo: Crear una Orden de Tokenización</h2>\n<p>Antes de utilizar el formulario, es necesario crear una orden de tokenización mediante el endpoint correspondiente.</p>\n<ul>\n<li><p>Obtendrás los valores importantes:</p>\n</li>\n<li><p>session: Identificador de la sesión de la orden de tokenización (UUID).</p>\n</li>\n<li><p>token: Token de seguridad de la orden de tokenización.</p>\n</li>\n</ul>\n<p>Guarda estos valores, ya que serán requeridos para redireccionar al formulario y completar el proceso de tokenización.</p>\n<hr />\n<h2 id=\"consideraciones-generales\">Consideraciones Generales</h2>\n<ul>\n<li><p>El formulario de tokenización está disponible en:</p>\n</li>\n<li><p>Sandbox: <code>https://tokenization.greenpaysbx.me/</code></p>\n</li>\n<li><p>Producción: <code>https://tokenization.greenpay.me/</code></p>\n</li>\n<li><p>Es necesario contar con una sesión y token de una orden de tokenización que no haya excedido los 30 minutos de vigencia.</p>\n</li>\n<li><p>El formulario de tokenización de GreenPay solo está disponible para aplicaciones web.</p>\n</li>\n</ul>\n<hr />\n<h2 id=\"pasos-para-uso-del-formulario\">Pasos para Uso del Formulario</h2>\n<h3 id=\"1-redireccionamiento-al-formulario-de-tokenización\">1. Redireccionamiento al Formulario de Tokenización</h3>\n<p>Es fundamental redireccionar al usuario a la URL del formulario de GreenPay utilizando el identificador de sesión obtenido al crear la orden de tokenización.</p>\n<p>Este paso es obligatorio para que el usuario pueda ingresar los datos de su tarjeta de forma segura.</p>\n<ul>\n<li>Sandbox:</li>\n</ul>\n<p><code>https://tokenization.greenpaysbx.me/{session}</code></p>\n<ul>\n<li>Producción:</li>\n</ul>\n<p><code>https://tokenization.greenpay.me/{session}</code></p>\n<p>Donde {session} es el identificador de sesión obtenido al crear la orden de tokenización.</p>\n<p>&gt; Asegúrate de redireccionar exactamente a la URL proporcionada por GreenPay, incluyendo el valor de la sesión.</p>\n<hr />\n<h3 id=\"2-definir-el-parámetro-callback-al-crear-la-orden\">2. Definir el parámetro callback al crear la orden</h3>\n<p>Es imprescindible que al crear la orden de tokenización, definas el parámetro callback con la URL a la que deseas recibir la respuesta del formulario.</p>\n<p>GreenPay enviará la respuesta de la tokenización a esta URL una vez que el usuario complete el formulario.</p>\n<ul>\n<li><p>El parámetro callback debe ser una URL válida y accesible desde el navegador del usuario.</p>\n</li>\n<li><p>La respuesta será enviada a esta URL, codificada en base64 como parte del path.</p>\n</li>\n</ul>\n<p>Ejemplo de callback recibido</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>http://localhost/eyJzdGF0dXNDb2RlIjoyMDAsInJlc3VsdCI6eyJjYXJkSG9sZGVyIjoiQW5nZWwgR29uemFsZXoiLCJicmFuZCI6Ik1hc3RlcmNhcmQiLCJiaW4iOiI1NTk3MjciLCJsYXN0NCI6IjE4MTEiLCJraGFzaCI6IjU1OTcyNzY0T0lGTEVUVVlLUlREIiwidG9rZW4iOiI4MDNhYThiMC05NThkLTExZWYtOGE0OC0xOWVlOTg5NDRiODMiLCJjYXJkTWFza2VkIjoiNTU5NzI3KioqKioqMTgxMSJ9fQ==\n\n</code></pre><p>Al decodificar el base64, se obtiene un JSON como el siguiente:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"statusCode\": 200,\n  \"result\": {\n    \"cardHolder\": \"Angel Gonzalez\",\n    \"brand\": \"Visa\",\n    \"bin\": \"445653\",\n    \"last4\": \"1096\",\n    \"khash\": \"4456534XQYXTFNC7M08D\",\n    \"token\": \"c02fe570-9588-11ef-bd8e-177728d45168\",\n    \"cardMasked\": \"445653******1096\"\n  }\n}\n\n</code></pre>\n<p>&gt; El campo result.token es el valor que debe guardarse en su base de datos para identificar la tarjeta de forma segura y realizar pagos futuros con token.</p>\n<hr />\n<h2 id=\"webhook-de-respuesta\">Webhook de Respuesta</h2>\n<p>⚡ ¿Cómo funciona el Webhook?</p>\n<p>La URL del webhook debe ser configurada previamente desde el dashboard de GreenPay.</p>\n<p>Para este endpoint de tokenización de tarjeta, la respuesta será enviada a la URL raíz del webhook que hayas configurado para tu comercio, agregando el path <code>/tokenizeCard</code>.</p>\n<p>Ejemplo:</p>\n<p>Si tu webhook es <code>https://mywebhook.com/</code>, la respuesta de la tokenización por API llegará a la url <code>https://mywebhook.com/tokenizeCard</code>.</p>\n<p>GreenPay agregará el path <code>/tokenizeCard</code>, esa url debe existir en tu backend.</p>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-exitosa-al-webhook\">Ejemplo de respuesta exitosa al webhook</h3>\n<p>🟢 statusCode: 200 en el campo statusCode de la respuesta del webhook indica una tokenización exitosa.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"statusCode\": 200,\n    \"result\": {\n        \"cardHolder\": \"John Doe\",\n        \"brand\": \"Visa\",\n        \"bin\": \"455676\",\n        \"last4\": \"6446\",\n        \"khash\": \"455676SNB18A5F1T3QWC\",\n        \"token\": \"b1249250-e620-11ee-a8be-d1e162aad25c\",\n        \"cardMasked\": \"455676******6446\"\n    }\n}\n\n</code></pre>\n<ul>\n<li>El campo <code>statusCode</code> con valor 200 indica una tokenización exitosa en la respuesta del webhook.</li>\n</ul>\n<hr />\n<h3 id=\"ejemplo-de-respuesta-fallida-al-webhook\">Ejemplo de respuesta fallida al webhook</h3>\n<p>🔴 status: 400 en el campo status de la respuesta del webhook indica una tokenización fallida.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": 400,\n  \"orderId\": \"compra-token-19-556\",\n  \"authorization\": null,\n  \"amount\": 394,\n  \"currency\": \"CRC\",\n  \"token\": \"aecef530-2b67-11f0-88c5-f347f8450491\",\n  \"internalRef\": 3227081501494,\n  \"transactionId\": \"4d874109-79a1-4930-9e59-93ddb9ce233a\",\n  \"errors\": [\n    \"token no encontrado\"\n  ],\n  \"last4\": null,\n  \"brand\": null\n}\n\n</code></pre>\n<ul>\n<li>El campo status con valor diferente de 200 indica una tokenización fallida en la respuesta del webhook.</li>\n</ul>\n","_postman_id":"d0764f61-42c5-4d1b-94cc-bc5378d87e35"},{"name":"Datacollector Antifraude","item":[],"id":"2d249d84-1f70-42e2-9abf-59d0d661e128","description":"<h1 id=\"data-collector-para-transacciones-con-antifraude\">Data Collector para Transacciones con Antifraude</h1>\n<p>En este apartado encontrará información sobre cómo obtener los datos del Data Collector, un componente requerido exclusivamente para integraciones que procesan transacciones con el servicio de antifraude de Greenpay.</p>\n<p>⚠️ ¡Importante!</p>\n<p>Este paso solo es necesario si tu integración requiere y tiene habilitado el análisis de fraude.</p>\n<h2 id=\"¿qué-es-el-data-collector\">¿Qué es el Data Collector?</h2>\n<p>El Data Collector es una herramienta que utiliza Greenpay para recolectar información del dispositivo y la sesión del usuario durante una transacción. Estos datos son analizados para detectar y prevenir posibles comportamientos de fraude, añadiendo una capa de seguridad a sus pagos.La recolección de estos datos se realiza en el frontend de su aplicación (página web).</p>\n<h2 id=\"integración-del-data-collector\">Integración del Data Collector</h2>\n<p>La integración consta de dos pasos principales:</p>\n<h3 id=\"1-incluir-el-script-del-data-collector\">1. Incluir el script del Data Collector</h3>\n<p>Añada el siguiente script en el o de su página de pago.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-html\">&lt;script src=\"https://static.greenpay.me/collector/1.0.1/GDataCollector.min.js\"&gt;&lt;/script&gt;\n\n</code></pre>\n<h3 id=\"2-iniciar-el-data-collector-y-obtener-la-sesión\">2. Iniciar el Data Collector y obtener la sesión</h3>\n<p>Una vez incluido el script, debe inicializar el Data Collector para que comience a recolectar la información.</p>\n<p>El resultado de este proceso es un identificador de sesión <code>(MercSessId)</code> que deberá ser enviado en las transacciones.</p>\n<p>El método <code>GDataCollector.init()</code> recibe tres parámetros:</p>\n<ol>\n<li>Entorno: <code>'sand'</code> para Sandbox (pruebas) o <code>'prod'</code> para Producción.</li>\n<li>Parámetros adicionales: null si no hay.</li>\n<li>Función de callback: Se ejecuta al finalizar la inicialización.</li>\n</ol>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">&lt;script&gt;\n  // Elemento donde se mostrará el ID de sesión (opcional, para depuración)\n  let sessionIdDiv = document.getElementById(\"kountSession\");\n  function kountSession(params) {\n    // 1. Obtenemos el ID de sesión de Kount\n    const kountSessionId = params.MercSessId;\n    console.log(kountSessionId);\n    // 2. Mostramos el ID de sesión (opcional)\n    sessionIdDiv.innerHTML = `KOUNT SESSION ${kountSessionId}`;\n    // 3. Aquí debes almacenar kountSessionId para usarlo en el pago.\n    // Puedes guardarlo en una variable global, un campo de formulario oculto, etc.\n  }\n  // Inicializamos el Data Collector\n  GDataCollector.init(\"sand\", null, function (collector) {\n    collector.setupCallback({\n      // Se dispara cuando la recolección ha finalizado\n      \"collect-end\": kountSession,\n      // Se dispara cuando la recolección ha comenzado\n      \"collect-begin\": function () {\n        console.log(\"La recolección de datos ha comenzado.\");\n      },\n    });\n    // Inicia el proceso de recolección\n    collector.collectData();\n  });\n&lt;/script&gt;\n\n</code></pre>\n<p>El valor que necesita es el que se recibe en <code>params.MercSessId</code> dentro de la función <code>kountSession</code>.</p>\n<p>Este valor es el que se conoce como <code>kountSession</code> en la documentación de los endpoints de pago.</p>\n<h2 id=\"uso-del-kountsession-en-las-transacciones\">Uso del kountSession en las transacciones</h2>\n<p>Una vez que ha obtenido el kountSessionId, debe incluirlo en el cuerpo (body) de las solicitudes de pago a los endpoints de Autorización y Preautorización.</p>\n<p>Como se detalla en la documentación de autorización y preautorización, el objeto que se envía cifrado en base64 en el campo ed debe contener el campo <code>kountSession</code>.</p>\n<h3 id=\"ejemplo-de-objeto-antes-de-cifrar-en-base64\">Ejemplo de objeto (antes de cifrar en base64)</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"card\": {\n    \"cardHolder\": \"John Doe\",\n    \"expirationDate\": { \"month\": \"12\", \"year\": \"31\" },\n    \"cardNumber\": \"4005529999000123\",\n    \"cvc\": \"196\"\n  },\n  \"additional\": {\n    \"channelData\": { \"channel\": \"01\", \"source\": \"API_CARD\" }\n  },\n  \"kountSession\": \"AQUI_VA_EL_ID_DE_SESION_OBTENIDO\"\n}\n\n</code></pre>\n<p>Al enviar este objeto en la solicitud de pago, Greenpay podrá realizar el análisis de fraude correspondiente a la transacción.</p>\n<h2 id=\"ejemplo-completo\">Ejemplo Completo</h2>\n<p>A continuación se muestra un ejemplo HTML completo y funcional para obtener el ID de sesión del Data Collector.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-html\">&lt;html lang=\"en\"&gt;\n  &lt;head&gt;\n    &lt;meta charset=\"UTF-8\" /&gt;\n    &lt;meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /&gt;\n    &lt;title&gt;Ejemplo Data Collector&lt;/title&gt;\n  &lt;/head&gt;\n  &lt;body&gt;\n    &lt;h1 class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27;&gt;Data Collector&lt;/h1&gt;\n    &lt;div class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; class=&amp;#x27;preserveHtml&amp;#x27; id=\"kountSession\"&gt;&lt;/div&gt;\n    &lt;script src=\"https://static.greenpay.me/collector/1.0.1/GDataCollector.min.js\"&gt;&lt;/script&gt;\n    &lt;script&gt;\n      let sessionIdDiv = document.getElementById(\"kountSession\");\n      function kountSession(params) {\n        console.log(params.MercSessId);\n        sessionIdDiv.innerHTML = `KOUNT SESSION: ${params.MercSessId}`;\n        // Almacena este valor para enviarlo en tu solicitud de pago.\n      }\n      GDataCollector.init(\"sand\", null, function (collector) {\n        collector.setupCallback({\n          \"collect-end\": kountSession,\n          \"collect-begin\": function () {\n            console.log(\"Iniciando recolección de datos...\");\n          },\n        });\n        collector.collectData();\n      });\n    &lt;/script&gt;\n  &lt;/body&gt;\n&lt;/html&gt;\n\n</code></pre>\n","_postman_id":"2d249d84-1f70-42e2-9abf-59d0d661e128"},{"name":"Batch Payment","item":[{"name":"Batch Payment","id":"ecde7d1c-5177-4654-af27-f3b68e36ca79","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"authInfo\": {\n    \"secret\": \"your_secret\",\n    \"merchantId\": \"your_merchantId\",\n    \"terminal\": \"your_terminal\",\n    \"callback\": \"https://greenpaybase64.free.beeceptor.com\"\n  },\n  \"transactions\": [\n    {\n      \"paymentMethod\": {\n        \"card\": \"ewogICAgICAgICAgInRva2VuaXplIjogdHJ1ZSwKICAgICAgICAgICJjYXJkSG9sZGVyIjogIkpvaG4gRG9lIiwKICAgICAgICAgICJleHBpcmF0aW9uRGF0ZSI6IHsKICAgICAgICAgICAgIm1vbnRoIjogIjEyIiwKICAgICAgICAgICAgInllYXIiOiAiMzEiCiAgICAgICAgICB9LAogICAgICAgICAgImNhcmROdW1iZXIiOiAiNTU5NzI3MDAwMDAwMTgxNSIsCiAgICAgICAgICAiY3ZjIjogIjE5NiIKfQ==\"\n      },\n      \"details\": [\n        {\n          \"amount\": 1000,\n          \"currency\": \"USD\",\n          \"description\": \"Compra producto A\",\n          \"orderReference\": \"compra-1454455-A\",\n          \"customer\": {\n            \"name\": \"John Doe\",\n            \"email\": \"johndoe@greenpay.me\",\n            \"identification\": \"12345\",\n            \"billingAddress\": {\n              \"country\": \"CR\",\n              \"province\": \"Nombre de la provincia\",\n              \"city\": \"Ciudad\",\n              \"street1\": \"Dirección Calle 1\",\n              \"street2\": \"Dirección Calle 2\",\n              \"zip\": \"10801\"\n            },\n            \"shippingAddress\": {\n              \"country\": \"CR\",\n              \"province\": \"Nombre de la provincia\",\n              \"city\": \"Ciudad\",\n              \"street1\": \"Dirección Calle 1\",\n              \"street2\": \"Dirección Calle 2\",\n              \"zip\": \"10801\"\n            }\n          },\n          \"products\": [\n            {\n              \"description\": \"Producto A\",\n              \"skuId\": \"SKU123\",\n              \"quantity\": 1,\n              \"price\": 10000,\n              \"type\": \"servicio\"\n            }\n          ]\n        },\n        {\n          \"amount\": 2500,\n          \"currency\": \"USD\",\n          \"description\": \"Compra producto B\",\n          \"orderReference\": \"compra-1454455-B\",\n          \"customer\": {\n            \"name\": \"John Doe\",\n            \"email\": \"johndoe@greenpay.me\",\n            \"identification\": \"12345\",\n            \"billingAddress\": {\n              \"country\": \"CR\",\n              \"province\": \"Nombre de la provincia\",\n              \"city\": \"Ciudad\",\n              \"street1\": \"Dirección Calle 1\",\n              \"street2\": \"Dirección Calle 2\",\n              \"zip\": \"10801\"\n            },\n            \"shippingAddress\": {\n              \"country\": \"CR\",\n              \"province\": \"Nombre de la provincia\",\n              \"city\": \"Ciudad\",\n              \"street1\": \"Dirección Calle 1\",\n              \"street2\": \"Dirección Calle 2\",\n              \"zip\": \"10801\"\n            }\n          },\n          \"products\": [\n            {\n              \"description\": \"Producto B\",\n              \"skuId\": \"SKU124\",\n              \"quantity\": 2,\n              \"price\": 1250,\n              \"type\": \"servicio\"\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"https://checkoutv2.greenpaysbx.me/batchPayment","description":"<h1 id=\"batch-payment-api--documentación\">Batch Payment API – Documentación</h1>\n<p>Este flujo permite procesar grandes volúmenes de transacciones y más información de pagos en lotes o batch payments.A continuación se describe la estructura de datos requerida para realizar un lote de pagos, incluyendo todas las validaciones y restricciones aplicadas por el middleware de validación.</p>\n<p><strong>Sandbox</strong>: <code>https://checkoutv2.greenpaysbx.me/batchPayment</code></p>\n<p><strong>Producción</strong>: <code>https://checkoutv2.greenpay.me/batchPayment</code></p>\n<h2 id=\"consideraciones-importantes\">Consideraciones importantes</h2>\n<ol>\n<li>Por cada transacción se debe generar:</li>\n</ol>\n<ul>\n<li>a. authInfo (si se necesita para validación o firma)</li>\n<li>b. paymentMethod</li>\n<li>c. details (todos para la transacción)</li>\n</ul>\n<ol>\n<li>Cada transacción no debe superar 256 KB.</li>\n<li>Una transacción solo puede contener un máximo de 20 detalles (details).</li>\n<li>Para cada transacción debe contener un paymentMethod y al menos un detail.</li>\n<li>paymentMethod solo debe tener un objeto de pago con token o tarjeta, no puede contener ambos.</li>\n<li>Timeout del endpoint: El endpoint tiene un timeout de 30 segundos para procesar la petición completa.</li>\n<li>Tamaño del payload: Se recomienda que el payload del evento no supere los 3MB por petición para evitar problemas de timeout.</li>\n</ol>\n<hr />\n<h2 id=\"estructura-de-datos-y-validaciones\">Estructura de datos y validaciones</h2>\n<h3 id=\"objeto-principal-body\">Objeto principal: body</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>authInfo</td>\n<td>Objeto</td>\n<td>Sí</td>\n<td>Ver tabla authInfo</td>\n</tr>\n<tr>\n<td>transactions</td>\n<td>Arreglo</td>\n<td>Sí</td>\n<td>Ver tabla transactions</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"authinfo\">authInfo</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>secret</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Entre 5 y 350 caracteres</td>\n</tr>\n<tr>\n<td>merchantId</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>UUID v4 válido</td>\n</tr>\n<tr>\n<td>terminal</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>UUID v4 válido</td>\n</tr>\n<tr>\n<td>callback</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>URL válida</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"transactions-arreglo-de-objetos\">transactions (arreglo de objetos)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>paymentMethod</td>\n<td>Objeto</td>\n<td>Sí</td>\n<td>Ver tabla paymentMethod</td>\n</tr>\n<tr>\n<td>details</td>\n<td>Arreglo</td>\n<td>Sí</td>\n<td>Mínimo 1, máximo 20 elementos. Ver tabla details</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"paymentmethod-uno-de-los-siguientes\">paymentMethod (uno de los siguientes)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>card</td>\n<td>Objeto</td>\n<td>Sí (si no hay tokenGp)</td>\n<td>Ver tabla card. IMPORTANTE: Debe ser codificado en base64</td>\n</tr>\n<tr>\n<td>tokenGp</td>\n<td>Objeto</td>\n<td>Sí (si no hay card)</td>\n<td>Ver tabla tokenGp</td>\n</tr>\n</tbody>\n</table>\n</div><ul>\n<li>Nota: Solo puede estar presente uno de los dos: card o tokenGp.</li>\n<li>Nota sobre card: El objeto card completo debe ser codificado en base64 antes de ser enviado.</li>\n</ul>\n<hr />\n<h3 id=\"card\">card</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>tokenize</td>\n<td>Booleano</td>\n<td>Sí</td>\n<td>true o false</td>\n</tr>\n<tr>\n<td>cardHolder</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Nombre del titular</td>\n</tr>\n<tr>\n<td>expirationDate</td>\n<td>Objeto</td>\n<td>Sí</td>\n<td>Ver tabla expirationDate</td>\n</tr>\n<tr>\n<td>cardNumber</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Número de tarjeta</td>\n</tr>\n<tr>\n<td>cvc</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Código de seguridad</td>\n</tr>\n</tbody>\n</table>\n</div><h4 id=\"expirationdate\">expirationDate</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>month</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Mes en formato string</td>\n</tr>\n<tr>\n<td>year</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Año en formato string</td>\n</tr>\n</tbody>\n</table>\n</div><p>⚠️ IMPORTANTE:</p>\n<ul>\n<li>El objeto card completo debe ser codificado en base64 antes de ser enviado en el campo card del paymentMethod.</li>\n<li>NO se pueden agregar keys adicionales al objeto card. Debe contener únicamente los campos definidos en la tabla anterior.</li>\n<li>Debe seguir exactamente la estructura de card mencionada, sin campos extra ni modificaciones.</li>\n</ul>\n<p>📝 Ejemplo de codificación en JavaScript:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">// 1. Crear el objeto card con la estructura exacta\nconst cardObject = {\n  tokenize: true,\n  cardHolder: \"John Doe\",\n  expirationDate: {\n    month: \"12\",\n    year: \"31\"\n  },\n  cardNumber: \"5597270000001815\",\n  cvc: \"196\"\n};\n// 2. Convertir a JSON string\nconst cardJsonString = JSON.stringify(cardObject);\n// 3. Codificar en base64\nconst cardBase64 = btoa(cardJsonString);\n// 4. Resultado final para enviar\nconsole.log(cardBase64);\n// Output: \"eyJ0b2tlbml6ZSI6dHJ1ZSwiY2FyZEhvbGRlciI6IkpvaG4gRG9lIiwiZXhwaXJhdGlvbkRhdGUiOnsibW9udGgiOiIxMiIsInllYXIiOiIzMSJ9LCJjYXJkTnVtYmVyIjoiNTU5NzI3MDAwMDAwMTgxNSIsImN2YyI6IjE5NiJ9\"\n// 5. Verificar decodificación (para debugging)\nconst decodedCard = JSON.parse(atob(cardBase64));\nconsole.log(decodedCard);\n\n</code></pre>\n<h3 id=\"tokengp\">tokenGp</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Identificador del token</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"details-arreglo-de-objetos\">details (arreglo de objetos)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>amount</td>\n<td>Número</td>\n<td>Sí</td>\n<td>Mayor o igual a 1</td>\n</tr>\n<tr>\n<td>currency</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Exactamente 3 caracteres</td>\n</tr>\n<tr>\n<td>description</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Entre 5 y 200 caracteres</td>\n</tr>\n<tr>\n<td>orderReference</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Entre 5 y 100 caracteres</td>\n</tr>\n<tr>\n<td>customer</td>\n<td>Objeto</td>\n<td>Sí</td>\n<td>Ver tabla customer</td>\n</tr>\n<tr>\n<td>products</td>\n<td>Arreglo</td>\n<td>No</td>\n<td>Ver tabla products</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"customer\">customer</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Entre 5 y 100 caracteres</td>\n</tr>\n<tr>\n<td>email</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Entre 5 y 100 caracteres, debe ser un correo válido con formato estándar</td>\n</tr>\n<tr>\n<td>identification</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Entre 5 y 20 caracteres</td>\n</tr>\n<tr>\n<td>billingAddress</td>\n<td>Objeto</td>\n<td>Sí</td>\n<td>Ver tabla billingAddress</td>\n</tr>\n<tr>\n<td>shippingAddress</td>\n<td>Objeto</td>\n<td>Sí</td>\n<td>Ver tabla shippingAddress</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"billingaddress--shippingaddress\">billingAddress / shippingAddress</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>street1</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Mínimo 2 caracteres</td>\n</tr>\n<tr>\n<td>street2</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Mínimo 2 caracteres</td>\n</tr>\n<tr>\n<td>country</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Mínimo 2 caracteres</td>\n</tr>\n<tr>\n<td>city</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Mínimo 2 caracteres</td>\n</tr>\n<tr>\n<td>province</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Mínimo 2 caracteres</td>\n</tr>\n<tr>\n<td>zip</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Mínimo 2 caracteres</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"products-opcional\">products (opcional)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>¿Obligatorio?</th>\n<th>Restricciones y validaciones</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>description</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Descripción del producto</td>\n</tr>\n<tr>\n<td>skuId</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Identificador SKU del producto</td>\n</tr>\n<tr>\n<td>quantity</td>\n<td>Número</td>\n<td>Sí</td>\n<td>Cantidad del producto</td>\n</tr>\n<tr>\n<td>price</td>\n<td>Número</td>\n<td>Sí</td>\n<td>Precio del producto</td>\n</tr>\n<tr>\n<td>type</td>\n<td>Cadena</td>\n<td>Sí</td>\n<td>Tipo de producto</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"ejemplo-de-json-válido-para-batch-payment\">Ejemplo de JSON válido para batch payment</h2>\n<p>�� Nota importante: Para una solicitud batch se pueden enviar transacciones con tarjeta o token. Cada transacción puede usar un método de pago diferente, permitiendo mezclar ambos tipos en la misma solicitud.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"authInfo\": {\n    \"secret\": \"U9vbOudD7dc/PoN3mfUHgOY4+0d2ficOByYOQV2KFPQrSpyKztMhwJ+Li3+yuOwmtRofVtyiJkHKzm/VDUGbEe55AXG7D9GWHliEfRQ0p47VIy7eV0YyJ+zB99RA4lZSYiqosioyUp7r5XMqOR8VkIaie+bRYk69Z9knRgYSGkc21ArBHgeavVb4Rs+NlUE8PzbR2hYC2FvoqYr7q4YbZ3kd16mZKHsYFD+zt83FV6FeRplWPwrpfiiaXqJcma1njmnRi3LknFE1YxGNssfpDfVksMDO4TqRmfMtfTpCbj2BSuFPgau1aGTAyOl254A9XNiZYvsa/3Ae7Sbt+X/GUw==\",\n    \"merchantId\": \"5c416119-89fe-41dd-a675-50c8f22c06ee\",\n    \"terminal\": \"fa736250-d1de-4169-bb76-6b9bebdf54cc\",\n    \"callback\": \"https://greenpaybase64.free.beeceptor.com\"\n  },\n  \"transactions\": [\n    {\n      \"paymentMethod\": {\n        \"card\": \"eyJ0b2tlbml6ZSI6dHJ1ZSwiY2FyZEhvbGRlciI6IkpvaG4gRG9lIiwiZXhwaXJhdGlvbkRhdGUiOnsibW9udGgiOiIxMiIsInllYXIiOiIzMSJ9LCJjYXJkTnVtYmVyIjoiNTU5NzI3MDAwMDAwMTgxNSIsImN2YyI6IjE5NiJ9\"\n      },\n      \"details\": [\n        {\n          \"amount\": 1000,\n          \"currency\": \"USD\",\n          \"description\": \"Compra producto A\",\n          \"orderReference\": \"compra-1454455-A\",\n          \"customer\": {\n            \"name\": \"John Doe\",\n            \"email\": \"johndoe@greenpay.me\",\n            \"identification\": \"12345\",\n            \"billingAddress\": {\n              \"country\": \"CR\",\n              \"province\": \"Nombre de la provincia\",\n              \"city\": \"Ciudad\",\n              \"street1\": \"Dirección Calle 1\",\n              \"street2\": \"Dirección Calle 2\",\n              \"zip\": \"10801\"\n            },\n            \"shippingAddress\": {\n              \"country\": \"CR\",\n              \"province\": \"Nombre de la provincia\",\n              \"city\": \"Ciudad\",\n              \"street1\": \"Dirección Calle 1\",\n              \"street2\": \"Dirección Calle 2\",\n              \"zip\": \"10801\"\n            }\n          },\n          \"products\": [\n            {\n              \"description\": \"Producto A\",\n              \"skuId\": \"SKU001\",\n              \"quantity\": 1,\n              \"price\": 1000,\n              \"type\": \"physical\"\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"paymentMethod\": {\n        \"tokenGp\": {\n          \"id\": \"c9693890-5bc0-11f0-85c2-d54f78ec1484\"\n        }\n      },\n      \"details\": [\n        {\n          \"amount\": 2500,\n          \"currency\": \"USD\",\n          \"description\": \"Compra producto B\",\n          \"orderReference\": \"compra-1454455-B\",\n          \"customer\": {\n            \"name\": \"Jane Doe\",\n            \"email\": \"janedoe@greenpay.me\",\n            \"identification\": \"67890\",\n            \"billingAddress\": {\n              \"country\": \"CR\",\n              \"province\": \"Otra provincia\",\n              \"city\": \"Otra Ciudad\",\n              \"street1\": \"Otra Calle 1\",\n              \"street2\": \"Otra Calle 2\",\n              \"zip\": \"10802\"\n            },\n            \"shippingAddress\": {\n              \"country\": \"CR\",\n              \"province\": \"Otra provincia\",\n              \"city\": \"Otra Ciudad\",\n              \"street1\": \"Otra Calle 1\",\n              \"street2\": \"Otra Calle 2\",\n              \"zip\": \"10802\"\n            }\n          },\n          \"products\": [\n            {\n              \"description\": \"Producto B\",\n              \"skuId\": \"SKU002\",\n              \"quantity\": 2,\n              \"price\": 1250,\n              \"type\": \"digital\"\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}\n\n</code></pre>\n<p>📝 Nota sobre el campo card codificado en base64:El campo card en el ejemplo anterior contiene el siguiente objeto codificado en base64:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"tokenize\": true,\n  \"cardHolder\": \"John Doe\",\n  \"expirationDate\": {\n    \"month\": \"12\",\n    \"year\": \"31\"\n  },\n  \"cardNumber\": \"5597270000001815\",\n  \"cvc\": \"196\"\n}\n\n</code></pre>\n<p>Proceso de codificación:</p>\n<ol>\n<li>Crear el objeto card con la estructura completa</li>\n<li>Convertir el objeto JSON a string</li>\n<li>Codificar el string en base64</li>\n<li>Enviar el string base64 en el campo card</li>\n</ol>\n<h3 id=\"��-respuestas-del-endpoint-batchpayment\">�� Respuestas del Endpoint /batchPayment</h3>\n<h4 id=\"respuesta-fallida-código-400\">Respuesta Fallida (Código 400)</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 400,\n  \"status\": \"failed\",\n  \"message\": \"Invalid request data.\",\n  \"error\": {\n    \"errorCode\": \"0002\",\n    \"errorDetails\": \"must have required property 'email'\"\n  }\n}\n\n</code></pre>\n<p>Nota importante: Todas las respuestas fallidas tienen esta estructura. Para evitar errores, asegúrate de enviar todos los campos requeridos y seguir exactamente la estructura documentada en esta guía.</p>\n<h4 id=\"respuesta-exitosa-código-200\">Respuesta Exitosa (Código 200)</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 200,\n  \"status\": \"success\",\n  \"message\": \"Mensajes recibidos exitosamente. Se procesará cada 'detail' individualmente y se reportará su resultado.\",\n  \"summary\": {\n    \"countTransaction\": 5,\n    \"countDetail\": 5,\n    \"batchId\": \"7e44c1d5-271c-4c68-9bed-3ba5c595b055\"\n  }\n}\n\n</code></pre>\n<p>Nota importante:</p>\n<ul>\n<li>La respuesta exitosa siempre tendrá esta estructura</li>\n<li>El batchId solo aparecerá para solicitudes de batch exitosas</li>\n<li>countTransaction y countDetail indican el número de transacciones y detalles procesados</li>\n<li>El resultado de cada transacción se enviará individualmente a la URL especificada en el campo callback</li>\n<li>La URL del callback debe ser de tipo POST y existir en el backend del comercio</li>\n<li>El backend debe soportar la cantidad de solicitudes de transacción que se envíen</li>\n</ul>\n<h3 id=\"��-respuestas-que-llegan-al-callback\">�� Respuestas que Llegan al Callback</h3>\n<p>Nota importante: En las respuestas de las transacciones que llegan al callback, si te fijas, el pago con token y con tarjeta tienen diferencias en <code>paymentMethod</code>, pero la estructura general es la misma.</p>\n<h4 id=\"estructura-común-de-respuesta\">Estructura Común de Respuesta</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Descripción</th>\n<th>Ejemplo</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>Código de respuesta HTTP</td>\n<td>200 (éxito), 400 (fallo)</td>\n</tr>\n<tr>\n<td>status</td>\n<td>Estado de la transacción</td>\n<td>\"success\" o \"failed\"</td>\n</tr>\n<tr>\n<td>message</td>\n<td>Mensaje descriptivo</td>\n<td>\"Transacción exitosa\"</td>\n</tr>\n<tr>\n<td>paymentMethod</td>\n<td>Método de pago utilizado</td>\n<td>Objeto con card o tokenGp</td>\n</tr>\n<tr>\n<td>additionalData</td>\n<td>Datos adicionales de la transacción</td>\n<td>Información del cliente y transacción</td>\n</tr>\n<tr>\n<td>error</td>\n<td>Detalles del error (solo en fallos)</td>\n<td>Código y descripción del error</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h4 id=\"1-pago-exitoso-con-tarjeta-y-tokenize--true\">1. Pago Exitoso con Tarjeta y tokenize = true</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 200,\n  \"status\": \"success\",\n  \"message\": \"Transacción exitosa\",\n  \"paymentMethod\": {\n    \"card\": {\n      \"tokenize\": true,\n      \"tokenCard\": \"2a0a45b0-76e5-11f0-a830-d3cadc024e83\",\n      \"bin\": \"456897\",\n      \"brand\": \"Visa\",\n      \"cardnumber\": \"456897******8886\",\n      \"khash\": \"456897WIMPVRZQCLU0EA\",\n      \"last4\": \"8886\"\n    }\n  },\n  \"additionalData\": {\n    \"customer\": {\n      \"name\": \"John Doe\",\n      \"email\": \"johndoe@greenpay.me\",\n      \"identification\": \"12345\"\n    },\n    \"transaction\": {\n      \"id\": \"427d8118-e7c5-4ffb-82b7-3b3d3c389517\",\n      \"merchantId\": \"7c383115-80af-432e-a966-2be134d0a754\",\n      \"orderReference\": \"compra-626-1-73887820-1e81-4c99-b104-12c18f982cdd\",\n      \"terminal\": \"f8c26f02-0053-4ff6-b8b0-1edfc306bbad\",\n      \"amount\": 1000,\n      \"currency\": \"USD\",\n      \"bankApprovalCode\": \"831000\"\n    },\n    \"batchId\": \"497fbb93-fd8f-4001-b546-ddf237358cf3\"\n  }\n}\n\n</code></pre>\n<h4 id=\"2-pago-exitoso-con-tarjeta-y-tokenize--false\">2. Pago Exitoso con Tarjeta y tokenize = false</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 200,\n  \"status\": \"success\",\n  \"message\": \"Transacción exitosa\",\n  \"paymentMethod\": {\n    \"card\": {\n      \"tokenize\": false,\n      \"tokenCard\": null,\n      \"bin\": \"474581\",\n      \"brand\": \"Visa\",\n      \"cardnumber\": \"474581******3511\",\n      \"khash\": null,\n      \"last4\": \"3511\"\n    }\n  },\n  \"additionalData\": {\n    \"customer\": {\n      \"name\": \"John Doe\",\n      \"email\": \"johndoe@greenpay.me\",\n      \"identification\": \"12345\"\n    },\n    \"transaction\": {\n      \"id\": \"c7dd8f81-ea42-4c43-9130-c6f266b41228\",\n      \"merchantId\": \"7c383115-80af-432e-a966-2be134d0a754\",\n      \"orderReference\": \"compra-1325-1-d947590d-d61e-40f3-b482-74dbea7bc61c\",\n      \"terminal\": \"f8c26f02-0053-4ff6-b8b0-1edfc306bbad\",\n      \"amount\": 1000,\n      \"currency\": \"USD\",\n      \"bankApprovalCode\": \"831000\"\n    },\n    \"batchId\": \"497fbb93-fd8f-4001-b546-ddf237358cf3\"\n  }\n}\n\n</code></pre>\n<h4 id=\"3-pago-con-tarjeta-fallido\">3. Pago con Tarjeta Fallido</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 400,\n  \"status\": \"failed\",\n  \"message\": \"Formato de tarjeta inválido\",\n  \"error\": {\n    \"errorCode\": \"021\",\n    \"errorDetails\": \"Formato de tarjeta inválido\"\n  },\n  \"paymentMethod\": {\n    \"card\": {\n      \"tokenize\": null,\n      \"tokenCard\": null,\n      \"bin\": null,\n      \"last4\": null,\n      \"brand\": null,\n      \"cardnumber\": null,\n      \"khash\": null\n    }\n  },\n  \"additionalData\": {\n    \"customer\": {\n      \"name\": \"John Doe\",\n      \"email\": \"johndoe@greenpay.me\",\n      \"identification\": \"12345\"\n    },\n    \"transaction\": {\n      \"id\": \"ebbb3d11-38c4-4649-8214-66e2d89e6901\",\n      \"merchantId\": \"7c383115-80af-432e-a966-2be134d0a754\",\n      \"orderReference\": \"compra-26-2-aba2414d-ef36-4e27-b6c0-5994c8d8efbe\",\n      \"terminal\": \"f8c26f02-0053-4ff6-b8b0-1edfc306bbad\",\n      \"amount\": 2500,\n      \"currency\": \"USD\",\n      \"bankApprovalCode\": null\n    },\n    \"batchId\": \"9c83de2-962a-45f5-9a6f-ed04b4a6fe3f\"\n  }\n}\n\n</code></pre>\n<p>Nota importante: En algunas ocasiones, aunque la respuesta sea fallida, pueden aparecer campos como brand, last4, bin, pueden ser diferente de null, dependiendo de la información que se haya podido extraer de la tarjeta antes del fallo.</p>\n<h4 id=\"4-pago-exitoso-con-token\">4. Pago Exitoso con Token</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 200,\n  \"status\": \"success\",\n  \"message\": \"Transacción exitosa\",\n  \"paymentMethod\": {\n    \"tokenGp\": {\n      \"id\": \"2a0a45b0-76e5-11f0-a830-d3cadc024e83\"\n    }\n  },\n  \"additionalData\": {\n    \"customer\": {\n      \"name\": \"John Doe\",\n      \"email\": \"johndoe@greenpay.me\",\n      \"identification\": \"12345\"\n    },\n    \"transaction\": {\n      \"id\": \"2829519f-8086-4e50-8154-acb6df7129a7\",\n      \"merchantId\": \"7c383115-80af-432e-a966-2be134d0a754\",\n      \"orderReference\": \"compra-1-1-03489016-7684-428d-9cfd-e6ebef3bdf88\",\n      \"terminal\": \"f8c26f02-0053-4ff6-b8b0-1edfc306bbad\",\n      \"amount\": 1000,\n      \"currency\": \"USD\",\n      \"bankApprovalCode\": \"831000\"\n    },\n    \"batchId\": \"0655a420-93e6-44f1-9626-17be169d3f8b\"\n  }\n}\n\n</code></pre>\n<h4 id=\"5-pago-con-token-fallido\">5. Pago con Token Fallido</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 400,\n  \"status\": \"failed\",\n  \"message\": \"Pago fallido\",\n  \"error\": {\n    \"errorCode\": \"024\",\n    \"errorDetails\": \"STOLEN_LOST_CARD - Decline - Stolen or lost card.\"\n  },\n  \"paymentMethod\": {\n    \"tokenGp\": {\n      \"id\": \"2a0a45b0-76e5-11f0-a830-d3cadc024e83\"\n    }\n  },\n  \"additionalData\": {\n    \"customer\": {\n      \"name\": \"John Doe\",\n      \"email\": \"johndoe@greenpay.me\",\n      \"identification\": \"12345\"\n    },\n    \"transaction\": {\n      \"id\": \"b9c787d6-bab8-43b1-b1f8-d9fdc0d8d62d\",\n      \"merchantId\": \"7c383115-80af-432e-a966-2be134d0a754\",\n      \"orderReference\": \"compra-1-1-a00e879c-dbc6-4cfa-b80a-90dcc195ee4d\",\n      \"terminal\": \"f8c26f02-0053-4ff6-b8b0-1edfc306bbad\",\n      \"amount\": 4004,\n      \"currency\": \"USD\",\n      \"bankApprovalCode\": null\n    },\n    \"batchId\": \"af049248-e940-4482-9ad6-1347a9fbabd4\"\n  }\n}\n\n</code></pre>\n","urlObject":{"path":["batchPayment"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[],"_postman_id":"ecde7d1c-5177-4654-af27-f3b68e36ca79"}],"id":"c3b60ea5-af99-4344-8837-54f94db7a2a2","_postman_id":"c3b60ea5-af99-4344-8837-54f94db7a2a2","description":""},{"name":"Merchant","item":[{"name":"Plans","item":[{"name":"Get plans by merchant and terminal ID","id":"193a5a4b-96ec-487d-bf68-4a65451175ec","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://checkoutv2.greenpaysbx.me/merchant/d17d1cec-ae39-4a1e-b0c6-8e9192824c3f/plans/terminal/832c10f8-726b-40d3-9f92-8db34f5141f7","description":"<h2 id=\"endpoint-de-planes-del-comercio---greenpay\">Endpoint de Planes del Comercio - GreenPay</h2>\n<h3 id=\"descripción\">Descripción</h3>\n<p>Este endpoint permite obtener los planes de financiamiento asociados a un comercio (merchant) y una terminal específica. Los planes incluyen opciones de cuotas con diferentes tasas de interés y están asociados a rangos específicos de BINs de tarjetas.</p>\n<h3 id=\"url-del-endpoint\">URL del Endpoint</h3>\n<p>Sandbox (Desarrollo):</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>https://checkoutv2.greenpaysbx.me/merchant/{merchantId}/planes/terminal/{terminalId}\n\n</code></pre><p>Producción:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>https://checkoutv2.greenpay.me/merchant/{merchantId}/planes/terminal/{terminalId}\n\n</code></pre><h3 id=\"método-http\">Método HTTP</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET\n\n</code></pre><h3 id=\"parámetros-de-url\">Parámetros de URL</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n<th>Requerido</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>merchantId</td>\n<td>String</td>\n<td>ID único del comercio</td>\n<td>Sí</td>\n</tr>\n<tr>\n<td>terminalId</td>\n<td>String</td>\n<td>ID único de la terminal</td>\n<td>Sí</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-http-200\">Respuesta Exitosa (HTTP 200)</h3>\n<p>Estructura de Respuesta:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"plans\": [\n    {\n      \"id\": \"06ae4d6a-a55d-41b8-894e-be9b75c4f063\",\n      \"planName\": \"Plan 6 Meses\",\n      \"bins\": [552882, 445653],\n      \"planType\": \"CUOTAS\",\n      \"planValue\": [6, 12],\n      \"programs\": \"VISA_MASTERCARD\",\n      \"status\": 1,\n      \"createdAt\": \"2024-01-15T10:30:00Z\",\n      \"updatedAt\": \"2024-01-15T10:30:00Z\"\n    },\n    {\n      \"id\": \"1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6\",\n      \"planName\": \"Plan 12 Meses\",\n      \"bins\": [552882, 445653],\n      \"planType\": \"CUOTAS\",\n      \"planValue\": [12, 18],\n      \"programs\": \"VISA_MASTERCARD\",\n      \"status\": 1,\n      \"createdAt\": \"2024-01-15T10:30:00Z\",\n      \"updatedAt\": \"2024-01-15T10:30:00Z\"\n    }\n  ],\n  \"mergedPlans\": [\n    {\n      \"text\": \"6 cuotas\",\n      \"planValue\": \"6_06ae4d6a-a55d-41b8-894e-be9b75c4f063\",\n      \"planId\": \"06ae4d6a-a55d-41b8-894e-be9b75c4f063\",\n      \"planName\": \"Plan 6 Meses\",\n      \"planType\": \"CUOTAS\"\n    },\n    {\n      \"text\": \"12 cuotas\",\n      \"planValue\": \"12_06ae4d6a-a55d-41b8-894e-be9b75c4f063\",\n      \"planId\": \"06ae4d6a-a55d-41b8-894e-be9b75c4f063\",\n      \"planName\": \"Plan 6 Meses\",\n      \"planType\": \"CUOTAS\"\n    }\n  ],\n  \"mergedBins\": [552882, 445653]\n}\n\n</code></pre>\n<p>Campos de Respuesta:</p>\n<ul>\n<li>plans: Array - Lista de planes disponibles</li>\n<li>mergedPlans: Array - Planes procesados para mostrar en UI</li>\n<li>mergedBins: Array - BINs únicos de todos los planes</li>\n</ul>\n<h3 id=\"respuesta-fallida-http-400\">Respuesta Fallida (HTTP 400)</h3>\n<p>Ejemplo de Respuesta:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"error\": \"Merchant not found\",\n  \"status\": 400\n}\n\n</code></pre>\n<p>Posibles Causas de Error:</p>\n<ul>\n<li>Merchant ID no válido</li>\n<li>Terminal ID no válido</li>\n<li>Terminal no asociada al merchant</li>\n<li>Planes no configurados para el merchant/terminal</li>\n</ul>\n<h3 id=\"uso-de-mergedplans-para-ui\">Uso de mergedPlans para UI</h3>\n<p>IMPORTANTE: Este endpoint debe ser consultado desde el frontend. GreenPay ya envía los datos procesados para usar mergedPlans directamente en un combobox o lista desplegable.Estructura recomendada para combobox/select:</p>\n<ul>\n<li>Text para mostrar: Usar el campo <code>text</code> de <code>mergedPlans</code></li>\n<li>Value del option: Usar el campo <code>planValue</code> de <code>mergedPlans</code></li>\n</ul>\n<h3 id=\"ejemplo-de-implementación-en-frontend\">Ejemplo de Implementación en Frontend</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">// Obtener planes del comercio\nconst getMerchantPlans = async () =&gt; {\n  try {\n    const response = await fetch(\n      `${process.env.NEXT_PUBLIC_ORCHESTRATOR_URL}/merchant/${merchantId}/plans/terminal/${terminalId}`,\n      {\n        method: 'GET',\n        headers: {\n          'Content-Type': 'application/json'\n        }\n      }\n    )\n    if (!response.ok) {\n      throw new Error('Error al obtener planes')\n    }\n    const data = await response.json()\n    return data.mergedPlans // Usar directamente mergedPlans\n  } catch (error) {\n    console.error('Error:', error)\n    throw error\n  }\n}\n// Crear opciones para combobox/select\nconst createPlanOptions = (mergedPlans) =&gt; {\n  return mergedPlans.map(plan =&gt; ({\n    label: plan.text,        // Texto para mostrar\n    value: plan.planValue    // Valor del option\n  }))\n}\n// Ejemplo de combobox en React\nconst PlanSelector = () =&gt; {\n  const [plans, setPlans] = useState([])\n  useEffect(() =&gt; {\n    const loadPlans = async () =&gt; {\n      const plansData = await getMerchantPlans()\n      setPlans(plansData)\n    }\n    loadPlans()\n  }, [])\n  return (\n    &lt;select onChange={handlePlanChange}&gt;\n      &lt;option value=\"\"&gt;Seleccionar plan&lt;/option&gt;\n      {plans.map((plan) =&gt; (\n        &lt;option key={plan.planId} value={plan.planValue}&gt;\n          {plan.text}\n        &lt;/option&gt;\n      ))}\n    &lt;/select&gt;\n  )\n}\n\n</code></pre>\n<h3 id=\"procesamiento-del-planvalue\">Procesamiento del planValue</h3>\n<p>IMPORTANTE: El campo <code>planValue</code> contiene la cuota y el plan separados por guion bajo. La cuota debe parsearse a número entero, NO puede enviarse como string.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">const handlePlanSelection = (selectedPlanValue) =&gt; {\n  if (selectedPlanValue.includes('_')) {\n    const [quota, plan] = selectedPlanValue.split('_')\n    // CRÍTICO: Parsear quota a número entero\n    const quotaNumber = parseInt(quota)\n    console.log('Cuotas:', quotaNumber) // Número entero\n    console.log('Plan ID:', plan)       // String\n    // Construir objeto cardData con planes\n    const cardData = {\n      card: {\n        cardHolder: \"John Doe\",\n        expirationDate: {\n          month: \"12\",\n          year: \"31\",\n        },\n        cardNumber: \"5528820000000003\",\n        cvc: \"196\",\n      },\n      additional: { \n        channelData: { \n          channel: \"01\", \n          source: \"API_CARD\" \n        } \n      },\n      // campos requeridos para pagos con planes\n      plan: plan,           // String del plan ID\n      quota: quotaNumber,   // Número entero de cuotas\n    };\n    // Codificar en base64 para envío\n    const encodedData = btoa(JSON.stringify(cardData))\n    return encodedData\n  }\n}\n\n</code></pre>\n<h2 id=\"integración-con-procesos-de-pago\">Integración con Procesos de Pago</h2>\n<h3 id=\"inclusión-de-planes-en-datos-de-tarjeta\">Inclusión de Planes en Datos de Tarjeta</h3>\n<p>IMPORTANTE: En los procesos de pago con 3DS (enrollment y/o validate) o autorización normal, se debe enviar el quota y plan en los datos de la tarjeta que van en base64.</p>\n<h3 id=\"estructura-de-datos-de-tarjeta-con-planes\">Estructura de Datos de Tarjeta con Planes</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">// Card data\nconst cardData = {\n  card: {\n    cardHolder: \"John Doe\",\n    expirationDate: {\n      month: \"12\",\n      year: \"31\",\n    },\n    cardNumber: \"5528820000000003\",\n    cvc: \"196\",\n  },\n  additional: { \n    channelData: { \n      channel: \"01\", \n      source: \"API_CARD\" \n    } \n  },\n  // campos requeridos para pagos con planes\n  plan: \"06ae4d6a-a55d-41b8-894e-be9b75c4f063\",\n  quota: 6, // DEBE ser número entero, NO string\n};\n\n</code></pre>\n<h3 id=\"aplicación-en-diferentes-endpoints\">Aplicación en Diferentes Endpoints</h3>\n<h4 id=\"1-enrollment-3ds\">1. Enrollment 3DS</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">const enrollmentData = {\n  cardData: {\n    session: sessionId,\n    ed: encodedCardDataWithPlans // Incluye quota (número) y plan (string)\n  },\n  referenceId: referenceId,\n  transactionId: transactionId,\n  redirectURL: redirectURL\n}\n\n</code></pre>\n<h4 id=\"2-validate-3ds\">2. Validate 3DS</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">const validateData = {\n  cardData: {\n    session: sessionId,\n    ed: encodedCardDataWithPlans // Incluye quota (número) y plan (string)\n  },\n  authenticationTransactionId: authTransactionId,\n  transactionId: transactionId\n}\n\n</code></pre>\n<h4 id=\"3-autorización-normal-sin-3ds\">3. Autorización Normal (sin 3DS)</h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">const authData = {\n  cardData: {\n    session: sessionId,\n    ed: encodedCardDataWithPlans // Incluye quota (número) y plan (string)\n  }\n}\n\n</code></pre>\n<h3 id=\"validaciones-requeridas\">Validaciones Requeridas</h3>\n<ol>\n<li>BIN de Tarjeta: Verificar que el BIN de la tarjeta esté incluido en los planes disponibles</li>\n<li>Plan Válido: Confirmar que el plan seleccionado esté activo</li>\n<li>Cuotas Permitidas: Validar que el número de cuotas esté dentro del rango del plan</li>\n<li>Tipo de Datos: Asegurar que quota sea número entero y plan sea string</li>\n</ol>\n<h3 id=\"notas-de-implementación\">Notas de Implementación</h3>\n<ul>\n<li>Los campos plan y quota son obligatorios cuando se procesa un pago con planes</li>\n<li>El plan debe ser el ID del plan obtenido del endpoint de planes (string)</li>\n<li>El quota debe ser un número entero que represente el número de cuotas</li>\n<li>CRÍTICO: La cuota NO puede enviarse como string, debe parsearse con parseInt()</li>\n<li>Estos campos se incluyen en todos los procesos de pago (3DS y autorización normal)</li>\n<li>Usar mergedPlans directamente para la UI, GreenPay ya procesa los datos</li>\n</ul>\n<h3 id=\"importante\">IMPORTANTE</h3>\n<p>Revisar la documentacion con 3DS o Authorizacion, ahí se encuentra el apartado de planes de cada integración  </p>\n<p>Puede revisar los siguientes ejemplos de código  </p>\n<p><a href=\"https://bitbucket.org/greeenpay/3ds-tokenization-nextjs/src/main/\">3DS</a></p>\n<p><a href=\"https://bitbucket.org/greeenpay/checkout-v2-nodejs/src/main/\">Checkout API</a></p>\n","urlObject":{"path":["merchant","d17d1cec-ae39-4a1e-b0c6-8e9192824c3f","plans","terminal","832c10f8-726b-40d3-9f92-8db34f5141f7"],"host":["https://checkoutv2.greenpaysbx.me"],"query":[],"variable":[]}},"response":[],"_postman_id":"193a5a4b-96ec-487d-bf68-4a65451175ec"}],"id":"1112c503-ffb3-4374-b272-2a1c6f711a9d","_postman_id":"1112c503-ffb3-4374-b272-2a1c6f711a9d","description":""}],"id":"a44c5ac3-1ee0-4b54-bb44-207ff66a2357","_postman_id":"a44c5ac3-1ee0-4b54-bb44-207ff66a2357","description":""}],"event":[{"listen":"prerequest","script":{"id":"4cb80fa5-a2d7-42d9-a26a-4249ecc9498c","type":"text/javascript","packages":{},"exec":[""]}},{"listen":"test","script":{"id":"7ef34627-37a1-40b9-95a1-9ceae286c13c","type":"text/javascript","packages":{},"exec":[""]}}],"variable":[{"key":"secret","value":"{{Secret provisto por GreenPay}}","type":"string"},{"key":"merchantId","value":"{{Merchant ID provisto por GreenPay}}","type":"string"},{"key":"terminal_CRC","value":"","type":"string"},{"key":"terminal_USD","value":"","type":"string"},{"key":"orchestrator_url","value":"https://checkoutv2.greenpaysbx.me","type":"string"},{"key":"environment","value":"","type":"string"},{"key":"liszt-token","value":"","type":"string"},{"key":"GP_SESSION","value":"{{ID de sesión obtenido al momento de crear la orden de pago o tokenizacion}}","type":"string"},{"key":"GP_TOKEN","value":"{{ID de token obtenido al momento de crear la orden de pago o tokenizacion}}","type":"string"},{"key":"terminal_CYBS","value":"","type":"string"},{"key":"cybs_terminal_USD","value":"{{Terminal en USD provista por GreenPay}}","type":"string"},{"key":"cybs_terminal_CRC","value":"{{Terminal en CRC provista por GreenPay}}","type":"string"},{"key":"card_token","value":"{{Token de la tarjeta con que se realizó la transacción}}","type":"string"},{"key":"confirm-authorization-token","value":"","type":"string"},{"key":"ed","value":"{{Información de la tarjeta codificada en base64}}","type":"string"},{"key":"referenceId","value":"{{ID de referencia obtenido al momento de ejecutar el proceso PA SETUP}}","type":"string"},{"key":"transactionId","value":"{{ID de transacción obtenido al momento de ejecutar el proceso PA SETUP}}","type":"string"},{"key":"checkoutFormURL","value":"{{URL del formulario de checkout donde se ingreso la informacion de la tarjeta}}","type":"string"},{"key":"authenticationTransactionId","value":"{{ID de autenticación de la transacción obtenido al momento de ejecutar el proceso PA ENROLLMENT}}","type":"string"}]}