Guia de migração do MPI V2 para o MPI Cielo V3 para autenticação 3DS

ℹ️

Esta página descreve como migrar uma integração existente do MPI V2 para o MPI Cielo V3. Para a referência completa da integração MPI Cielo V3 (endpoints, campos e código-fonte dos scripts), consulte Nova integração do MPI Cielo para autenticação 3DS.

Nesta página

  1. Quem pode migrar
  2. O que muda
  3. Regras para migração
  4. Roteiro de migração
  5. Pontos de atenção
  6. Checklist de go-live

Quem pode migrar

O MPI V3 é exclusivo para estabelecimentos que atendem aos dois pré-requisitos abaixo:

  • Ter certificação PCI DSS;
  • Ter o produto 3DS habilitado na Cielo.
⚠️

Confirme os dois pontos antes de iniciar a migração. Sem eles, a integração MPI V3 não funciona.


O que muda

A migração troca apenas o plugin de integração (MPI): do modelo MPI V2, baseado em front-end, para o modelo MPI V3, server-to-server, no qual o estabelecimento controla todas as chamadas à API do back-end.

ℹ️

Versão do MPI vs. versão do 3DS

A mudança de MPI V2 para MPI V3 afeta somente a evolução do plugin de integração. O protocolo de autenticação 3DS não muda:

ComponenteVersão
MPI (integração)✅ MPI V3 (modelo server-to-server)
3DS (protocolo de autenticação)✅ 2.2 (Visa, Mastercard) / 2.1 (Elo, Amex)

As credenciais de acesso também não mudam: ClientId e ClientSecret continuam os mesmos usados no MPI V2. O que muda é o endpoint da operação AUTH, de /v2/auth/token para /v3/auth/token.


Regras para migração

Respeite as regras abaixo durante e depois da migração:

  • A migração é obrigatória: a integração MPI V2 será descontinuada, então respeite o prazo informado pela Cielo;
  • Não rode o MPI V2 e o MPI V3 em paralelo para o mesmo pedido, os scripts são incompatíveis entre si. Trate a migração como uma substituição completa: remova os scripts e classes do MPI V2 e implemente o fluxo do MPI V3 por inteiro;
  • Não misture versões na mesma transação, uma autenticação iniciada com o MPI V2 deve ser concluída com o MPI V2, e uma autenticação iniciada com o MPI V3 deve ser concluída com o MPI V3;
  • Planeje a ativação em produção para um momento de baixo volume, para minimizar o impacto em transações em andamento.

Roteiro de migração

Siga a sequência abaixo para substituir a integração MPI V2 pelo MPI Cielo V3.

Passo 1 – Substituir os scripts

Remova o script do MPI V2 da página de checkout e adicione os scripts do MPI V3:

<!-- REMOVER (MPI V2) -->
<script src="https://mpisandbox.braspag.com.br/Scripts/BP.Mpi.3ds20.min.js"></script>

<!-- ADICIONAR (MPI V3) -->
<script src="https://mpisandbox.braspag.com.br/Scripts/V3/mpi.js"></script>
<script src="https://mpisandbox.braspag.com.br/Scripts/V3/mpiHelpers.js"></script>
ℹ️

Em produção, troque o domínio de mpisandbox.braspag.com.br para mpi.braspag.com.br nos três scripts.

Passo 2 – Remover as classes bpmpi_* do HTML

Remova do formulário de checkout todos os inputs com classes bpmpi_* (por exemplo, bpmpi_auth, bpmpi_accesstoken, bpmpi_cardnumber, bpmpi_billto_* e bpmpi_cart_*) e a chamada bpmpi_authenticate(). Nenhum desses campos é usado no MPI V3: os mesmos dados passam a ser enviados pelo back-end no corpo do ENROLL.

Passo 3 – Mover a geração do access_token para o back-end

Atualize o endpoint da operação AUTH de /v2/auth/token para /v3/auth/token. O access_token nunca deve ser enviado ao front-end.

POST https://mpisandbox.braspag.com.br/v3/auth/token
Authorization: Basic <credencial_em_base64>
Content-Type: application/json

{
  "EstablishmentCode": "1044748068",
  "MerchantName": "Nome da Loja",
  "MCC": "7372"
}

Resposta:

{
  "access_token": "<access_token>",
  "token_type": "bearer",
  "expires_in": "1200"
}

Passo 4 – Implementar o INIT no back-end

Depois de obter o access_token, chame a operação INIT no back-end e retorne referenceId e token ao front-end:

POST https://mpisandbox.braspag.com.br/v3/3ds/init
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "orderNumber": "ORD-001",
  "currency": "986",
  "amount": "1000"
}

Resposta:

