skill-cobranca-automatizada-saas-abacatepay
When To Use
This skill covers the complete automated billing system ("cobranca automatizada") for Brazilian SaaS products using AbacatePay. Use when implementing or maintaining:
=== Provisioning ===
- Billing configuration tables (cobrancas, cobranca_reguas, billing_config, etc.)
- Dunning rule sequencing (cobranca_regua_eventos)
- Encrypted integration configs (Resend, Evolution API, AbacatePay)
=== Billing Engine ===
- Automated invoice generation and dunning execution via cron
- AbacatePay billing creation (PIX + CARD)
- Webhook processing with HMAC-SHA256 verification
- Invoice state machine (pending, paid, overdue, cancelled, refunded)
- Subscription/plan integration via cobranca_tracking
=== Trial Management ===
- Configurable trial duration
- Pre-expiration notifications (7/3/1 days before)
- Automatic trial expiration and account blocking
=== Interfaces ===
- Public invoice page (FaturaPage) with PIX QR Code, payment link, polling
- Pricing/Plans page with AbacatePay checkout
- User-side invoice listing (MinhasCobrancasSection)
- Admin billing management (cobranças CRUD, planos CRUD, global settings)
- Plan Manager (PlanManager) for user plan changes
=== Notifications ===
- Email via Resend with HTML templates (logo, badge, invoice details)
- WhatsApp via Evolution API with template variables
- Variables: {{nome}}, {{plano}}, {{valor}}, {{vencimento}}, {{link_pagamento}}, {{empresa_nome}}
- Dunning sequence: configurable events with days_apos_vencimento, channel (email/whatsapp/ambos)
Architecture
+-------------------+
| Cron (8/12/16h |
| BRT + 5min) |
+--------+----------+
|
+--------------------+--------------------+
| | |
Processar Trial Metrics
Cobranças Notificações (meia-noite)
| |
+-----v------+ +-----v------+
| Ver regua | | Trial exp. |
| Send notif | | Notif pre |
| Create bill | +------------+
+-----+------+
|
+-----v------------------------------------------+
| Controller Layer |
| cobrancas.ts | abacatepay-webhook.ts |
| fatura.ts | trial.ts |
+-----+----------------------------+--------------+
| |
+-----v----------+ +--------v---------+
| AbacatePay | | Notifications |
| API v2 | | Resend + Evol. |
+----------------+ +------------------+
|
+-----v----------+
| Supabase/ |
| PostgreSQL |
+----------------+
Billing State Machine
pending ──► paid ──► refunded
│
├──► overdue ──► paid
│ └──► cancelled
│
└──► cancelled
States managed by invoice-state-machine.ts:
pending: cobrança criada, aguardando pagamento
paid: paga, released_at setado, conteúdo liberado
overdue: vencida, entra na régua de cobrança
cancelled: cancelada manualmente ou por expiração
refunded: estornada (transição exclusiva de paid)
Key Tables
| Table |
Purpose |
cobrancas |
Core billing records per user |
cobranca_reguas |
Dunning rule sets per tenant |
cobranca_regua_eventos |
Individual dunning events in sequence |
billing_config |
Encrypted integration configs (Resend, Evolution, AbacatePay) |
front_users |
User profiles with plan and status |
partner_billing_config |
Partner-specific billing overrides |
cobranca_tracking |
Subscription-like recurring billing tracking |
transaction_log |
Billing operation audit log |
abacatepay_events |
Raw webhook event storage |
Full details in billing-tables.md.
Core Flows
Dunning Flow (Régua de Cobrança)
- Cron runs billing-cron.ts at 8h/12h/16h BRT
- Queries cobrancas WHERE status = 'overdue' AND NOT paga
- For each cobranca, resolves billing_config + cobranca_regua + cobranca_regua_eventos
- Checks if next evento should fire (based on dias_apos_vencimento)
- Sends notification via billing-sender.ts (email + WhatsApp)
- If all eventos fired and still overdue, marks as cancelled
Webhook Flow
- POST /api/abacatepay-webhook receives event
- HMAC-SHA256 signature verification (replay + timing-safe compare)
- Rate limited: 100 req/min per IP
- On
billing.paid: processPaymentWithTransaction updates cobranca + cobranca_tracking
- On failure: processRollback reverts state
- Raw event stored in abacatepay_events
Trial Flow
- trial-cron.ts runs every 5 minutes
- Queries users where trial ends within notification window
- Sends pre-expiration notifications (7/3/1 day before)
- On expiration: blocks account (status = blocked)
- billing-cron.ts also handles trial notifications at 8/12/16h
Invoice Portal Flow
- FaturaPage loads by shortlink (8 chars, unique)
- Materializes billing from AbacatePay API on demand
- Shows: PIX QR Code, payment link, due date, amount, status badge
- Polls status every 5 seconds
- "Share via WhatsApp" button with pre-formatted message
Configuration
billing_config stores encrypted credentials per owner (AES-256-GCM):
resend_config: Resend API key + from email
evolution_config: Evolution API URL + API key + instance
abacatepay_config: AbacatePay API key
trial_duration_days: Trial length (default)
- Encryption key: BILLING_CONFIG_ENCRYPTION_KEY env var
See billing-config.md for full schema and setup.
Guardrails
- Keep ALL payment provider secrets server-side. Never expose AbacatePay API keys in browser bundles.
- Process webhooks idempotently: check cobranca current state before mutating.
- Treat checkout redirect as advisory. Grant access only after webhook confirmation.
- Do not log API keys, webhook secrets, full CPF/CNPJ, full phone numbers.
- Cron must not overlap. billing-cron uses lock checks to prevent concurrent runs.
- Dunning notifications must respect channel preference (email, whatsapp, or ambos).
- Trial expiration is irreversible: set status = blocked, do not auto-unblock without payment.
- Metrics queries (MRR, faturamento) should use aggregateBillingMetrics(), not ad-hoc SQL.
Local Reference (example-saas)
This skill is extracted from the example-saas SaaS billing system. The production codebase is at:
{{USER_HOME}}/Documents/Code/example-saas/server/controllers/cobrancas.ts — billing CRUD + processing + dunning
{{USER_HOME}}/Documents/Code/example-saas/server/controllers/abacatepay-webhook.ts — webhook handler
{{USER_HOME}}/Documents/Code/example-saas/server/controllers/fatura.ts — invoice lookup by shortlink
{{USER_HOME}}/Documents/Code/example-saas/server/controllers/trial.ts — trial expiration processing
{{USER_HOME}}/Documents/Code/example-saas/server/services/abacatepay-create-billing-v2.ts — AbacatePay billing creation
{{USER_HOME}}/Documents/Code/example-saas/server/services/billing-sender.ts — notification dispatch (email + WhatsApp)
{{USER_HOME}}/Documents/Code/example-saas/server/services/billing-email-template.ts — HTML invoice email template
{{USER_HOME}}/Documents/Code/example-saas/server/services/billing-integrations-config.ts — encrypted config management
{{USER_HOME}}/Documents/Code/example-saas/server/services/billing-metrics.ts — MRR and billing metrics
{{USER_HOME}}/Documents/Code/example-saas/server/utils/invoice-state-machine.ts — state machine logic
{{USER_HOME}}/Documents/Code/example-saas/server/cron/billing-cron.ts — main billing scheduler
{{USER_HOME}}/Documents/Code/example-saas/server/cron/trial-cron.ts — trial scheduler
{{USER_HOME}}/Documents/Code/example-saas/src/pages/FaturaPage.tsx — public invoice page
{{USER_HOME}}/Documents/Code/example-saas/src/components/PlansPage.tsx — pricing/plans page
{{USER_HOME}}/Documents/Code/example-saas/src/components/PlanManager.tsx — user plan manager
{{USER_HOME}}/Documents/Code/example-saas/src/components/AdminCobrancas.tsx — admin billing CRUD
{{USER_HOME}}/Documents/Code/example-saas/src/components/AdminPlanos.tsx — admin plan CRUD
{{USER_HOME}}/Documents/Code/example-saas/src/components/AdminGlobalSettings.tsx — global settings
{{USER_HOME}}/Documents/Code/example-saas/src/components/MinhasCobrancasSection.tsx — user invoice list
{{USER_HOME}}/Documents/Code/example-saas/supabase/migrations/20260617_cobrancas_foundation.sql — core tables
{{USER_HOME}}/Documents/Code/example-saas/supabase/migrations/20260617_cobrancas_website_final.sql — shortlink trigger
{{USER_HOME}}/Documents/Code/example-saas/supabase/migrations/20240101_billing_config.sql — billing_config table
{{USER_HOME}}/Documents/Code/example-saas/supabase/migrations/20240117_partner_billing.sql — partner billing
Reference Files
billing-tables.md — complete table schemas, indexes, enums, RLS policies
billing-flows.md — detailed flow diagrams and pseudocode for each core flow
billing-config.md — encryption, config resolution, and setup steps
billing-admin.md — admin interfaces and CRUD operations
billing-notifications.md — email/WhatsApp templates, dunning sequence, template variables
Validation
- After changes, run build and typecheck (npm run build, npm run typecheck or equivalent)
- Simulate webhook: POST billing.paid event and verify idempotent processing
- Test dunning: create overdue cobranca with regua de 0/3/7 dias and confirm notification dispatch
- Test trial: set trial_duration_days=1, create user, wait for pre-expiration and expiration
- Verify no AbacatePay/Resend/Evolution keys leak to browser bundles
- Run project lint when available
Related Skills
skill-abacatepay-integration — AbacatePay API specifics (billing create, list, webhook)
skill-saas-core-limits — plan limits, entitlements, feature flags after payment
skill-evolution-api — WhatsApp notification channel
skill-supabase-rls — RLS policies for billing tables
skill-saas-factory — top-level SaaS construction entry
1---2name: skill-cobranca-automatizada-saas-abacatepay-23description: Automatic SaaS billing engine with AbacatePay (PIX + credit card), configurable dunning (regua de cobranca), trial management, invoice portal, email (Resend) and WhatsApp (Evolution API) notifications, admin CRUD, and billing metrics. Covers the full billing lifecycle from provisioning to collection.4---56# skill-cobranca-automatizada-saas-abacatepay78## When To Use910This skill covers the complete automated billing system ("cobranca automatizada") for Brazilian SaaS products using AbacatePay. Use when implementing or maintaining:1112=== Provisioning ===13- Billing configuration tables (cobrancas, cobranca_reguas, billing_config, etc.)14- Dunning rule sequencing (cobranca_regua_eventos)15- Encrypted integration configs (Resend, Evolution API, AbacatePay)1617=== Billing Engine ===18- Automated invoice generation and dunning execution via cron19- AbacatePay billing creation (PIX + CARD)20- Webhook processing with HMAC-SHA256 verification21- Invoice state machine (pending, paid, overdue, cancelled, refunded)22- Subscription/plan integration via cobranca_tracking2324=== Trial Management ===25- Configurable trial duration26- Pre-expiration notifications (7/3/1 days before)27- Automatic trial expiration and account blocking2829=== Interfaces ===30- Public invoice page (FaturaPage) with PIX QR Code, payment link, polling31- Pricing/Plans page with AbacatePay checkout32- User-side invoice listing (MinhasCobrancasSection)33- Admin billing management (cobranças CRUD, planos CRUD, global settings)34- Plan Manager (PlanManager) for user plan changes3536=== Notifications ===37- Email via Resend with HTML templates (logo, badge, invoice details)38- WhatsApp via Evolution API with template variables39- Variables: {{nome}}, {{plano}}, {{valor}}, {{vencimento}}, {{link_pagamento}}, {{empresa_nome}}40- Dunning sequence: configurable events with days_apos_vencimento, channel (email/whatsapp/ambos)4142## Architecture4344```45 +-------------------+46 | Cron (8/12/16h |47 | BRT + 5min) |48 +--------+----------+49 |50 +--------------------+--------------------+51 | | |52 Processar Trial Metrics53 Cobranças Notificações (meia-noite)54 | |55 +-----v------+ +-----v------+56 | Ver regua | | Trial exp. |57 | Send notif | | Notif pre |58 | Create bill | +------------+59 +-----+------+60 |61 +-----v------------------------------------------+62 | Controller Layer |63 | cobrancas.ts | abacatepay-webhook.ts |64 | fatura.ts | trial.ts |65 +-----+----------------------------+--------------+66 | |67 +-----v----------+ +--------v---------+68 | AbacatePay | | Notifications |69 | API v2 | | Resend + Evol. |70 +----------------+ +------------------+71 |72 +-----v----------+73 | Supabase/ |74 | PostgreSQL |75 +----------------+76```7778## Billing State Machine7980```81pending ──► paid ──► refunded82 │83 ├──► overdue ──► paid84 │ └──► cancelled85 │86 └──► cancelled87```8889States managed by `invoice-state-machine.ts`:90- `pending`: cobrança criada, aguardando pagamento91- `paid`: paga, `released_at` setado, conteúdo liberado92- `overdue`: vencida, entra na régua de cobrança93- `cancelled`: cancelada manualmente ou por expiração94- `refunded`: estornada (transição exclusiva de `paid`)9596## Key Tables9798| Table | Purpose |99|---|---|100| `cobrancas` | Core billing records per user |101| `cobranca_reguas` | Dunning rule sets per tenant |102| `cobranca_regua_eventos` | Individual dunning events in sequence |103| `billing_config` | Encrypted integration configs (Resend, Evolution, AbacatePay) |104| `front_users` | User profiles with plan and status |105| `partner_billing_config` | Partner-specific billing overrides |106| `cobranca_tracking` | Subscription-like recurring billing tracking |107| `transaction_log` | Billing operation audit log |108| `abacatepay_events` | Raw webhook event storage |109110Full details in `billing-tables.md`.111112## Core Flows113114### Dunning Flow (Régua de Cobrança)1151. Cron runs billing-cron.ts at 8h/12h/16h BRT1162. Queries cobrancas WHERE status = 'overdue' AND NOT paga1173. For each cobranca, resolves billing_config + cobranca_regua + cobranca_regua_eventos1184. Checks if next evento should fire (based on dias_apos_vencimento)1195. Sends notification via billing-sender.ts (email + WhatsApp)1206. If all eventos fired and still overdue, marks as cancelled121122### Webhook Flow1231. POST /api/abacatepay-webhook receives event1242. HMAC-SHA256 signature verification (replay + timing-safe compare)1253. Rate limited: 100 req/min per IP1264. On `billing.paid`: processPaymentWithTransaction updates cobranca + cobranca_tracking1275. On failure: processRollback reverts state1286. Raw event stored in abacatepay_events129130### Trial Flow1311. trial-cron.ts runs every 5 minutes1322. Queries users where trial ends within notification window1333. Sends pre-expiration notifications (7/3/1 day before)1344. On expiration: blocks account (status = blocked)1355. billing-cron.ts also handles trial notifications at 8/12/16h136137### Invoice Portal Flow1381. FaturaPage loads by shortlink (8 chars, unique)1392. Materializes billing from AbacatePay API on demand1403. Shows: PIX QR Code, payment link, due date, amount, status badge1414. Polls status every 5 seconds1425. "Share via WhatsApp" button with pre-formatted message143144## Configuration145146billing_config stores encrypted credentials per owner (AES-256-GCM):147- `resend_config`: Resend API key + from email148- `evolution_config`: Evolution API URL + API key + instance149- `abacatepay_config`: AbacatePay API key150- `trial_duration_days`: Trial length (default)151- Encryption key: BILLING_CONFIG_ENCRYPTION_KEY env var152153See `billing-config.md` for full schema and setup.154155## Guardrails1561571. Keep ALL payment provider secrets server-side. Never expose AbacatePay API keys in browser bundles.1582. Process webhooks idempotently: check cobranca current state before mutating.1593. Treat checkout redirect as advisory. Grant access only after webhook confirmation.1604. Do not log API keys, webhook secrets, full CPF/CNPJ, full phone numbers.1615. Cron must not overlap. billing-cron uses lock checks to prevent concurrent runs.1626. Dunning notifications must respect channel preference (email, whatsapp, or ambos).1637. Trial expiration is irreversible: set status = blocked, do not auto-unblock without payment.1648. Metrics queries (MRR, faturamento) should use aggregateBillingMetrics(), not ad-hoc SQL.165166## Local Reference (example-saas)167168This skill is extracted from the example-saas SaaS billing system. The production codebase is at:169170- `{{USER_HOME}}/Documents/Code/example-saas/server/controllers/cobrancas.ts` — billing CRUD + processing + dunning171- `{{USER_HOME}}/Documents/Code/example-saas/server/controllers/abacatepay-webhook.ts` — webhook handler172- `{{USER_HOME}}/Documents/Code/example-saas/server/controllers/fatura.ts` — invoice lookup by shortlink173- `{{USER_HOME}}/Documents/Code/example-saas/server/controllers/trial.ts` — trial expiration processing174- `{{USER_HOME}}/Documents/Code/example-saas/server/services/abacatepay-create-billing-v2.ts` — AbacatePay billing creation175- `{{USER_HOME}}/Documents/Code/example-saas/server/services/billing-sender.ts` — notification dispatch (email + WhatsApp)176- `{{USER_HOME}}/Documents/Code/example-saas/server/services/billing-email-template.ts` — HTML invoice email template177- `{{USER_HOME}}/Documents/Code/example-saas/server/services/billing-integrations-config.ts` — encrypted config management178- `{{USER_HOME}}/Documents/Code/example-saas/server/services/billing-metrics.ts` — MRR and billing metrics179- `{{USER_HOME}}/Documents/Code/example-saas/server/utils/invoice-state-machine.ts` — state machine logic180- `{{USER_HOME}}/Documents/Code/example-saas/server/cron/billing-cron.ts` — main billing scheduler181- `{{USER_HOME}}/Documents/Code/example-saas/server/cron/trial-cron.ts` — trial scheduler182- `{{USER_HOME}}/Documents/Code/example-saas/src/pages/FaturaPage.tsx` — public invoice page183- `{{USER_HOME}}/Documents/Code/example-saas/src/components/PlansPage.tsx` — pricing/plans page184- `{{USER_HOME}}/Documents/Code/example-saas/src/components/PlanManager.tsx` — user plan manager185- `{{USER_HOME}}/Documents/Code/example-saas/src/components/AdminCobrancas.tsx` — admin billing CRUD186- `{{USER_HOME}}/Documents/Code/example-saas/src/components/AdminPlanos.tsx` — admin plan CRUD187- `{{USER_HOME}}/Documents/Code/example-saas/src/components/AdminGlobalSettings.tsx` — global settings188- `{{USER_HOME}}/Documents/Code/example-saas/src/components/MinhasCobrancasSection.tsx` — user invoice list189- `{{USER_HOME}}/Documents/Code/example-saas/supabase/migrations/20260617_cobrancas_foundation.sql` — core tables190- `{{USER_HOME}}/Documents/Code/example-saas/supabase/migrations/20260617_cobrancas_website_final.sql` — shortlink trigger191- `{{USER_HOME}}/Documents/Code/example-saas/supabase/migrations/20240101_billing_config.sql` — billing_config table192- `{{USER_HOME}}/Documents/Code/example-saas/supabase/migrations/20240117_partner_billing.sql` — partner billing193194## Reference Files195196- `billing-tables.md` — complete table schemas, indexes, enums, RLS policies197- `billing-flows.md` — detailed flow diagrams and pseudocode for each core flow198- `billing-config.md` — encryption, config resolution, and setup steps199- `billing-admin.md` — admin interfaces and CRUD operations200- `billing-notifications.md` — email/WhatsApp templates, dunning sequence, template variables201202## Validation203204- After changes, run build and typecheck (npm run build, npm run typecheck or equivalent)205- Simulate webhook: POST billing.paid event and verify idempotent processing206- Test dunning: create overdue cobranca with regua de 0/3/7 dias and confirm notification dispatch207- Test trial: set trial_duration_days=1, create user, wait for pre-expiration and expiration208- Verify no AbacatePay/Resend/Evolution keys leak to browser bundles209- Run project lint when available210211## Related Skills212213- `skill-abacatepay-integration` — AbacatePay API specifics (billing create, list, webhook)214- `skill-saas-core-limits` — plan limits, entitlements, feature flags after payment215- `skill-evolution-api` — WhatsApp notification channel216- `skill-supabase-rls` — RLS policies for billing tables217- `skill-saas-factory` — top-level SaaS construction entry