Comunicação via postMessage e tratamento de erros
A comunicação entre a página da loja e o iframe ocorre por eventos do postMessage enviados pelo checkout e pelos estados do próprio front-end. Esses mecanismos permitem ajustar a exibição, reagir a sucessos, capturar falhas e manter a jornada de pagamento funcional mesmo quando há erros.
Erros no front-end
Falha ao criar a página de pagamento
O erro mais crítico ocorre quando a checkoutUrl não está presente na resposta do back-end. O front-end interrompe o carregamento e exibe uma mensagem amigável.
try {
const data = await CheckoutFetcher.callCreateCheckout(apiUrl, payload);
// Extrai a checkoutUrl da resposta
// A URL pode estar em diferentes lugares dependendo da versão da API
let checkoutUrl = '';
if (data?.data?.settings?.checkoutUrl) {
checkoutUrl = data.data.settings.checkoutUrl;
} else if (data?.data?.checkoutUrl) {
checkoutUrl = data.data.checkoutUrl;
} else if (data?.data?.url) {
checkoutUrl = data.data.url;
}
this.checkoutUrl = checkoutUrl;
if (!this.checkoutUrl) {
this.error = 'URL de checkout não encontrada na resposta.';
}
} catch (e) {
this.error = 'Erro ao criar checkout.';
console.error(e);
} finally {
this.loading = false;
}
}
}
};Iframe não aparece
O iframe não carrega quando a checkoutUrl está vazia ou inválida. Validar a URL ajuda a identificar o problema:
console.log('checkoutUrl recebida:', checkoutUrl);Erro CORS
Ocorre quando a API Checkout é chamada diretamente do front-end. A chamada deve sempre ocorrer pelo back-end.
URL nula ou fora do padrão
Alterações na estrutura da API podem fazer com que a URL apareça em campos diferentes:
const checkoutUrl =
data?.data?.settings?.checkoutUrl ||
data?.data?.checkoutUrl ||
data?.data?.url;Erros no backend
Erro 401 (Unauthorized)
Indica problema com o MerchantId ou configuração de autenticação. É necessário revisar o envio do header para a API.
Falha ao criar o checkout na API
O back-end deve tratar exceções da API e retornar uma resposta consistente para o front-end.
try {
const { data } = await axios.post(
'https://cieloecommerce.cielo.com.br/api/public/v1/orders/',
payload,
{
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
MerchantId: CIELO_MERCHANT_ID
},
timeout: 10000
}
);
const checkoutUrl = data?.CheckoutUrl || data?.checkoutUrl || data?.url;
return res.json({ checkoutUrl });
} catch (err) {
return res.status(err.response?.status || 500).json({
message: 'Falha ao criar checkout',
detail: err.response?.data || err.message
});
}
Esse tratamento permite:
- Diferenciar erros da API de falhas internas;
- Retornar código HTTP adequado;
- Expor uma mensagem de erro controlada para o front-end.
Boas práticas de tratamento
Algumas práticas ajudam a tornar o fluxo de checkout mais resiliente:
- Implementar
timeoutsnas chamadas para a API; - Considerar
retriescom intervalo exponencial em cenários de instabilidade; - Aplicar idempotência na criação de pedidos ou de checkouts;
- Validar dados de entrada antes de enviar ao backend;
- Monitorar erros e respostas da API para detectar padrões de falha;
- Utilizar TLS e políticas de conteúdo (CSP) no domínio da loja.
Timeout e fallback do iframe
O carregamento do iframe usa um tempo máximo para identificar quando o checkout não respondeu a tempo. Quando esse limite é atingido, o fluxo ativa o fallback, evitando que a pessoa compradora permaneça indefinidamente na tela de carregamento e oferecendo uma alternativa segura para continuar o pagamento.
Timeout
const FAIL_TIMEOUT_MS = 7000; // ajuste conforme sua UXEstrutura de marcação
<div id="checkout-loading" role="status">
Carregando o checkout…
</div>
<div id="checkout-fallback" hidden>
Não foi possível carregar o checkout embutido.
<a id="checkout-direct-link" rel="noopener">Abrir pagamento</a>.
</div>Funcionamento
function loadCheckout(url) {
directLink.href = url;
iframe.src = url;
let finished = false;
const FAIL_TIMEOUT_MS = 7000;
iframe.addEventListener(
'load',
() => {
finished = true;
loadingEl.hidden = true;
},
{ once: true }
);
setTimeout(() => {
if (!finished) {
loadingEl.hidden = true;
fallbackEl.hidden = false;
}
}, FAIL_TIMEOUT_MS);
}Esse fluxo mantém o carregamento sob controle e oferece alternativa quando o iframe não responde a tempo.
Updated about 2 hours ago