Pular para o conteúdo principal

@cactus-agents/payments

SDK framework-agnostic para providers de pagamento, deposito e saque multi-pais (PIX/SPEI/Wallet/CreditCard/Redirect, bank-list, chave PIX, contas MX/CHL).

Instalacao

pnpm add @cactus-agents/payments

Uso recomendado

Use createPaymentsFromClient quando voce ja estiver usando @cactus-agents/api-client:

import { createApiClient } from "@cactus-agents/api-client";
import { createPaymentsFromClient } from "@cactus-agents/payments";

const client = createApiClient({ baseUrl, tenant, language });
const payments = createPaymentsFromClient(client);

const providers = await payments.getPaymentProviders();
// providers.deposit, providers.withdraw

API publica

Exports principais:

  • createPaymentsService(fetcher)
  • createPaymentsFromClient(client)
  • getPaymentProviders(), submitDeposit(payload), checkDepositStatus(transactionId), submitWithdraw(payload)
  • getBankList(), getPixKey(), updatePixKey(payload), getMexBankAccount(), storeMexBankAccount(payload), getGenericBankAccount(), storeGenericBankAccount(payload)
  • Transforms: transformPaymentProviders, transformPaymentProvider, transformDepositResponse, transformWithdrawResponse, buildDepositPayload, buildWithdrawPayload, transformPixKey, buildPixKeyUpdatePayload, transformMexBankAccount, buildMexBankAccountPayload, transformGenericBankAccount, buildGenericBankAccountPayload, transformBankListItem, resolvePaymentIconUrl
  • Classificadores: isPixMethod, isSpeiMethod, isPhoneMethod, isRedirectMethod, isCheckoutPageMethod, isCreditCardFormMethod, isWalletMethod, isKushkiMethod, isBankTransferDepositMethod, isBankTransferWithdrawMethod, isExternalRedirectMethod, resolveCanonicalMethod
  • Outros helpers: filterProvidersByCurrency, normalizeDepositStatus
  • Catalogos de dados: CHL_BANKS, NGA_BANKS, CHL_ACCOUNT_TYPES, CHL_DEFAULT_ACCOUNT_TYPE

Tipos principais: PaymentProvider, PaymentProviders, PaymentMethodSlug, DepositPayload, DepositResult, DepositChargeStatus, WithdrawPayload, WithdrawResult, PixKey, PixKeyType, PixKeyUpdatePayload, MexBankAccount(+Payload), GenericBankAccount(+Payload), BankListItem, ChlAccountType, ChlAccountTypeOption, HubPaymentMethod, HubPaymentMethodRaw, PaymentStatusV3, PaymentsService, PaymentsFetcher.

Referencia de exports: front-cactus-core/packages/payments/src/index.ts.

Metodos de pagamento suportados

SlugTipoPaisDescricao
pix, pixtopay, paybrokers, anspacepay, pay2free, riopag, paag, triopay, starkbank, efibank, genialbank, iuguPIX-likeBRQR code + copia-e-cola + polling
speiSPEIMXTransferencia bancaria (CLABE)
oxxoOXXOMXPagamento em loja (barcode)
credit-cardCheckout PageCHL/MX/PER/FINIframe com gateway de pagamento
bank-transferCheckout PageCHLIframe com gateway bancario
khipuCheckout PageCHLIframe Khipu
dusupay, korapayCheckout PageNGIframe gateway agregador (bank transfer / USSD / mobile money / card)
credit-card-2, credit-card-prontopagaCard FormCHL/MXFormulario de cartao no frontend
walletWallet/MACHCHLQR + deep-link (app_link) + polling
astropayRedirectMultiIframe AstroPay
worldlineRedirectMultiIframe Worldline
prontopagaRedirectMultiIframe ProntoPaga
cryptoRedirectMultiIframe crypto
webpay, bitfeverExternal RedirectCHLAbre nova aba
trioRedirectPER/FINTrio payments

Classificadores de metodo

isPixMethod("pix") // true — QR + brCode + polling
isSpeiMethod("spei") // true — CLABE + barcode
isPhoneMethod("astropay") // true — requer telefone no saque
isRedirectMethod("astropay") // true — iframe com URL
isCheckoutPageMethod("credit-card") // true — iframe com checkout_page
isCreditCardFormMethod("credit-card-2") // true — form de cartao
isKushkiMethod("kushki") // true — gateway Kushki
isWalletMethod("wallet") // true — app_link + QR
isBankTransferDepositMethod("bank-transfer") // true — deposito por transferencia
isBankTransferWithdrawMethod("bank-transfer") // true — conta bancaria generica
isExternalRedirectMethod("webpay") // true — abre nova aba

resolveCanonicalMethod(slug)

Todos os classificadores acima passam o slug por resolveCanonicalMethod antes de testar, então variantes sufixadas pelo backend continuam classificando certo:

  1. match exato num slug conhecido;
  2. prefixo mais longo, com limite de segmento - (credit-card-2-abccredit-card-2, e nunca credit-card);
  3. sem match, devolve o slug original (cai no fallback).

O limite de segmento evita falso positivo: pixel não casa pix, porque o caractere após pix seria e e não -.

normalizeDepositStatus(raw)

