Serviço de criação de Token PCI
Este serviço de criação de Token permite aos EC PCI-DSS criar um Token passando os dados de cartões na solicitação.
No âmbito da 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
Este WS permite criar um Token do cartão enviado na solicitação Permite usar este token em futuros pagamentos sem precisar digitar novamente os dados de cartão do comprador.
A chamada para o Web service PCI/Charge/CreateToken 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 o Web Service PCI/Charge/CreateToken
- A resposta pode ser de 2 tipos:
- AuthenticationResponseData : Esta resposta mostra que precisa autenticar o portador Você deve então chamar de novo o mesmo PCI/Charge/CreateToken com o resultado da instrução para a autenticação 3D Secure.
- Charge/Payment : Esta resposta indica o fim da verificação e a criação do Token. Pode-se então verificar o resultado na resposta.
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/CreateToken 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/CreateToken com o resultado assinado da instrução obtida via o navegador
- o serviço PCI/Charge/CreateToken retorna 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/CreateToken está pronto para ser chamado.
Etapa 3: Chamada ao serviço PCI/Charge/CreateToken
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/CreateToken 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": "27", "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/CreateToken. 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" }, "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 }, "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 }, "extraDetails": { "browserAccept": null, "fingerPrintId": null, "ipAddress": "10.33.160.29", "browserUserAgent": "PostmanRuntime/7.23.0" }, "shoppingCart": { "insuranceAmount": null, "shippingAmount": null, "taxAmount": null, "cartItemInfo": null } }, "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" }, "captureResponse": { "refundAmount": null, "captureDate": null, "captureFileNumber": null, "refundCurrency": null }, "threeDSResponse": { "authenticationResultData": { "transactionCondition": null, "enrolled": null, "status": null, "eci": null, "xid": null, "cavvAlgorithm": null, "cavv": null, "signValid": null, "brand": null } }, "authenticationResponse": { "id": "451d6c8b-8ba9-4a10-854f-34308e5cff3b", "operationSessionId": "c7f9c8711d994aa5818f886dc995e9eb", "protocol": { "name": "THREEDS", "network": "VISA", "version": "1.0.2", "challengePreference": "NO_PREFERENCE", "simulation": false }, "value": { "authenticationType": "CHALLENGE", "authenticationId": { "authenticationIdType":"xid", "value":"c82794e99c2044a89297b70e1e7c4006" }, "authenticationValue": { "authenticationValueType": "CAVV", "value": "FsXD4Ox0VEI2MseoR0VhN5pX952I" }, "status": "SUCCESS", "commerceIndicator": "05", "extension": { "enrolled": "Y", "algorithm": "2", "signatureValid": true }, "reason": { "_type": "V4/PCI/Charge/Authenticate/AuthenticationResultReason" } } }, "installmentNumber": null, "installmentCode": null, "markAuthorizationResponse": { "amount": 0, "currency": "EUR", "authorizationDate": "2020-03-23T14:31:13+00:00", "authorizationNumber": "3fefaa", "authorizationResult": "0" }, "cardHolderName": null, "identityDocumentNumber": null, "identityDocumentType": null }, "parentTransactionUuid": null, "mid": "1549425", "sequenceNumber": 1, "taxAmount": null, "preTaxAmount": null, "taxRate": null, "externalTransactionId": null, "_type": "V4/TransactionDetails" } } ] } }
Etapa 18: Continuação das operações pelo Servidor do Estabelecimento Comercial
Se a resposta anterior for um resultado final, a criação do Token acabou.
Anexos
Exemplo de cinemática: Autenticação 3DS v2 com autenticação no ACS
- uma chamada inicia ao serviço PCI/Charge/CreateToken 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/CreateToken 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/CreateToken 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.