Serviço de verificação de cartão PCI
A verificação de cartão permite aos EC PCI-DSS verificar a validade dos cartões de pagamento. Uma vez que a verificação foi realizada, o cartão pode ser usado pelo EC no âmbito de pagamentos que ele poderá gerenciar No âmbito da diretiva européia DSP2, é obrigatório autenticar o portador do cartão via o protocolo 3D Secure O serviço autentica o portador do cartão e retorna os dados de autenticação no final da operação.
Princípio geral
A verificação do cartão de pagamento verifica a validade de um cartão. A chamada para o Web service PCI/Charge/VerifyPaymentMethod dá então inicio a uma transação de verificação. Como mencionado acima, no âmbito da DSP2, é obrigatório autenticar o portador do cartão via o protocolo 3D Secure. O roteiro é, portanto, o seguinte:
- Chamada do Web Service PCI/Charge/VerifyPaymentMethod
- A resposta pode ser de 2 tipos:
- AuthenticationResponseData : Esta resposta mostra que precisa autenticar o portador Você terá que chamar de novo o mesmo PCI/Charge/VerifyPaymentMethod com o resultado da instrução para a autenticação 3D Secure.
- Charge/Payment : Esta resposta indica que a verificação acabou e que pode-se consultar o resultado.
A autenticação sendo uma parte importante deste WebService, seu funcionamento foi detalhado abaixo.
Processo de autenticação
O serviço aplica um principio de funcionamento que não considera o protocolo subjacente para possibilitar uma integração única, e não uma integração por protocolo.
A cinemática padrão de uma autenticação completa pode ser dividida em etapas:
- uma chamada inicial ao serviço PCI/Charge/VerifyPaymentMethod com uma resposta de tipo AuthenticationResult ou AuthenticationInstruction.
- se o retorno for de tipoAuthenticationInstruction, esta operação deverá ser realizada do lado EC:
- criação de um iFrame visível ou invisível
- na iFrame, redirecionamento do navegador para o alvo com um formulário que aplica a definição presente na instrução
- interação eventual com o portador do cartão, ou o navegador
- página de retorno do servidor remoto que emitirá um evento JavaScript contendo o resultado da instrução
- intercepção do resultado da instrução sob a forma de evento JavaScript na página parente
- nova chamada ao serviço PCI/Charge/VerifyPaymentMethod com o resultado assinado da instrução obtido via o navegador
- o serviço PCI/Charge/VerifyPaymentMethod envia então de novo ou uma instrução ou um resultado
- se o retorno for de tipo AuthenticationResult , terá então o resultado de autenticação final. A operação finalizou.
Diagrama detalhado
O diagrama a seguir apresenta em detalhe os passos de um pagamento com autenticação: a chamada inicial ao serviço, uma instrução, uma interação, um resultado final da autenticação e o final do pagamento.
CLIENTE
Navegador
iFrame
Servidor Estabelecimento Comercial
Servidor da Plataforma de pagamento
Servidor remoto (ex: ACS)
Vamos detalhar as diferentes etapas da integração nos parágrafos seguintes.
Integração | Etapas |
---|---|
Ações a serem realizadas do lado do servidor do EC | etapas 3 , 4 , 16 e 17 |
Ações a serem realizadas do lado JavaScript | etapas 5 , 6 , 7 e 15 |
Etapa 1 e 2: Início (pagamento ou adição de cartão)
Uma ação de pagamento ou um registro de cartão foi iniciado e requer uma autenticação. O serviço PCI/Charge/VerifyPaymentMethod está pronto para ser chamado.
Etapa 3: Chamada do serviço PCI/Charge/VerifyPaymentMethod
A solicitação inicial permite enviar os dados necessários à autenticação.
Dentre destes dados, é preciso informar certos dados sobre o navegador ou o dispositivo mobile do cliente no objeto device.
Estes dados são pela maioria técnicos e devem ser recuperados no navegador ou no mobile (em JavaScript por exemplo).
O objetivo é facilitar a identificação do cliente (endereço IP) e do seu suporte de pagamento (tamanho do navegador) para possibilitar um processo de autenticação mais adequado.
Consulte a documentação de integração do serviço PCI/Charge/VerifyPaymentMethod para maiores informações sobre este campo.
Segue abaixo um exemplo descrevendo a solicitação 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: Resposta completa com uma instrução
A resposta conterá uma instrução sob a forma seguinte (neste exemplo trata-se de uma autentificação 3DS v1 (desvalorizado)):
{ "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" } }
O conteúdo divide-se em:
Objeto | Função |
---|---|
id | Código único da transação de autenticação em andamento. |
operationSessionId | Login de sessão único para a operação em andamento Sempre deverá ser enviado em toda chamada nova. |
protocol | Indica qual protocolo será aplicado de fato para a autenticação. |
Value | Representa o resultado da autenticação ou a instrução a seguir. Se value for de tipo AuthenticationInstruction , a instrução deve ser executada, se for de tipo AuthenticationResult , é somente o resultado da autenticação. |
Etapa 5: Elaboração da página de gerenciamento da instrução
Se uma instrução foi retornada durante a etapa anterior, a página exibida durante esta etapa deve permitir:
- implementar um tipo de evento retornado pelo iFrame, que iniciará um POST para o servidor do Estabelecimento Comercial com o resultado de instrução (ver. etapa 15 ).
- a criação de uma iFrame oculta ou exibida (cf. etapas 6 et 7 ).
Etapa 6: Criação do iFrame
A instrução recebida na etapa 4 está portanto como segue:
{ "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" }
As diferentes propriedades do iFrame a ser criado encontram-se no elemento target :
"target": { "element": "IFRAME", "visible": true, "width": 400, "height": 400 }
Si precisar exibir o iFrame (atributo value.target.visible com true ), ele deverá ser criado com estes parâmetros (largura em função de width e altura em função de height ) e mostrá-lo. Caso contrário criar um iFrame oculta.
Gerenciamento do timeout de exibição do iframe
É também preciso gerenciar a duração de exibição máxima do iframe se o atributo value.timeout estiver presente na instrução (timeout definido em segundo). Para isso será preciso permitir a realização de um evento de tipo LYRA_AUTH_INSTRUCTION_RESULT valorizado como segue:
{ 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" } }
Exemplo de implementação:
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: Apresentação do formulário
Uma vez a iFrame criada, precisa preenchê-la com um formulário e seguindo as instruções do tag '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" }
- a propriedade method indica o verbo HTTP a ser associado ao formulário
- url indica para qual servidor a ação do formulário deve ser dirigida
- os cabeçalhos da solicitação http nos headers
- os parâmetros do formulário no body (aqui por exemplo termUrl, MD e paReq)
Uma vez que o formulário foi gerado e colocado no iFrame, bastar iniciar a apresentação ao carregamento da página.
Se o timeout configurado no código de criação do iframe iniciar, o evento de tipo LYRA_AUTH_INSTRUCTION_RESULT será captado pelo listener cujos detalhes estão apresentados na etapa 15. Permitirá dar continuação a operação e ter um resultado final.
Etapas 8 até 14: Autenticação do usuário
Uma vez que o formulário foi postado, o código do banco emissor assumirá a operação para permitir a autenticação segura (silenciosa ou interativa). No final desta etapa, o evento LYRA_AUTH_INSTRUCTION_RESULT será emitido a partir da iFrame para indicar o fim da operação. Exemplo:
{ "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: Recuperação do evento JavaScript emitido na etapa 14
Para interpretar o evento LYRA_AUTH_INSTRUCTION_RESULT , é preciso implementar um listener na página principal. Deve ser capaz passar do código JSON e pode ser escrito assim:
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);
Precisa depois enviar estas informações ao servidor do Estabelecimento Comercial.
Etapa 16: Envio ao servidor do Estabelecimento Comercial do resultado da instrução
Uma vez que o resultado de instrução foi recuperado do lado do servidor do Estabelecimento Comercial, deve ser enviado em uma nova chamada ao serviço PCI/Charge/VerifyPaymentMethod. A solicitação deverá conter o objeto instructionResult bem como o código de sessão operationSessionId , recebido na resposta daetapa 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: Recepção da resposta do servidor da plataforma de pagamento
Bem como na etapa 4 , o servidor do Estabelecimento Comercial recebe uma nova resposta, que pode ser de fim ( AuthenticationResult ), ou que pode solicitar uma nova instrução ( AuthenticationInstruction ). Neste último caso, a troca retoma na etapa 5. Segue um exemplo de mensagem 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: Continuação das operações pelo Servidor do Estabelecimento Comercial
Se a resposta anterior for um resultado final, a verificação de cartão acabou.
Anexos
Exemplo de cinemática: Autenticação 3DS v2 com autenticação no ACS
- uma chamada inicial ao serviço PCI/Charge/VerifyPaymentMethod com um cartão inscrito 3DS v2
- um retorno com uma instrução FINGERPRINT (3DS Method)
- um redirecionamento para o ACS no iFrame incisível, carregamento e execução do código JavaScript de fingerprint do ACS
- um retorno via o navegador com um resultado de instrução
- uma nova chamada ao serviço PCI/Charge/VerifyPaymentMethod enviando este resultado
- um retorno do servidor da plataforma de pagamento com uma nova instrução CHALLENGE de redirecionamento para o ACS com um CReq (iFrame visível)
- a instrução acontece (redirecionamento para o ACS com um Creq e interação usuário)
- a volta via o navegador é um resultado de instrução: nova chamada ao serviço PCI/Charge/VerifyPaymentMethod enviando este resultado
- o retorno do servidor é o resultado final de autenticação
Glossário
3DS Method | Código JavaScript do ACS realizado no navegador do comprador para fins de fingerprinting. |
3DS Requestor | Solicitador para um autenticação 3DS, geralmente o EC ou seu gateway de pagamento. |
3DS Server | Servidor 3DS. Componente do domínio do 3DS Requestor que inicia a operação 3DS v2 e comunica com o DS ou o ACS durante a autenticação de transações. Facilita a interação entre o 3DS Requestor e o DS. |
ACS | Access Control Server. Componente que verifica se a autenticação está disponível para um número de cartão e que autentica transações específicas. |
Application 3DS Requestor | Aplicativo em dispositivo mobile do comprador que pode tratar uma transação 3DS usando o SDK 3DS. Possível graças à integração com o SDK 3DS. |
Challenge | Fase de autenticação interativa entre o comprador e seu banco (ACS). |
CReq | Mensagem 3DS v2 de solicitação de autenticação do portador de cartão, enviado ao ACS. |
DS | Directory Server. Componente que mantem a lista de intervalos de cartões para os quais uma autenticação pode estar disponível e que permite aos MPIs / 3DS Servers comunicar entre eles durante as autenticações. |
Fingerprinting | Literalmente "tomada de digital". Identificação única do comprador graças às informações do navegador. |
SDK 3DS | Kit de desenvolvimento 3D Secure. Componente software incluso em uma Aplicação 3DS Requestor. |
IAN | Notificação de servidor para servidor que permite obter o resultado da autenticação (Instant Authentification Notification). |
operationUrl | Url enviada ao método de inicialização do script de autenticaçãokr-authenticate.js . |
operationSessionId | Código único da sessão de autenticação. |
Lista dos protocolos suportados
PROTOCOLO | VERSÃO |
---|---|
3D Secure | 2.1.0 |
3D Secure | 2.2.0 |
Cartões de teste
A página de referência dos cartões de teste encontra-se aqui.