{
  "referenceId": "f49f78fc-...",
  "token": "eyJhbGci..."
}
⚠️

O referenceId e o token retornados pelo INIT não são o access_token e podem ser expostos ao front-end. O access_token nunca deve sair do back-end.

Passo 5 – Configurar o script no front-end

Substitua a chamada bpmpi_authenticate() pela inicialização do MPI V3:

// MPI V3: configurar e carregar o script
MPI.load({
    Environment: "SDB", // "PRD" em produção
    Debug: false,
    onLoadComplete: function () {
        // Inicializar com os valores retornados pelo INIT
        MPI.init(referenceId, token);
    },
    onReady: function () {
        // Script pronto para uso
    },
    onError: function (error) {
        // Tratar erro: { Xid, Eci, ReturnCode, ReturnMessage, ReferenceId }
    },
    onValidationRequired: function ({ TransactionId }) {
        // Enviar TransactionId ao back-end para chamar VALIDATE
    },
    cardNumberReader: function () {
        return document.getElementById("cardNumber").value;
    }
});

Passo 6 – Coletar dados e chamar o ENROLL no back-end

No momento do checkout, colete o BrowserInfo com MPIHelpers.getBrowserInfo() e envie ao back-end para compor a requisição ENROLL:

// Front-end: coletar browserInfo e enviar ao back-end
document.getElementById("btnPagar").addEventListener("click", function () {
    MPI.updateCard();
    const browserInfo = MPIHelpers.getBrowserInfo();

    fetch("/api/3ds/enroll", {
        method: "POST",
        body: JSON.stringify({ browserInfo, ...dadosDoPedido })
    })
    .then(res => res.json())
    .then(enroll => {
        if (enroll.status === 2) {
            // Status 2: exibir desafio — atenção ao remapeamento de campos
            const order = MPIHelpers.getOrderBuilder()
                .withOrderNumber(enroll.orderNumber)
                .build();

            MPI.challenge(
                {
                    acsUrl:        enroll.challenge.acsUrl,
                    payload:       enroll.challenge.pareq, // atenção: o campo vem como "pareq"
                    transactionId: enroll.challenge.transactionId
                },
                order
            );
        }
        // Status 1: autenticado sem desafio → prosseguir para autorização
        // Status 0: falha → tratar conforme o Eci retornado
    });
});

Passo 7 – Implementar o VALIDATE no back-end

Quando o callback onValidationRequired for acionado, envie o TransactionId ao back-end para chamar o VALIDATE.

POST https://mpisandbox.braspag.com.br/v3/3ds/validate
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "transactionId": "<TransactionId>",
  "ordernumber": "ORD-001",
  "currency": "BRL",
  "totalamount": 1000,
  "card": {
      "cardnumber": "4000000000002701",
      "expirationmonth": 3,
      "expirationyear": 2029
  }
}

Resposta:

{
    "Authentication": {
        "Version": "2.2.0",
        "DirectoryServerTransactionId": "9a7c2937-148a-446a-9da8-3fffbe84f390",
        "Xid": null,
        "Eci": "07",
        "Cavv": null
    },
    "Status": 0,
    "Reason": { "Code": "100", "Message": "Success" }
}

Passo 8 – Autorização

Depois do ENROLL (status 1) ou do VALIDATE (status 0 ou 1), envie o resultado da autenticação no nó Payment.ExternalAuthentication da chamada de autorização. Esta etapa não muda em relação ao MPI V2 — a estrutura do nó é a mesma; só a origem dos dados muda, agora vinda do ENROLL/VALIDATE do MPI V3.

{
  "Payment": {
    "Authenticate": true,
    "ExternalAuthentication": {
      "Cavv": "<Authentication.Cavv>",
      "Xid": "<Authentication.Xid>",
      "Eci": "<Authentication.Eci>",
      "Version": "<Authentication.Version>",
      "ReferenceID": "<referenceId do INIT>"
    }
  }
}
ℹ️

Avalie sempre o Eci retornado antes de decidir prosseguir com a autorização: ele determina se a transação foi de fato autenticada e de quem é o risco de chargeback. Consulte a tabela de ECI da bandeira usada na transação.


Pontos de atenção

access_token no back-end

O access_token nunca pode ser enviado ao front-end. Qualquer exposição representa risco de segurança. Apenas o token retornado pelo INIT deve chegar ao navegador.

Diferença entre token e access_token

TokenOrigemDestinoUso
access_tokenAUTHBack-end apenasAutoriza as chamadas INIT, ENROLL e VALIDATE.
tokenINITFront-endInicializa o script com MPI.init().

Validade do access_token

