skill-abacatepay-integration
Workflow
- Inspect the project backend boundary first: Netlify/Vercel function, Express route, server action, Edge Function, or other server-only layer.
- Keep all AbacatePay calls behind that backend boundary. Browser code calls the project API, never AbacatePay directly with secrets.
- Validate customer data before billing creation: email, cellphone with country code, CPF/CNPJ without punctuation, amount in cents, plan ID, and tenant/user identity.
- Create billing with stable metadata:
user_id, tenant_id, plan_id, internal correlation ID, and payment link token when present.
- Persist provider IDs, normalized status, amount, currency, raw event reference, and support/debug timestamps.
- Process webhooks idempotently, update entitlements from trusted backend evidence, and audit every access transition.
- Verify with local webhook tooling or provider test events plus project build/typecheck.
Current API Shape (v2)
Use API v2 for new work. API v1 remains only for legacy integrations:
- base URL:
https://api.abacatepay.com/v2
- hosted checkout:
POST /checkouts/create
- subscriptions:
POST /subscriptions/create
- transparent PIX/card/boleto checkout:
POST /transparents/create
- webhook management:
POST /webhooks/create
- auth header:
Authorization: Bearer <abacatepay-api-key>
- current checkout events:
checkout.completed, checkout.refunded, checkout.disputed
- current subscription events:
subscription.completed, subscription.renewed, subscription.cancelled
The old v1 routes such as /v1/billing/create and events such as billing.paid are legacy-compatible references. Do not copy them into new integrations; if maintaining v1, isolate an adapter and plan migration to v2.
Guardrails
- Keep
ABACATEPAY_API_KEY and webhook secrets server-side.
- Treat checkout redirect as advisory. Grant access only after trusted backend/webhook confirmation.
- Deduplicate webhook processing by the v2 event ID and the provider checkout/subscription ID.
- Do not log API keys, webhook secrets, full CPF/CNPJ, full phone numbers, or unnecessary PII.
- Keep plan and entitlement rules in local product tables, not encoded only in AbacatePay objects.
- Support retries and out-of-order delivery by re-reading local payment state before mutation.
Local Pattern
The example-saas project has a useful boundary pattern: frontend client calls a Netlify function, the function uses the server API key and service-role Supabase client, and the webhook updates users/plans after billing.paid.
Read {{USER_HOME}}/Documents\Code\example-saas\src\lib\abacatepay.ts only when implementing a similar client boundary or validating local conventions.
Validation
- Confirm no
ABACATEPAY_API_KEY or webhook secret appears in browser bundles or VITE_ variables.
- Simulate or replay
billing.paid and confirm idempotent entitlement update.
- Check invalid CPF/CNPJ, invalid cellphone, duplicate webhook, expired billing, and failed provider response paths.
- Run the project build/typecheck/lint when available.
- Confirm the integration uses the v2 payload shape (
apiVersion: 2) and does not assume the legacy billing.* event names.
Official References
Related Skills
skill-saas-factory
skill-saas-core-limits
skill-supabase-rls
skill-security-hooks
1---2name: skill-abacatepay-integration3description: Integrate AbacatePay PIX/card billing, customers, QRCode PIX, billing webhooks, CPF/CNPJ validation, BRL SaaS checkout, payment receipts, refunds, cancellations, and entitlement sync for Brazilian SaaS products.4---56# skill-abacatepay-integration78## Workflow9101. Inspect the project backend boundary first: Netlify/Vercel function, Express route, server action, Edge Function, or other server-only layer.112. Keep all AbacatePay calls behind that backend boundary. Browser code calls the project API, never AbacatePay directly with secrets.123. Validate customer data before billing creation: email, cellphone with country code, CPF/CNPJ without punctuation, amount in cents, plan ID, and tenant/user identity.134. Create billing with stable metadata: `user_id`, `tenant_id`, `plan_id`, internal correlation ID, and payment link token when present.145. Persist provider IDs, normalized status, amount, currency, raw event reference, and support/debug timestamps.156. Process webhooks idempotently, update entitlements from trusted backend evidence, and audit every access transition.167. Verify with local webhook tooling or provider test events plus project build/typecheck.1718## Current API Shape (v2)1920Use API v2 for new work. API v1 remains only for legacy integrations:21- base URL: `https://api.abacatepay.com/v2`22- hosted checkout: `POST /checkouts/create`23- subscriptions: `POST /subscriptions/create`24- transparent PIX/card/boleto checkout: `POST /transparents/create`25- webhook management: `POST /webhooks/create`26- auth header: `Authorization: Bearer <abacatepay-api-key>`27- current checkout events: `checkout.completed`, `checkout.refunded`, `checkout.disputed`28- current subscription events: `subscription.completed`, `subscription.renewed`, `subscription.cancelled`2930The old v1 routes such as `/v1/billing/create` and events such as `billing.paid` are legacy-compatible references. Do not copy them into new integrations; if maintaining v1, isolate an adapter and plan migration to v2.3132## Guardrails33341. Keep `ABACATEPAY_API_KEY` and webhook secrets server-side.352. Treat checkout redirect as advisory. Grant access only after trusted backend/webhook confirmation.363. Deduplicate webhook processing by the v2 event ID and the provider checkout/subscription ID.374. Do not log API keys, webhook secrets, full CPF/CNPJ, full phone numbers, or unnecessary PII.385. Keep plan and entitlement rules in local product tables, not encoded only in AbacatePay objects.396. Support retries and out-of-order delivery by re-reading local payment state before mutation.4041## Local Pattern4243The example-saas project has a useful boundary pattern: frontend client calls a Netlify function, the function uses the server API key and service-role Supabase client, and the webhook updates users/plans after `billing.paid`.4445Read `{{USER_HOME}}/Documents\Code\example-saas\src\lib\abacatepay.ts` only when implementing a similar client boundary or validating local conventions.4647## Validation4849- Confirm no `ABACATEPAY_API_KEY` or webhook secret appears in browser bundles or `VITE_` variables.50- Simulate or replay `billing.paid` and confirm idempotent entitlement update.51- Check invalid CPF/CNPJ, invalid cellphone, duplicate webhook, expired billing, and failed provider response paths.52- Run the project build/typecheck/lint when available.53- Confirm the integration uses the v2 payload shape (`apiVersion: 2`) and does not assume the legacy `billing.*` event names.5455## Official References5657- https://docs.abacatepay.com/pages/reference/introduction58- https://docs.abacatepay.com/pages/payment/create59- https://docs.abacatepay.com/pages/webhooks60- https://docs.abacatepay.com/pages/changelog6162## Related Skills6364- `skill-saas-factory`65- `skill-saas-core-limits`66- `skill-supabase-rls`67- `skill-security-hooks`