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
- Quem pode migrar
- O que muda
- Regras para migração
- Roteiro de migração
- Pontos de atenção
- 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.
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 3DSA 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:
Componente Versã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.brparampi.braspag.com.brnos 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
referenceIde otokenretornados pelo INIT não são oaccess_tokene podem ser expostos ao front-end. Oaccess_tokennunca 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
Eciretornado 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
| Token | Origem | Destino | Uso |
|---|---|---|---|
access_token | AUTH | Back-end apenas | Autoriza as chamadas INIT, ENROLL e VALIDATE. |
token | INIT | Front-end | Inicializa 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.jsempiHelpers.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_tokengerado e usado exclusivamente no back-end; -
access_tokennão exposto em logs, respostas de API ou front-end; - Renovação do
access_tokenimplementada (validade: 20 minutos).
Fluxo de autenticação
- AUTH: endpoint atualizado para
/v3/auth/token; - INIT: implementado no back-end, retornando
referenceIdetoken; -
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ó
ExternalAuthenticationpreenchido com os dados retornados pelo ENROLL/VALIDATE.
Tratamento de status
- Status = 0 (falha): fluxo de contingência definido e implementado, considerando o
Eciretornado; - Status = 1 (autenticado): fluxo de autorização acionado;
- Status = 2 (desafio):
MPI.challenge()chamado com o remapeamento correto (Pareq→payload); - Callback
onErrorimplementado 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.
Updated 2 days ago