Pular para o conteúdo principal

Payments

Integracao de deposito e saque no template. Suporta PIX (Brasil), SPEI/OXXO (Mexico), Wallet/MACH (Chile), Credit Card, Checkout Page, Redirect e outros metodos via @cactus-agents/lotus-payments.

Arquitetura​

usePayments() hook
|
+---> Store Zustand (payments.ts)
+---> API Routes (server-side, token HttpOnly)
| |
| v
| @cactus-agents/lotus-payments (SDK)
| |
| v
| Backend API
|
+---> Componentes (DepositModal, WithdrawModal)

Como o token JWT fica em cookie HttpOnly, todas as chamadas de pagamento passam por API routes no servidor.

Arquivos principais​

ArquivoTipoDescricao
store/payments.tsStore (Zustand)Estado dos modais, providers, metodo selecionado, cupom
hooks/usePayments.tsHookOrquestra fetch providers, submit deposit/withdraw, polling
config/deposit.config.tsConfigAtalhos de valor por moeda (fork-overridable)
components/payments/DepositModal.tsxComponentModal de deposito
components/payments/WithdrawModal.tsxComponentModal de saque
components/payments/LazyPaymentModals.tsxComponentLazy wrapper

Store — usePaymentsStore​

interface PaymentsState {
paymentModal: "deposit" | "withdraw" | null;
providers: PaymentProviders | null;
providersLoading: boolean;
selectedDepositMethod: PaymentMethodSlug | null;
selectedWithdrawMethod: PaymentMethodSlug | null;
depositLoading: boolean;
withdrawLoading: boolean;
coupon: CouponData | null;
}

Hook — usePayments()​

Retorna estado derivado e actions:

Estado derivado​

PropriedadeDescricao
depositMethodsProviders de deposito filtrados pela moeda da marca
withdrawMethodsProviders de saque filtrados pela moeda da marca
minDeposit / maxDepositLimites de deposito (do brand settings, fallback 100 / 4.900.000)
minWithdraw / maxWithdrawLimites de saque (do brand settings, fallback 100 / 50.000)
currency / countryMoeda e pais do ambiente

Actions​

ActionDescricao
fetchProviders()Busca providers disponiveis
submitDeposit(payload)Envia deposito
checkDepositStatus(transactionId)Polling do status do deposito
submitWithdraw(payload)Envia saque
fetchBankList()Lista de bancos disponiveis
fetchPixKey()Busca chave PIX do usuario
updatePixKey(payload)Atualiza chave PIX

API Routes​

RotaMetodoDescricao
api/payments/providersGETProviders de deposito/saque
api/payments/depositPOSTSubmit deposito
api/payments/deposit-statusPOSTStatus do deposito (polling)
api/payments/withdrawPOSTSubmit saque
api/payments/bank-listGETLista de bancos
api/payments/pix-keyPOSTGet/update chave PIX
api/payments/couponPOSTValidar cupom

Configuracao — deposit.config.ts​

Define atalhos de valor por moeda (fork-overridable):

export const depositConfig: DepositConfig = {
shortcuts: {
BRL: [
{ value: 20 }, { value: 50, hot: true }, { value: 100 },
{ value: 250, hot: true }, { value: 500 }, { value: 1000, hot: true },
],
MXN: [
{ value: 200 }, { value: 500 }, { value: 1000, hot: true },
{ value: 2500, hot: true }, { value: 5000 }, { value: 10000, hot: true },
],
CLP: [
{ value: 5000 }, { value: 20000, hot: true }, { value: 50000, hot: true },
{ value: 200000 }, { value: 400000, hot: true }, { value: 800000 },
],
PEN: [
{ value: 20 }, { value: 50, hot: true }, { value: 100 },
{ value: 250, hot: true }, { value: 500 }, { value: 1000, hot: true },
],
EUR: [
{ value: 10 }, { value: 25, hot: true }, { value: 50 },
{ value: 100, hot: true }, { value: 250 }, { value: 500, hot: true },
],
// ARS, COP, UYU, INR...
},
defaultShortcuts: [
{ value: 20 }, { value: 50, hot: true }, { value: 100 },
{ value: 250, hot: true }, { value: 500 }, { value: 1000, hot: true },
],
};

Moedas com atalhos: BRL, MXN, ARS, CLP, COP, UYU, INR, PEN, EUR. Moedas sem configuracao usam defaultShortcuts.

Componentes de deposito​

DepositModal​

Fluxo completo de deposito com routing automatico de resultado baseado no tipo de metodo:

  1. MethodSelector — selecao do metodo
  2. DepositForm — valor + campo especifico do metodo (+ CreditCardFields para credit-card-2)
  3. Resultado — roteado automaticamente pelo classificador do SDK:
ClassificadorComponenteDescricao
isPixMethodDepositResultPixQR code + copia-e-cola + countdown + polling
isSpeiMethodDepositResultSpeiCLABE + barcode + countdown
isWalletMethodDepositResultWalletQR + deep-link (MACH) + countdown + polling
isCheckoutPageMethodDepositResultCheckoutPageIframe com checkout_page (credit-card, bank-transfer, khipu)
isCreditCardFormMethodDepositResultCreditCardTela de confirmacao pos-submit
isRedirectMethodDepositResultRedirectIframe com URL (astropay, worldline, prontopaga, crypto)
isExternalRedirectMethodDepositResultExternalRedirectAbre nova aba + tela informativa

WithdrawModal​

  1. MethodSelector — selecao do metodo
  2. WithdrawForm — valor + dados especificos:
    • PIX: PixKeySelector (tipo + valor da chave)
    • SPEI: tipo de conta (CLABE/debito/telefone) + numero
    • Bank-transfer (CHL): tipo de conta + codigo banco + numero
    • Wallet (CHL): info do usuario (email + documento)
    • AstroPay: telefone com DDI
  3. WithdrawConfirm — confirmacao e senha

Componentes compartilhados​

  • CurrencyInput — input de valor com mascara de moeda. Aceita countryCodeAlpha3 opcional para resolucao de flag. Usa @cactus-agents/lotus-country-config (getCountriesByCurrency, getCountryByAlpha3) para descobrir o pais a partir da moeda.
  • AmountShortcuts — botoes de atalho de valor
  • CopyableField — campo com botao de copiar (para PIX, CLABE)
  • PixKeySelector — seletor de tipo de chave PIX
  • CreditCardFields — formulario de cartao (numero, nome, vencimento, CVV) com icones de bandeiras
  • DepositCoupon — campo de cupom promocional

Icones de pagamento​

Os icones SVG dos metodos de pagamento sao fornecidos pelo pacote @cactus-agents/lotus-payments/icons/. Um plugin Vite (copyPaymentIcons em vite.config.ts) copia automaticamente os icones para public/icons/ no build e dev server.

A pasta public/icons/payments/ esta no .gitignore — nao precisa commitar os icones, eles sao auto-gerados.

Para adicionar novos icones, coloque o SVG em front-lotus-core/packages/payments/icons/payments/ e publique uma nova versao do pacote.

Abrindo o modal programaticamente​

import { usePaymentsStore } from "~/store/payments";

const openPaymentModal = usePaymentsStore((s) => s.openPaymentModal);

openPaymentModal("deposit"); // abre deposito
openPaymentModal("withdraw"); // abre saque