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/payments.
Arquitetura
usePayments() hook
|
+---> Store Zustand (payments.ts)
+---> API Routes (server-side, token HttpOnly)
| |
| v
| @cactus-agents/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
| Arquivo | Tipo | Descricao |
|---|---|---|
store/payments.ts | Store (Zustand) | Estado dos modais, providers, metodo selecionado, cupom |
hooks/usePayments.ts | Hook | Orquestra fetch providers, submit deposit/withdraw, polling |
config/deposit.config.ts | Config | Atalhos de valor por moeda (fork-overridable) |
components/payments/DepositModal.tsx | Component | Modal de deposito |
components/payments/WithdrawModal.tsx | Component | Modal de saque |
components/payments/LazyPaymentModals.tsx | Component | Lazy 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
| Propriedade | Descricao |
|---|---|
depositMethods | Providers de deposito filtrados pela moeda da marca |
withdrawMethods | Providers de saque filtrados pela moeda da marca |
minDeposit / maxDeposit | Limites de deposito (do brand settings, fallback 100 / 4.900.000) |
minWithdraw / maxWithdraw | Limites de saque (do brand settings, fallback 100 / 50.000) |
currency / country | Moeda e pais do ambiente |
Actions
| Action | Descricao |
|---|---|
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
| Rota | Metodo | Descricao |
|---|---|---|
api/payments/providers | GET | Providers de deposito/saque |
api/payments/deposit | POST | Submit deposito |
api/payments/deposit-status | POST | Status do deposito (polling) |
api/payments/withdraw | POST | Submit saque |
api/payments/bank-list | GET | Lista de bancos |
api/payments/pix-key | POST | Get/update chave PIX |
api/payments/coupon | POST | Validar 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:
MethodSelector— selecao do metodoDepositForm— valor + campo especifico do metodo (+CreditCardFieldspara credit-card-2)- Resultado — roteado automaticamente pelo classificador do SDK:
| Classificador | Componente | Descricao |
|---|---|---|
isPixMethod | DepositResultPix | QR code + copia-e-cola + countdown + polling |
isSpeiMethod | DepositResultSpei | CLABE + barcode + countdown |
isWalletMethod | DepositResultWallet | QR + deep-link (MACH) + countdown + polling |
isCheckoutPageMethod | DepositResultCheckoutPage | Iframe com checkout_page (credit-card, bank-transfer, khipu) |
isCreditCardFormMethod | DepositResultCreditCard | Tela de confirmacao pos-submit |
isRedirectMethod | DepositResultRedirect | Iframe com URL (astropay, worldline, prontopaga, crypto) |
isExternalRedirectMethod | DepositResultExternalRedirect | Abre nova aba + tela informativa |
WithdrawModal
MethodSelector— selecao do metodoWithdrawForm— 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
- PIX:
WithdrawConfirm— confirmacao e senha
Componentes compartilhados
CurrencyInput— input de valor com mascara de moeda. AceitacountryCodeAlpha3opcional para resolucao de flag. Usa@cactus-agents/country-config(getCountriesByCurrency,getCountryByAlpha3) para descobrir o pais a partir da moeda.AmountShortcuts— botoes de atalho de valorCopyableField— campo com botao de copiar (para PIX, CLABE)PixKeySelector— seletor de tipo de chave PIXCreditCardFields— formulario de cartao (numero, nome, vencimento, CVV) com icones de bandeirasDepositCoupon— campo de cupom promocional
Icones de pagamento
Os icones SVG dos metodos de pagamento sao fornecidos pelo pacote @cactus-agents/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-cactus-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