Skip to Content
SDKsJavaScript / Navegador

SDK JavaScript / Navegador

@lartech/infraio-checkout-js é o único SDK que a gente publica hoje. Roda no navegador e abre o nosso checkout hospedado. SDKs de backend (Node, Go, Python) estão no roadmap; até lá, fale direto com o gateway — veja o Início rápido para um helper de assinatura HMAC.

  • Versão atual: 0.1.1-beta.17 (pré-1.0; espere pequenas quebras)
  • Formatos: ESM (index.js), CJS (index.cjs), IIFE (index.global.js)
  • Tipos embutidos (index.d.ts)
  • Zero dependências de runtime — sem React, jQuery ou outras deps

Não existe ponto de entrada do lado do servidor. Helpers de verificação de assinatura para webhooks não vêm embutidos — implemente você mesmo com crypto (a página de verificação de assinatura tem código pronto para copiar e colar em 4 linguagens).

Instalação

npm install @lartech/infraio-checkout-js

loadInfraIo(publicKey, options?)

Retorna uma Promise<InfraIoInstance>.

import { loadInfraIo } from "@lartech/infraio-checkout-js"; const sdk = await loadInfraIo("pk_live_yourkeyhere", { // Opcional. Sobrescreva só quando apontar para um ambiente não-prod. checkoutUrl: "https://checkout-dev.infraio.xyz", });
ParamTipoObrigatórioNotas
publicKeystringPrecisa combinar com pk_(live|test)_…
options.checkoutUrlstringSobrescreve a URL base do checkout. Padrão: https://checkout.infraio.xyz. A URL de gateway correspondente é determinada pela página de checkout em runtime — cada deploy checkout(-dev).infraio.xyz carrega o seu NEXT_PUBLIC_API_URL de tempo de compilação, então escolher o hostname certo aqui escolhe o backend certo automaticamente. Não há uma opção gatewayUrl separada.

sdk.checkout({ … })

Abre o checkout hospedado. Retorna void (use callbacks para estado).

CampoTipoObrigatórioNotas
sessionIdstringsession_key retornado por POST /b2b/v1/checkout-sessions/quick
checkoutUrlstringURL completa retornada pelo mesmo endpoint. Se omitida, o SDK constrói a partir do checkoutUrl de loadInfraIo() (ou do padrão) + sessionId
mode"popup" | "redirect" | "embed"Padrão "popup"
containerstring | HTMLElementsó embedSeletor CSS ou elemento do DOM onde o iframe é montado
widthnumberSó popup. Padrão 560. Limitado a [320, 1280]
heightnumberSó popup. Padrão 780. Limitado a [400, 1000]
timeoutMsnumberSó popup. Timeout de carregamento do iframe. Padrão 30000. Passe 0 para desativar
localestringTag BCP-47 encaminhada como ?locale= para a página de checkout (en, ja, zh-CN, zh-TW)
hideSummarybooleanEsconde a coluna de resumo do pedido. Padrão false
hideHeaderbooleanEsconde o header InfraIO e o botão embutido de wallet-connect. Padrão false. Combine com walletAddress para white-label completo
walletAddressstringPré-conecta uma carteira do comprador. Requer onSignRequest
walletChainIdnumberEVM chain ID para a carteira pré-conectada
onReady() => voidDispara uma vez que o iframe está interativo. Só popup/embed
onSignRequest(req: { method: string; params: unknown[] }) => Promise<string>quando walletAddress está setO SDK faz proxy das RPCs de carteira para o seu handler; retorne o hex assinado
onSuccess({ sessionId }) => voidDispara em pagamento bem-sucedido. Não é oficial — o webhook é
onCancel() => voidDispara quando o comprador fecha o popup/embed sem pagar
onError(err: InfraIoError) => voidDispara em falha de carregamento do iframe (modos popup + embed). Argumentos inválidos são lançados de forma síncrona, não entregues aqui. O modo redirect não tem superfície de erro em runtime — a falha é observada na página redirecionada.

onSuccess não é oficial. Pode disparar mesmo quando o webhook depois determina que o pagamento falhou (reorgs de testnet, timing do lado do comprador). Use só para UX (mostrar “Obrigado!”, redirecionar). Sempre confirme via webhook antes de cumprir a entrega.

sdk.close()

Descarta programaticamente um popup ou embed aberto. No-op para o modo redirect.

sdk.checkout({ sessionId, mode: "popup", /* … */ }); // depois, por exemplo, quando o usuário navega para longe sdk.close();

sdk.openRefundRequest({ … })

Abre o formulário hospedado de pedido de reembolso para um token de uso único que o seu backend criou via POST /b2b/v1/merchants/{merchant_id}/refund-requests. O comprador preenche o endereço de destino do reembolso + motivo + (opcional) metadata na nossa página; a sua página só cuida do ciclo de abertura/fechamento. Retorna uma função close() — chame para descartar programaticamente o popup ou destacar o iframe de embed. No modo redirect a função retornada é no-op.

O formulário vive em https://checkout.infraio.xyz/refund-request/:token. Este método só envelopa essa URL num popup / redirect / embed para que o comprador nunca saia do seu domínio (em popup / embed) ou volte para ele automaticamente (em redirect). O endpoint que o seu backend chama para criar o token é POST /b2b/v1/merchants/{merchant_id}/refund-requests — assinado com HMAC pela sua chave secreta, mesma auth do resto da superfície B2B. Veja Conceitos → Reembolsos.

import { loadInfraIo } from "@lartech/infraio-checkout-js"; const sdk = await loadInfraIo("pk_live_yourkeyhere"); // Cria o token no servidor e entrega para o SDK no navegador. const { token } = await fetch("/api/mint-refund-token", { method: "POST" }).then(r => r.json()); const close = sdk.openRefundRequest({ token, mode: "popup", onSuccess: ({ linkToken, refundId }) => { // Comprador submeteu o formulário. // linkToken → página de status /r/:linkToken (compartilhe com o comprador). // refundId → use com a API B2B para aprovar / rejeitar. window.location.href = `/r/${linkToken}`; }, onCancel: () => { /* comprador fechou sem enviar */ }, }); // Descarte programaticamente o popup depois, se precisar: // close();
CampoTipoObrigatórioNotas
tokenstringO token rfqt_… retornado por POST /b2b/v1/merchants/{merchant_id}/refund-requests
mode"popup" | "redirect" | "embed"Padrão "popup". Mesma semântica de superfície do sdk.checkout() — veja Notas sobre os modos
containerstring | HTMLElementsó embedSeletor CSS ou elemento do DOM onde o iframe é montado
localestringTag BCP-47 encaminhada como ?locale= (en, ja, zh-CN, zh-TW)
hideHeaderbooleanEsconde o header InfraIO dentro do iframe. Em popup/embed o SDK desenha o próprio chrome de modal, então o header da página costuma ser ruído. Padrão false
hideSummarybooleanEsconde a coluna de Resumo do Pedido, mostrando só o formulário de reembolso. Padrão false
walletAddressstringPré-preenche o campo de carteira de destino (?wallet_address=). Deixa um lojista que já conhece a carteira do comprador pular a re-digitação manual
onSuccess(data: { linkToken: string; refundId: string }) => voidDispara depois que o comprador submete o formulário. linkToken → página de status /r/:linkToken para compartilhar com o comprador. refundId → use com a API B2B para aprovar / rejeitar
onCancel() => voidDispara quando o comprador fecha o popup/embed sem submeter
onError(err: InfraIoError) => voidDispara em falha de carregamento do iframe ou args inválidos. Expiração de token / cancelamento é tratado pela página hospedada, não via onError

Estados de token expostos via onError

Se o comprador abre um token velho, a própria página cuida do display (renderiza um prompt “Expirado — peça link novo”, etc.), e o SDK não dispara onError para esses casos — o comprador está dentro do fluxo do formulário e o seu código não precisa reagir. onError só dispara para coisas em que o seu código pode agir (argumentos ruins, falha de rede ao carregar o iframe).

openRefundRequest registra a intenção de reembolso — ele não move fundos. Depois de onSuccess, a linha de reembolso está PENDING (ou APPROVED se a sua config de lojista faz auto-aprovação de reembolsos de cliente). Você ainda precisa assinar e transmitir a transferência on-chain da carteira do seu lojista e depois postar o tx hash em POST /b2b/v1/refunds/:id/submit-tx. Veja Conceitos → Reembolsos para o ciclo de vida completo.

Classe de erro

import { InfraIoError } from "@lartech/infraio-checkout-js"; sdk.checkout({ sessionId, onError: (err: InfraIoError) => { switch (err.code) { case "invalid_request_error": /* sessionId / args ruins */ break; case "iframe_load_error": /* iframe falhou em carregar */ break; case "iframe_timeout_error": /* excedeu timeoutMs */ break; case "already_open_error": /* outro checkout já está aberto */ break; case "network_error": /* problema de rede transiente falando com a origem do checkout */ break; case "api_error": /* backend retornou não-2xx para uma chamada emitida pelo SDK */ break; } }, });

sdk.openRefundRequest() lança somente invalid_request_error (token / args ausentes ou inválidos), de forma síncrona. iframe_load_error (o iframe de pedido de reembolso falhou em carregar) é entregue de forma assíncrona via onError, não lançado. Ele não emite iframe_timeout_error nem already_open_error — o popup de pedido de reembolso não tem load-timeout e permite múltiplos popups concorrentes.

Notas sobre os modos

  • Overlay centralizado com um backdrop escuro semi-transparente
  • z-index: 2147483647 (max int32) — fica acima de tudo
  • Scroll do body é travado enquanto aberto; restaurado no fechamento
  • Botão de fechar pega o foco inicial; Tab é trapeado no popup
  • Fechado por: botão de fechar, Escape, clique fora, sdk.close(). Todos eles chamam onCancel
  • A página de checkout pode pedir resize via postMessage — o SDK limita dentro dos limites de width/height

Redirect

  • Navegação completa via window.location.href
  • Anexa automaticamente ?return_url=<página-atual> para que o comprador volte ao lugar de onde veio. Se a sua success_url / cancel_url na sessão já cobrem isso, a viagem de ida e volta ignora return_url

Embed

  • iframe com allow="payment; clipboard-write" (diretivas HTML5 Feature Policy — não o atributo sandbox). O iframe é servido da origem do checkout, então popups de carteira e escritas no clipboard do lado do comprador funcionam sem opt-in adicional.
  • Largura do container é 100%; altura faz auto-resize via postMessage INFRAIO_RESIZE, limitada a [200, 2000]px
  • Sem isolamento CSS além da fronteira do iframe — os estilos da página pai não vazam para dentro
  • Sempre conecte onReady para você poder esconder o seu próprio estado de carregamento quando o checkout fica interativo

TypeScript

Todos os tipos vêm embutidos. Exports mais úteis:

import type { CheckoutOptions, RefundRequestOptions, LoadOptions, InfraIoInstance, InfraIoErrorCode, } from "@lartech/infraio-checkout-js"; import { loadInfraIo, InfraIoError, VERSION } from "@lartech/infraio-checkout-js";

VERSION é a string de versão do próprio SDK — útil em bug reports.

Próximos passos

  • Wrappers para React / Vue — planejados para a iteração pós-lançamento, uma vez que a superfície JS vanilla estabilize entre os lojistas-piloto. O SDK vanilla funciona bem dentro do React hoje; os wrappers só vão remover o useRef manual + o plumbing de ciclo de vida.
  • Resumo de sessão entre abas — abre o checkout na aba A, termina na aba B. Útil quando um comprador segue um magic-link no meio do fluxo. Rastreado para o próximo minor release.
  • Theming via CSS variables — expor um pequeno conjunto de design tokens (raio, cor de acento) no iframe para que lojistas consigam combinar a marca sem forkar a página.
  • Helpers do lado do servidor — um pacote minúsculo @lartech/infraio-server expondo verifyWebhook() + signedRequest() para que código de backend não precise copiar o ritual HMAC. Até ele chegar, a página de verificação de assinatura lista implementações drop-in em TypeScript, Go, Python e Ruby.