Erros no createOrder

Se o teu backend falhar a criar a ordem, lança dentro do createOrder(). A SDK encaminha para onError e o popup não avança.
async createOrder() {
  const r = await fetch('/api/facipay/create-order', { method: 'POST' });
  if (!r.ok) {
    const { error } = await r.json().catch(() => ({}));
    throw new Error(error || 'Falha ao criar ordem');
  }
  const { referenceNumber } = await r.json();
  if (!referenceNumber) throw new Error('referenceNumber vazio');
  return referenceNumber;
}
Se o createOrder() devolver uma string vazia, o popup fecha-se sem erro visível. Valida sempre que o referenceNumber é uma string não-vazia.

onError

async onError(error) {
  console.error('FaciPay error:', error.code, error.message);
  showToast('Ocorreu um erro durante o pagamento. Tenta novamente.', 'error');
}

Estados de loading

Desativa o botão enquanto validas dados e reativa quando estiver pronto.
facipay.generateButton({
  async onInit(actions) {
    if (!cartIsValid()) actions.disable();
  },
  async onClick(data, actions) {
    const customer = validateCustomerForm();
    if (!customer) {
      actions.reject(); // interrompe o fluxo deste clique (o popup não abre)
      return;
    }
    facipay.button.addCustomerInfo(customer);
  },
});

Popups bloqueados

Os browsers podem bloquear o popup se ele não nascer de um gesto direto do utilizador.
  • Abre o popup como reação direta ao clique (a SDK já o faz no handler do botão).
  • Avisa o utilizador para permitir popups do teu site.
  • Evita await longos antes de abrir o popup no caminho do clique.

Chave inválida

Se apiKeyStatus ficar invalid, o render() mostra uma mensagem de erro em vez do botão. Confirma que a chave corresponde ao ambiente (sandbox vs produção) e que não está vazia.
const facipay = FaciPay(PUBLISHABLE_KEY);
// Verifica no console se aparece "API Key status: invalid"