• França
lyra.com
Procurando
Categoria
Tags
pagina inicial
Suporte técnico

Serviço de criação de Token PCI

Ativação desta funcionalidade sujeita à uma autorização prévia do Lyra.

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.

Se o EC ou o cartão não forem inscritos ao programa 3D Secure, a chamada ao Web Service PCI/Charge/CreateToken retornará diretamente um objeto Payment. Neste caso, não há chamada para a URL de notificação.

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.

A sequência do pagamento está apresentada aqui a título de exemplo de uso possível do serviço PCI/Charge/CreateToken. A autenticação inicia na etapa 3 , e acaba na etapa 17.

CLIENTE

Navegador

iFrame

Servidor Estabelecimento Comercial

Servidor da Plataforma de pagamento

Servidor remoto (ex: ACS)

O retorno com o resultado de instrução ao serviço PCI/Charge/CreateToken (etapas 16 e 17 ) permite verificar a integridade dos dados que passaram pelo navegador do comprador e interpretar os resultados em função do protocolo usado.

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:

/pt-BR/rest/V4.0/api/kb/authentication.html
https://github.com/lyra/rest-php-examples/blob/master/www/minimalEmbeddedForm.php#L9-L44
https://api.lyra.com/api-payment/V4/PCI/Charge/CreateToken
{

  "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.

A autenticação é realizada geralmente com diversas chamadas ao serviço PCI/Charge/CreateToken. Para manter a transação, é preciso enviar em toda chamada o atributo id recebido besta resposta.

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 :

/pt-BR/rest/V4.0/api/kb/authentication.html
https://github.com/lyra/rest-php-examples/blob/master/www/minimalEmbeddedForm.php#L9-L44
https://api.lyra.com/api-payment/V4/PCI/Charge/CreateToken
{
  "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.

Jobs
Legal
GDPR
25.22-1.11