Normaliza o status de charge/withdraw para DepositChargeStatus, aceitando os três dialetos que o backend produz:

  • legado lowercase — approved, pending, processing, expired, denied;
  • v3 em PT (uppercase) — PAGO, AGUARDANDO_PAGAMENTO, EM_LIQUIDACAO, FALHA_NA_INTEGRACAO, …;
  • v3 em EN (uppercase) — PAID, AWAITING_PAYMENT, SETTLING, LAPSED, PROVIDER_REJECTED, …

Valor desconhecido cai em "pending" de propósito — o polling continua rodando em vez de resolver falsamente. Os valores crus v3 estão tipados como PaymentStatusV3.

Catálogos de dados

CHL_BANKS e NGA_BANKS são as listas de banco embutidas no pacote (usadas quando o país não tem bank-list no BFF). CHL_ACCOUNT_TYPES (+ CHL_DEFAULT_ACCOUNT_TYPE, ChlAccountType, ChlAccountTypeOption) são os tipos de conta do formulário chileno. Não replique essas listas no base.

Icones de pagamento

Os icones SVG dos metodos de pagamento ficam dentro do pacote em @cactus-agents/payments/icons/payments/. O transformPaymentProvider() aplica automaticamente resolvePaymentIconUrl() para converter o slug da API (ex: payments/pix) em URL absoluta (ex: /icons/payments/pix.svg).

No front-web-base, um plugin Vite (copyPaymentIcons) copia os icones do pacote para public/icons/ automaticamente no build e dev server.

import { resolvePaymentIconUrl } from "@cactus-agents/payments";

resolvePaymentIconUrl("payments/pix"); // "/icons/payments/pix.svg"
resolvePaymentIconUrl("payments/pix", "/assets"); // "/assets/payments/pix.svg"

DepositPayload

Shape canonico do payload aceito por submitDeposit() / buildDepositPayload(). O builder converte camelCase → snake_case antes de enviar pro BFF (POST /wallet/add-credit).

interface DepositPayload {
userId: number;
/** Valor em centavos. */
creditAmount: number;
paymentMethod: PaymentMethodSlug;
currency: string;
couponCode?: string;

// ─── Tracking de marketing (paridade com legado Nuxt) ─────────────────
// Anexados pelo template no `DepositModal` a partir do cookie
// `cookie_tracking` + `_ga`. Detalhes em
// → ../architecture/marketing-tracking.md
utmCampaign?: string;
utmSource?: string;
utmMedium?: string;
utmContent?: string;
gaClientId?: string;

/** Campos de cartao de credito (apenas `credit-card-2` / `credit-card-prontopaga`). */
cardNumber?: string;
cardName?: string;
cardExpiryMonth?: string;
cardExpiryYear?: string;
cardCvv?: string;
}

:::caution Paridade estrita: src NAO vai no deposit Diferente do signup, o deposit nao envia src (first-touch source). Nenhum dos quatro projetos legado (base, 7k, cassino, vera) jamais incluiu src em /wallet/add-credit. Manter essa distincao evita quebrar dashboards de BI calibrados na atribuicao legacy.

Se voce ver um pull request adicionando utmSrc ou src ao DepositPayload / buildDepositPayload, bloqueie ate validar com BI/backoffice. Existe um teste em packages/payments/src/__tests__/transform.test.ts que falha intencionalmente caso o campo seja reintroduzido. :::

affiliation_code e app_source tambem nao sao enviados no deposit — so no signup.

Endpoints do PaymentsService

MetodoEndpointObservacao
getPaymentProviders()GET /payment-providersProviders deposit/withdraw por pais
submitDeposit(payload)POST /wallet/add-creditDeposito (payload em snake_case)
checkDepositStatus(transactionId)GET /wallet/charge/{transactionId}Status do deposito (polling)
submitWithdraw(payload)POST /new-withdrawsSaque (PIX, SPEI, bank, phone)
getBankList()GET /bff/users/bank-listLista de bancos
getPixKey()POST /pix-keys/user-keyBR — chave PIX do usuario
updatePixKey(payload)POST /pix-keys/update-user-key-v2BR — atualizar chave PIX
getMexBankAccount()GET /mex-bank-accounts/user-accountMX — conta do usuario
storeMexBankAccount(payload)POST /mex-bank-accounts/storeMX — salvar conta
getGenericBankAccount()GET /generic-bank-accounts/user-accountCHL — conta bancaria generica
storeGenericBankAccount(payload)POST /generic-bank-accounts/storeCHL — salvar conta generica

Os dois endpoints de conta generica espelham o par de MX (/mex-bank-accounts/*), nao o shape /bff/users/*.

Integracao no front-web-base

Quando o token fica em cookie HttpOnly, as chamadas de deposito/saque passam por API routes no servidor. O template expoe:

  • Rotas: api.payments.providers, api.payments.deposit, api.payments.deposit-status, api.payments.withdraw, api.payments.bank-list, api.payments.pix-key
  • Store Zustand payments.ts (providers, estado do modal)
  • Hook usePayments (submit deposit/withdraw, polling de status)
  • Componentes: DepositModal, WithdrawModal, DepositForm, WithdrawForm, resultados PIX/SPEI/Wallet/CheckoutPage/CreditCard/Redirect/ExternalRedirect

Carteira e historico de transacoes usam @cactus-agents/accounts (rotas api.wallet.*) — o antigo @cactus-agents/wallet foi absorvido por ele.