Depois do pagamento, redireciona o cliente para uma de três páginas. Use actions.onPopupWindowClosed() para redirecionar só quando o popup fecha.

/sucesso

Leia o orderId, confirme o estado no backend (a fonte da verdade é o webhook) e mostre a confirmação.
async onApprove(data, actions) {
  actions.onPopupWindowClosed(() => {
    window.location.href = `/sucesso?orderId=${data.payment.orderId}`;
  });
}
/sucesso (cliente)
const orderId = new URLSearchParams(location.search).get('orderId');
const r = await fetch(`/api/facipay/order/${orderId}/status`);
const { status } = await r.json();
if (status === 'CON') showConfirmed();
else showStillProcessing();

/pendente (Referência EMIS)

Mostre entidade + referência + valor bem visíveis. Faça polling de fallback ao endpoint de estado e redirecione para /sucesso quando CON.
async onPending(data, actions) {
  actions.onPopupWindowClosed(() => {
    const ref = data.payment?.data?.paymentReference;
    const entity = data.payment?.data?.entity?.number;
    const amount = data.payment?.data?.amount;
    window.location.href = `/pendente?ref=${ref}&entity=${entity}&amount=${amount}`;
  });
}
/pendente (polling de fallback)
const orderId = new URLSearchParams(location.search).get('orderId');
const poll = setInterval(async () => {
  const r = await fetch(`/api/facipay/order/${orderId}/status`);
  const { status } = await r.json();
  if (status === 'CON') {
    clearInterval(poll);
    window.location.href = `/sucesso?orderId=${orderId}`;
  }
}, 7000); // 5–10s
O polling é apenas rede de segurança caso o webhook atrase. A confirmação oficial continua a vir do webhook no seu backend.

/cancelado

Mensagem clara e um CTA para tentar de novo.
async onCancel() {
  window.location.href = '/cancelado';
}

Próxima receita: Referências múltiplas

Mostrar o valor e vários itens no botão.