Servicio de verificación de tarjeta PCI
La verificación de tarjeta permite que los vendedores PCI DSS comprueben la validez de las tarjetas de pago. Tras la verificación, el vendedor puede utilizar la tarjeta para pagos que puede gestionar por su cuenta. En virtud de la directiva europea DSP2, es obligatorio autentificar al titular de la tarjeta utilizando el protocolo 3-D Secure. El servicio autentifica al titular de la tarjeta y devuelve la información de autentificación al final del proceso.
Principio general
verificación: operación que permite verificar la validez de una tarjeta. Para ello, la llamada al Web Service PCI/Charge/VerifyPaymentMethod inicia una transacción de verificación. En el marco de la DSP2, es obligatorio autentificar al titular de la tarjeta utilizando el protocolo 3-D Secure. El escenario se desarrolla de la siguiente manera:
- Llamada del Web Service PCI/Charge/VerifyPaymentMethod
- La respuesta puede ser de 2 tipos:
- AuthenticationResponseData : Esta respuesta indica que es necesario autentificar al titular. Deberá indicar el mismo PCI/Charge/VerifyPaymentMethod con el resultado de la instrucción para la autentificación 3-D Secure.
- Charge/Payment : Charge/Payment : Esta respuesta indica el fin de la verificación y que es posible consultar el resultado de la misma.
Considerando que la autentificación ocupa un lugar importante en este Web Service, detallamos su funcionamiento a continuación.
Proceso de autentificación
El servicio adopta un principio de funcionamiento que hace abstracción del protocolo subyacente para permitir una integración única y no una integración por protocolo.
La secuencia genérica de una autentificación completa se puede dividir en varias etapas:
- una llamada inicial al servicio PCI/Charge/VerifyPaymentMethod con una respuesta de tipo AuthenticationResult o AuthenticationInstruction.
- si el retorno es de tipoAuthenticationInstruction, es una operación que debe realizarse del lado del vendedor:
- creación de un iFrame visible o invisible
- en el iFrame, redirección del navegador hacia el destino con un formulario que sigue la definición presente en la instrucción
- interacción eventual con el titular de la tarjeta, o el navegador
- página de regreso del servidor remoto que emitirá un evento JavaScript que contiene el resultado de la instrucción
- intercepción del resultado de la instrucción bajo la forma de un evento JavaScript en la página principal
- nueva llamada al servicio PCI/Charge/VerifyPaymentMethod con el resultado firmado de la instrucción obtenido a través del navegador
- el servicio PCI/Charge/VerifyPaymentMethod responde de nuevo ya sea con una instrucción o un resultado
- si el retorno es de tipo RESULT, entonces este contendrá el resultado final de la autentificación y el proceso es terminado.
Diagrama detallado
El siguiente diagrama detalla un escenario de pago genérico con autentificación: la llamada inicial al servicio, una instrucción, una interacción, un resultado final de la autentificación y el fin del pago.
CLIENTE
Navegador
iFrame
Servidor Vendedor
Servidor de la Plataforma de Pago.
Servidor remoto (ejemplo: ACS)
Explicaremos las diferentes etapas de integración en los siguientes párrafos.
Integración | Etapas |
---|---|
Acciones a realizar del lado del servidor vendedor | Etapas 3 , 4 , 16 y 17 |
Acciones a realizar del lado JavaScript. | Etapas 5 , 6 , 7 y 15 |
Etapa 1 y 2: Iniciación (pago o adición de una tarjeta)
Se ha iniciado una acción de pago o registro de una tarjeta y necesita de una autentificación. El servicio PCI/Charge/VerifyPaymentMethod está listo para recibir llamadas..
Etapa 3: Etapa 3:
La solicitud inicial permite transmitir los datos necesarios para la autentificación.
Entre estos datos, es necesario ingresar cierta información relacionada con el navegador o el dispositivo móvil en el objeto device.
Esta información es principalmente técnica y debe obtenerse desde el navegador o el dispositivo móvil (en JavaScript, por ejemplo).
El objetivo es facilitar la identificación del cliente (dirección IP) y de su herramienta de pago (talla del navegador) para permitir un proceso de autentificación más acorde a su caso.
Para más información sobre este campo, consulte la documentación sobre la integración del servicio PCI/Charge/VerifyPaymentMethod.
A continuación encontrará un ejemplo que describe la solicitud inicial:
{ "currency": "EUR", "orderId":"myOrderId", "paymentForms": [ { "paymentMethodType": "CARD", "pan": "4970100000000014", "brand": "VISA", "expiryMonth": "02", "expiryYear": "22", "securityCode": "123" } ], "customer": { "email": "sample@example.com" }, "device": { "deviceType": "BROWSER", "acceptHeader": "application/json", "ip": "89.249.65.28", "javaEnabled": true, "language": "en", "colorDepth": "1", "screenHeight": 1024, "screenWidth": 768, "timezoneOffset": 0, "userAgent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0" } }
/** * I initialize the PHP SDK */ require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/keys.php'; require_once __DIR__ . '/helpers.php'; /** * Initialize the SDK * see keys.php */ $client = new Lyra\Client(); /** * I create a formToken */ $store = array("amount" => 250, "currency" => "EUR", "orderId" => uniqid("MyOrderId"), "customer" => array( "email" => "sample@example.com" )); $response = $client->post("V4/Charge/CreatePayment", $store); /* I check if there are some errors */ if ($response['status'] != 'SUCCESS') { /* an error occurs, I throw an exception */ display_error($response); $error = $response['answer']; throw new Exception("error " . $error['errorCode'] . ": " . $error['errorMessage'] ); } /* everything is fine, I extract the formToken */ $formToken = $response["answer"]["formToken"]; ?>
Etapa 4: Respuesta completa con una instrucción.
La respuesta contiene una instrucción del siguiente tipo (ejemplo con una autentificación 3DS v1 obsoleta):
{ "answer": { "id": "c82794e9-9c20-44a8-9297-b70e1e7c4006", "operationSessionId": "c7f9c8711d994aa5818f886dc995e9eb", "protocol": { "name": "THREEDS", "network": "VISA", "version": "1.0.2", "challengePreference":"NO_PREFERENCE", "simulation":false, "_type": "V4/PCI/Charge/Authenticate/Protocol" }, "value": { "instructionType": "FORM", "name": "CHALLENGE", "timeout" : "15", "target": { "element": "IFRAME", "visible": true, "width": 400, "height": 400, "_type": "V4/PCI/Charge/Authenticate/InstructionTarget" }, "http": { "method": "POST", "url": "https://acs.sg.com/1.0.2", "headers": { "Accept": "text/html" }, "body": { "termUrl": "https://pass.sample-acs.net/v1/notify/threeds/v1/pares", "MD": "eJwljEmSokAAAL8yd2O6imLVCA+oINAKCLLekALZd2ggePz0dF/ylJnEB/xAG8GQLLcRiKRoZgtWnHtkwniZfw2qontZg4mvIv2SrOOGIMERCDJ/CHSg2QMkNpqEcNt/52iDEP1/bdVYFFsyDM0BgKIOgyKp++HAQQ6CKcD93yZYyqgawK/4A6VlbYPzWv0OZu3Gj04+rf6LMlQP8db81Tm7JXBxyrM3cKIYaV7GedZVQdLkWAo6W+ufqbUMjQxLQvkUIG8k384FpmsJfG2fQ0qzI3rulyLFqkPMYD9No8B48rkcrmI59ar3Yk29l6k8EQJPDlc9p+OqPzuxhul33WZx2TvmyNBxswb2U9OmCHFhelH8WI6e3nV2xVACYrHwadbjVpKbxxjWjywfgi7EK3ZWGTMnsSl2baxnlWKWhmXuqpOXX2JBhDDUebZccWyNOagnJHKm+kgz//4OF8oyrWig5hIAw1LL7jNTTkiw76DgJDl2VXKxGc4h0O1W9e4k1b4LPeRfzsh6H4//ANdloIQ=", "paReq": "eJxVUslu2zAQ/RVBd5mLLZk2RgzSBlkOCYLGPqSXgss4VmNJDkkHdr4+pKosPXHezPDN4xvC2bHdZa/ofNN3dc4mNM+wM71tuqc6X68uC5FnPqjOql3fYZ2f0OdnElZbh3jxgObgUMIteq+eMGtsnf8RSghqDS0st7yY0WpeaKNZoamwrFpQzSvMJdyf/8IXCeNoGSdPOJAPGCmd2aouSFDm5cfNnWTVdC6AjAhadDcXkvHprKyA/EPQqRblrRpu2hX6AGRIgekPXXAnyUsK5APAwe3kNoS9XxLSjrcmpm+BpAqQLw33hxT5yHRsrFRv9vlxuq0e//6+Ut3O6XV4sFeXpb5e10BSB1gVUHLKBOO0yhhflvMlZUCGPKg2SZDllEY5I4B9mnH+vfI9A9FpFzdzkotkwycCPO7jYmJHdO8zBovexBeMx5f8n9fJUBOSdxsurFa0VJrPNqg0ZTjb2LnhJU8+D02JvoleMUEXA38CQBINGTdIxu3H6L9f8Q7HNMYj" }, "_type": "V4/PCI/Charge/Authenticate/HttpRequest" }, "_type": "V4/PCI/Charge/Authenticate/AuthenticationInstruction" }, "_type": "V4/AuthenticationResponseData" } }
El contenido se divide en:
Objeto | Función |
---|---|
id | Identificador único de la transacción de autentificación en curso. |
operationSessionId | Identificador de sesión único para la operación en curso. Tendrá que ser retransmitido a cada nueva llamada.. |
protocol | Indica qué protocolo se aplicará durante la autentificación. |
Value | Representa el resultado de la autentificación o las instrucciones a seguir. Si value es de tipo AuthenticationInstruction , se trata de una instrucción para ejecutar, si es de tipo AuthenticationResult , se trata del resultado de la autentificación. |
Etapa 5: Preparación de la página de gestión de instrucciones
Si se devolvió una instrucción durante la etapa anterior, la página que se mostrará durante este paso debe permitir:
- la configuración de un "listener" en el tipo de evento devuelto por el iframe, el cual activará un POST hacia el servidor del vendedor con el resultado de la instrucción (ver. etapa 15).
- la creación de un iFrame oculto o visible (ver etapas 6 y 7 ).
Etapa 6: Creación del iFrame
La instrucción recibida durante la etapa 4 es como sigue:
{ "instructionType": "FORM", "name": "CHALLENGE", "timeout" : "15", "target": { "element": "IFRAME", "visible": true, "width": 400, "height": 400, "_type": "V4/PCI/Charge/Authenticate/InstructionTarget" }, "http": { "method": "POST", "url": "https://acs.sg.com/1.0.2", "headers": { "Accept": "text/html" }, "body": { "termUrl": "https://pass.sample-acs.net/v1/notify/threeds/v1/pares", "MD": "eJwljEmSokAAAL8yd2O6imLVCA+oINAKCLLekALZd2ggePz0dF/ylJnEB/xAG8GQLLcRiKRoZgtWnHtkwniZfw2qontZg4mvIv2SrOOGIMERCDJ/CHSg2QMkNpqEcNt/52iDEP1/bdVYFFsyDM0BgKIOgyKp++HAQQ6CKcD93yZYyqgawK/4A6VlbYPzWv0OZu3Gj04+rf6LMlQP8db81Tm7JXBxyrM3cKIYaV7GedZVQdLkWAo6W+ufqbUMjQxLQvkUIG8k384FpmsJfG2fQ0qzI3rulyLFqkPMYD9No8B48rkcrmI59ar3Yk29l6k8EQJPDlc9p+OqPzuxhul33WZx2TvmyNBxswb2U9OmCHFhelH8WI6e3nV2xVACYrHwadbjVpKbxxjWjywfgi7EK3ZWGTMnsSl2baxnlWKWhmXuqpOXX2JBhDDUebZccWyNOagnJHKm+kgz//4OF8oyrWig5hIAw1LL7jNTTkiw76DgJDl2VXKxGc4h0O1W9e4k1b4LPeRfzsh6H4//ANdloIQ=", "paReq": "eJxVUslu2zAQ/RVBd5mLLZk2RgzSBlkOCYLGPqSXgss4VmNJDkkHdr4+pKosPXHezPDN4xvC2bHdZa/ofNN3dc4mNM+wM71tuqc6X68uC5FnPqjOql3fYZ2f0OdnElZbh3jxgObgUMIteq+eMGtsnf8RSghqDS0st7yY0WpeaKNZoamwrFpQzSvMJdyf/8IXCeNoGSdPOJAPGCmd2aouSFDm5cfNnWTVdC6AjAhadDcXkvHprKyA/EPQqRblrRpu2hX6AGRIgekPXXAnyUsK5APAwe3kNoS9XxLSjrcmpm+BpAqQLw33hxT5yHRsrFRv9vlxuq0e//6+Ut3O6XV4sFeXpb5e10BSB1gVUHLKBOO0yhhflvMlZUCGPKg2SZDllEY5I4B9mnH+vfI9A9FpFzdzkotkwycCPO7jYmJHdO8zBovexBeMx5f8n9fJUBOSdxsurFa0VJrPNqg0ZTjb2LnhJU8+D02JvoleMUEXA38CQBINGTdIxu3H6L9f8Q7HNMYj" }, "_type": "V4/PCI/Charge/Authenticate/HttpRequest" }, "_type": "V4/PCI/Charge/Authenticate/AuthenticationInstruction" }
Las distintas propiedades del iFrame que se va a crear se encuentran en el elemento **target**:
"target": { "element": "IFRAME", "visible": true, "width": 400, "height": 400 }
Si debe ser visible (atributo **value.target.visible** en **true**), entonces crea el iFrame con estos parámetros (anchura según **width** y altura según **height**) y muéstralo, en caso contrario crea un iframe oculto.
Gestión del tiempo de espera de visualización del iframe
También se debe gestionar la duración de visualización máxima del iframe si el atributo value.timeout está presente en la instrucción (time-out establecido en segundos). Para ello, se debe autorizar la activación de un evento LYRA_AUTH_INSTRUCTION_RESULT con los siguientes valores:
{ eventName: 'LYRA_AUTH_INSTRUCTION_RESULT', value: { name: "Add here the instruction name you have received in the answer", value: 'TIMEOUT', protocol: "Add here the protocol object you have received in the answer" } }
Ejemplo de implementación:
function createInstructionIframe(instruction) { // Get instruction container element container = document.getElementById('instructionContainer'); // Clean instruction container container.innerHTML = '; // Create iframe element var iframe = document.createElement('iframe'); iframe.id = 'instructionIframe'; iframe.name = 'instructionIframe'; iframe.src = 'about:blank'; iframe.style.width = instruction.value.target.width+"px"; iframe.style.height = instruction.value.target.height+"px"; iframe.style.visibility = instruction.value.target.visible ? 'visible' : 'hidden'; // Handle timeout if(instruction.value.timeout){ setTimeout(() => { const instructionResultTimeout = { eventName: 'LYRA_AUTH_INSTRUCTION_RESULT', value: { name: instruction.value.name, value: 'TIMEOUT', protocol: { name: instruction.protocol.name, version: instruction.protocol.version, network: instruction.protocol.network, challengePreference: instruction.protocol.challengePreference, simulation: instruction.protocol.simulation }, }, }; window.postMessage(JSON.stringify(instructionResultTimeout), '*'); }, instruction.value.timeout * 1000); } // Add iframe to container container.appendChild(iframe); // Create form to post var form = document.createElement('form'); form.id = 'instructionForm'; form.name = 'instructionForm'; form.target = 'instructionIframe'; form.method = instruction.value.http.method; form.action = instruction.value.http.url; form.style = 'visibility: hidden'; // Create form body Object.keys(instruction.value.http.body).forEach(function (name) { form.innerHTML += '<input name="' + name + '" value="' + instruction.value.http.body[name] + '">'; }); var body = document.createElement('form'); // Add form to container container.appendChild(form); // Triger form submit form.submit(); }
Etapa 7: Transmisión del formulario
Una vez que se haya creado el iFrame, se debe completar con un formulario siguiendo las instrucciones de la etiqueta ‘http’:
"http": { "method": "POST", "url": "https://acs.sg.com/1.0.2", "headers": { "Accept": "text/html" }, "body": { "termUrl": "https://pass.sample-acs.net/v1/notify/threeds/v1/pares", "MD": "eJwljEmSokAAAL8yd2O6imLVCA+oINAKCLLekALZd2ggePz0dF/ylJnEB/xAG8GQLLcRiKRoZgtWnHtkwniZfw2qontZg4mvIv2SrOOGIMERCDJ/CHSg2QMkNpqEcNt/52iDEP1/bdVYFFsyDM0BgKIOgyKp++HAQQ6CKcD93yZYyqgawK/4A6VlbYPzWv0OZu3Gj04+rf6LMlQP8db81Tm7JXBxyrM3cKIYaV7GedZVQdLkWAo6W+ufqbUMjQxLQvkUIG8k384FpmsJfG2fQ0qzI3rulyLFqkPMYD9No8B48rkcrmI59ar3Yk29l6k8EQJPDlc9p+OqPzuxhul33WZx2TvmyNBxswb2U9OmCHFhelH8WI6e3nV2xVACYrHwadbjVpKbxxjWjywfgi7EK3ZWGTMnsSl2baxnlWKWhmXuqpOXX2JBhDDUebZccWyNOagnJHKm+kgz//4OF8oyrWig5hIAw1LL7jNTTkiw76DgJDl2VXKxGc4h0O1W9e4k1b4LPeRfzsh6H4//ANdloIQ=", "paReq": "eJxVUslu2zAQ/RVBd5mLLZk2RgzSBlkOCYLGPqSXgss4VmNJDkkHdr4+pKosPXHezPDN4xvC2bHdZa/ofNN3dc4mNM+wM71tuqc6X68uC5FnPqjOql3fYZ2f0OdnElZbh3jxgObgUMIteq+eMGtsnf8RSghqDS0st7yY0WpeaKNZoamwrFpQzSvMJdyf/8IXCeNoGSdPOJAPGCmd2aouSFDm5cfNnWTVdC6AjAhadDcXkvHprKyA/EPQqRblrRpu2hX6AGRIgekPXXAnyUsK5APAwe3kNoS9XxLSjrcmpm+BpAqQLw33hxT5yHRsrFRv9vlxuq0e//6+Ut3O6XV4sFeXpb5e10BSB1gVUHLKBOO0yhhflvMlZUCGPKg2SZDllEY5I4B9mnH+vfI9A9FpFzdzkotkwycCPO7jYmJHdO8zBovexBeMx5f8n9fJUBOSdxsurFa0VJrPNqg0ZTjb2LnhJU8+D02JvoleMUEXA38CQBINGTdIxu3H6L9f8Q7HNMYj" }, "_type": "V4/PCI/Charge/Authenticate/HttpRequest" }
- la propiedad method indica el verbo HTTP que se debe asociar al formulario.
- url indica a que servidor debe apuntar la acción de formulario
- los encabezados de la solicitud http en headers
- los parámetros de formulario en body (aquí, por ejemplo, termUrl, MD y paReq)
Una vez que el formulario ha sido generado y colocado en el iframe, todo lo que queda es activar el envío a la carga de la página.
Si se alcanza el tiempo de espera configurado en el código de creación de iframe, el cliente de escucha recogerá el evento de tipo LYRA_AUTH_INSTRUCTION_RESULT , cuyos detalles se describen en la etapa 15. Esto permitirá que el proceso continúe y tenga un resultado final.
Etapas de la 8 a la 14 : autentificación del usuario
Una vez el formulario publicado, el código del banco emisor tomará el control del proceso con la finalidad de permitir la autentificación segura (silenciosa o interactiva). Al final de esta etapa, el evento LYRA_AUTH_INSTRUCTION_RESULT se emite desde el iFrame para indicar el final del proceso. Ejemplo:
{ "eventName": "LYRA_AUTH_INSTRUCTION_RESULT", "value" : { "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", "name": "CHALLENGE", "protocol": { "name": "THREEDS", "version": "2.1.0", "network": "VISA", "challengePreference" : "NO_PREFERENCE", "simulation": "false" } } }
Etapa 15: Recuperación del evento JavaScript emitido en la etapa 14
Con el fin de interpretar el evento LYRA_AUTH_INSTRUCTION_RESULT, es necesario configurar un listener en la página principal. Este último debe ser capaz de analizar el código JSON y puede escribirse como:
window.addEventListener('message', function (messageEvent) { var data = messageEvent.data; try { var messageData = JSON.parse(data); if (messageData.eventName === 'LYRA_AUTH_INSTRUCTION_RESULT') { try { // callback call with messageData.value content container = document.getElementById('instructionContainer'); var form = document.createElement('form'); form.method = 'POST'; form.action = "https://myhost.com/payment/authentication/result.php"; form.style = 'visibility: hidden'; form.innerHTML += "<input name='messageData' value='" + data + "'>"; var body = document.createElement('form'); container.appendChild(form); form.submit(); } catch (err) { // error callback call } finally { // always close the iFrame/popin container = document.getElementById('instructionContainer'); container.remove(); } } } catch (err) { // process eventual exceptions during callbacks } }, false);
Es conveniente enviar enseguida esta información al servidor del vendedor.
Etapa 16: Regresa al servidor vendedor el resultado de la instrucción.
Una vez, recuperado el resultado de instrucción del servidor del vendedor, el resultado será devuelto a través de una nueva llamada al servicio Charge/Authenticate. La solicitud debe contener el objeto instructionResult y el ID de sesion operationSessionId recibido en la respuesta de la etapa 4 :
{ "instructionResult": { "name" : "CHALLENGE", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", "protocol" : { "name" : "THREEDS", "network": "VISA", "version" : "1.0.2", "challengePreference": "NO_PREFERENCE", "simulation": false } }, "operationSessionId": "c7f9c8711d994aa5818f886dc995e9eb" }
/** * I initialize the PHP SDK */ require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/keys.php'; require_once __DIR__ . '/helpers.php'; /** * Initialize the SDK * see keys.php */ $client = new Lyra\Client(); /** * I create a formToken */ $store = array("amount" => 250, "currency" => "EUR", "orderId" => uniqid("MyOrderId"), "customer" => array( "email" => "sample@example.com" )); $response = $client->post("V4/Charge/CreatePayment", $store); /* I check if there are some errors */ if ($response['status'] != 'SUCCESS') { /* an error occurs, I throw an exception */ display_error($response); $error = $response['answer']; throw new Exception("error " . $error['errorCode'] . ": " . $error['errorMessage'] ); } /* everything is fine, I extract the formToken */ $formToken = $response["answer"]["formToken"]; ?>
Etapa 17: Recepción de la respuesta del servidor de la plataforma de pago.
Como en la etapa 4, el servidor del vendedor recibe una nueva respuesta, que puede ser la definitiva (RESULT), o bien solicita una nueva instrucción (INSTRUCTION). En este último caso, el flujo se reanuda en la etapa 5. Ejemplo de un mensaje final:
{ "answer": { "shopId": "33148340", "orderCycle": "CLOSED", "orderStatus": "PAID", "serverDate": "2020-03-23T14:31:14+00:00", "orderDetails": { "orderTotalAmount": 0, "orderEffectiveAmount": 0, "orderCurrency": "EUR", "mode": "TEST", "orderId": "myOrder", "_type": "V4/OrderDetails" }, "customer": { "billingDetails": { "address": null, "category": null, "cellPhoneNumber": null, "city": null, "country": null, "district": null, "firstName": null, "identityCode": null, "language": "FR", "lastName": null, "phoneNumber": null, "state": null, "streetNumber": null, "title": null, "zipCode": null, "_type": "V4/Customer/BillingDetails" }, "email": "sample@example.com", "reference": null, "shippingDetails": { "address": null, "address2": null, "category": null, "city": null, "country": null, "deliveryCompanyName": null, "district": null, "firstName": null, "identityCode": null, "lastName": null, "legalName": null, "phoneNumber": null, "shippingMethod": null, "shippingSpeed": null, "state": null, "streetNumber": null, "zipCode": null, "_type": "V4/Customer/ShippingDetails" }, "extraDetails": { "browserAccept": null, "fingerPrintId": null, "ipAddress": "10.33.160.29", "browserUserAgent": "PostmanRuntime/7.23.0", "_type": "V4/Customer/ExtraDetails" }, "shoppingCart": { "insuranceAmount": null, "shippingAmount": null, "taxAmount": null, "cartItemInfo": null, "_type": "V4/Customer/ShoppingCart" } }, "transactions": [ { "shopId": "33148340", "uuid": "ca83e404cd134bef95dff577927d2e09", "amount": 0, "currency": "EUR", "paymentMethodType": "CARD", "paymentMethodToken": null, "status": "PAID", "detailedStatus": "ACCEPTED", "operationType": "VERIFICATION", "effectiveStrongAuthentication": "DISABLED", "creationDate": "2020-03-23T14:31:13+00:00", "errorCode": null, "errorMessage": null, "detailedErrorCode": null, "detailedErrorMessage": null, "metadata": null, "transactionDetails": { "liabilityShift": "NO", "effectiveAmount": 0, "effectiveCurrency": "EUR", "creationContext": "VERIFICATION", "cardDetails": { "paymentSource": "EC", "manualValidation": "NO", "expectedCaptureDate": null, "effectiveBrand": "VISA", "pan": "497010XXXXXX0055", "expiryMonth": 11, "expiryYear": 2021, "country": "FR", "issuerCode": 17807, "issuerName": "BP Occitane", "effectiveProductCode": null, "legacyTransId": "923865", "legacyTransDate": "2020-03-23T14:31:13+00:00", "paymentMethodSource": "TOKEN", "authorizationResponse": { "amount": null, "currency": null, "authorizationDate": null, "authorizationNumber": null, "authorizationResult": null, "authorizationMode": "MARK", "_type": "V4/PaymentMethod/Details/Cards/CardAuthorizationResponse" }, "captureResponse": { "refundAmount": null, "captureDate": null, "captureFileNumber": null, "refundCurrency": null, "_type": "V4/PaymentMethod/Details/Cards/CardCaptureResponse" }, "threeDSResponse": { "authenticationResultData": { "transactionCondition": null, "enrolled": null, "status": null, "eci": null, "xid": null, "cavvAlgorithm": null, "cavv": null, "signValid": null, "brand": null, "_type": "V4/PaymentMethod/Details/Cards/CardAuthenticationResponse" }, "_type": "V4/PaymentMethod/Details/Cards/ThreeDSResponse" }, "authenticationResponse": { "id": "451d6c8b-8ba9-4a10-854f-34308e5cff3b", "operationSessionId": "c7f9c8711d994aa5818f886dc995e9eb", "protocol": { "name": "THREEDS", "network": "VISA", "version": "1.0.2", "challengePreference": "NO_PREFERENCE", "simulation": false, "_type": "V4/PCI/Charge/Authenticate/Protocol" }, "value": { "authenticationType": "CHALLENGE", "authenticationId": { "authenticationIdType":"xid", "value":"c82794e99c2044a89297b70e1e7c4006", "_type": "V4/PCI/Charge/Authenticate/AuthenticationId" }, "authenticationValue": { "authenticationValueType": "CAVV", "value": "FsXD4Ox0VEI2MseoR0VhN5pX952I", "_type": "V4/PCI/Charge/Authenticate/AuthenticationValue" }, "status": "SUCCESS", "commerceIndicator": "05", "extension": { "enrolled": "Y", "algorithm": "2", "signatureValid": true, "_type": "V4/PCI/Charge/Authenticate/AuthenticationResultExtensionThreedsV1" }, "reason": { "_type": "V4/PCI/Charge/Authenticate/AuthenticationResultReason" }, "_type": "V4/PCI/Charge/Authenticate/AuthenticationResult" }, "_type": "V4/AuthenticationResponseData" }, "installmentNumber": null, "installmentCode": null, "markAuthorizationResponse": { "amount": 0, "currency": "EUR", "authorizationDate": "2020-03-23T14:31:13+00:00", "authorizationNumber": "3fefaa", "authorizationResult": "0", "_type": "V4/PaymentMethod/Details/Cards/MarkAuthorizationResponse" }, "cardHolderName": null, "identityDocumentNumber": null, "identityDocumentType": null, "_type": "V4/PaymentMethod/Details/CardDetails" }, "parentTransactionUuid": null, "mid": "1549425", "sequenceNumber": 1, "taxAmount": null, "preTaxAmount": null, "taxRate": null, "externalTransactionId": null, "_type": "V4/TransactionDetails" } }, "_type": "V4/PaymentTransaction" ] }, "_type": "V4/Payment" }
Etapa 18: Seguimiento de las operaciones por el servidor mercantil
Si la respuesta anterior es un resultado final, la verificación de la tarjeta ha finalizado.
Apéndices
Ejemplo de cinemática: Autentificación 3DS v2 con autentificación en el ACS
- una llamada inicial al servicio PCI/Charge/VerifyPaymentMethod con una tarjeta afiliada a 3DS v2
- un retorno con una instrucción FINGERPRINT (3DS Method)
- una redirección al ACS dentro del iFrame invisible, cargando y ejecutando el código JavaScript de fingerprint del ACS
- un retorno vía el navegador con un resultado de instrucción
- una nueva llamada al servicio PCI/Charge/VerifyPaymentMethod con este resultado
- un retorno del servidor de la plataforma de pago con una nueva instrucción CHALLENGE de redirección al ACS con un CReq (iFrame visible)
- la instrucción se produjo (redirección al ACS con un Creq y la interacción del usuario)
- el retorno a través del navegador es un resultado de instrucción: nueva llamada al servicio PCI/Charge/VerifyPaymentMethod transmitiendo este resultado
- el retorno del servidor es el resultado final de la autentificación
Glosario
3DS Method | Código JavaScript del ACS ejecutado en el navegador del comprador con el fin de fingerprinting. |
3DS Requestor | Solicitante durante una autentificación 3DS, generalmente el vendedor o su pasarela de pago. |
3DS Server | Servidor 3DS. Componente del dominio 3DS Requestor que inicia el proceso 3DS v2 y se comunica con DS o ACS durante la autentificación de las transacciones. Facilita la interacción entre el 3DS Requestor y el DS. |
ACS | Access Control Server. Componente que verifica si la autentificación está disponible para un número de tarjeta y autentifica las transacciones específicas. |
Application 3DS Requestor | La aplicación sobre dispositivo móvil del comprador que puede tratar una transacción 3DS mediante el uso del SDK de 3DS. La aplicación es posible gracias a la integración con el SDK 3DS. |
Challenge | Fase de autentificación interactiva entre el comprador y su banco (ACS). |
CReq | Mensaje 3DS v2 de solicitud de autentificación del titular de la tarjeta enviado al ACS. |
DS | Directory Server. Componente que mantiene la lista de intervalos de tarjetas para las cuales la autentificación puede estar disponible y permite que los MPI / 3DS Servers / ACS se comuniquen entre ellos durante la autentificación. |
Fingerprinting | Literalmente "verificación de la tarjeta". Identificación de manera única del comprador a través de la información del navegador. |
SDK 3DS | Kit de desarrollo 3-D Secure. Componente de software incluido en una aplicación 3DS Requestor. |
IAN | Notificación de servidor a servidor para obtener el resultado de la autentificación (Notificación de autentificación instantánea). |
operationUrl | URL enviada al método de inicialización del script de autentificaciónkr-authenticate.js . |
operationSessionId | Identificador único para la sesión de autentificación. |
Lista de protocolos soportados
PROTOCOLO | VERSIÓN |
---|---|
3D Secure | 2.1.0 |
3D Secure | 2.2.0 |
Tarjetas de test
La página de referencia de las tarjetas de test se encuentra aquí.