O access_token expira em 20 minutos (1.200 segundos) em produção. Implemente uma lógica de renovação automática ou gere um novo token por sessão de compra. Se o access_token expirar antes do fim da sequência, a API retorna 401 — nesse caso, gere um novo access_token e reinicie o fluxo a partir do AUTH.


Ordem das operações

A API bloqueia chamadas fora de ordem e chamadas repetidas (erro 409). Respeite sempre a sequência: AUTH → INIT → ENROLL → VALIDATE (quando aplicável) → autorização.

Assinatura de MPI.init()

A ordem dos parâmetros é MPI.init(referenceId, token). Inverter os parâmetros causa falha silenciosa na inicialização.

MPI.updateCard() antes do ENROLL

Chame MPI.updateCard() antes de enviar os dados ao back-end. O método lê o número do cartão via cardNumberReader e atualiza o estado interno do script. Se o método não for chamado — ou se o comprador trocar de cartão durante a mesma sessão sem chamá-lo de novo —, a autenticação pode usar um número de cartão desatualizado.


Desafio de autenticação

Desafio: construir o objeto order corretamente

Ao chamar MPI.challenge(), construa o segundo parâmetro (order) com MPIHelpers.getOrderBuilder(). Um objeto malformado impede a exibição do desafio.

Desafio: remapeamento dos campos do ENROLL

O objeto que MPI.challenge() espera como primeiro parâmetro é { acsUrl, payload, transactionId }, mas a resposta do ENROLL retorna Challenge.AcsUrl, Challenge.Pareq e Challenge.TransactionId. Mapeie Pareq para payload — passar o objeto challenge bruto do ENROLL direto para MPI.challenge() não funciona.


Cartões múltiplos (crédito e débito)

Para cartões que suportam crédito e débito, o campo card.paymentMethod é obrigatório no ENROLL. Os valores aceitos são "credit" ou "debit" (em minúsculo, conforme os exemplos da API MPI V3).


Data Only

No MPI V3, o modo Data Only é ativado pelo campo authNotifyOnly: true no corpo do ENROLL, e não por classe CSS. Remova o controle via bpmpi_auth_notifyonly. O ECI de uma autenticação Data Only bem-sucedida é sempre 4 (Mastercard) ou 7 (Visa) — nesses casos, a responsabilidade por chargeback permanece com a loja.


Checklist de go-live

Use esta lista antes de ativar a integração MPI V3 em produção.

Elegibilidade

  • Certificação PCI DSS confirmada;
  • Produto 3DS habilitado na Cielo;
  • Nenhuma transação rodando o MPI V2 e o MPI V3 em paralelo para o mesmo pedido.

Infraestrutura

  • Scripts do MPI V3 incluídos na página de checkout (mpi.js e mpiHelpers.js);
  • URLs de produção configuradas nos scripts e nas chamadas de API;
  • Script do MPI V2 (BP.Mpi.3ds20.min.js) removido do HTML;
  • Todas as classes bpmpi_* removidas do HTML.

Segurança

  • access_token gerado e usado exclusivamente no back-end;
  • access_token não exposto em logs, respostas de API ou front-end;
  • Renovação do access_token implementada (validade: 20 minutos).

Fluxo de autenticação

  • AUTH: endpoint atualizado para /v3/auth/token;
  • INIT: implementado no back-end, retornando referenceId e token;
  • MPI.init(referenceId, token) chamado com os parâmetros na ordem correta;
  • MPI.updateCard() chamado antes do envio do pedido;
  • MPIHelpers.getBrowserInfo() usado para coletar os dados do navegador;
  • ENROLL: implementado no back-end com todos os campos obrigatórios;
  • VALIDATE: implementado no back-end, com os campos em minúsculas, e acionado via callback onValidationRequired;
  • Autorização: nó ExternalAuthentication preenchido com os dados retornados pelo ENROLL/VALIDATE.

Tratamento de status

  • Status = 0 (falha): fluxo de contingência definido e implementado, considerando o Eci retornado;
  • Status = 1 (autenticado): fluxo de autorização acionado;
  • Status = 2 (desafio): MPI.challenge() chamado com o remapeamento correto (Pareq → payload);
  • Callback onError implementado com log e tratamento de falha.

Testes

  • Cenário 1 validado: autenticação sem desafio (Status = 1) com o cartão 4000000000002701;
  • Cenário 5 validado: autenticação com desafio (Status = 2) com o cartão 4000000000002503;
  • Cenário 6 validado: falha de autenticação (Status = 0) com o cartão 4000000000002925;
  • Cenário Data Only validado (se aplicável);
  • Cenário de recorrência validado (se aplicável);
  • Erros HTTP 400, 401 e 409 tratados corretamente.

Did this page help you?