cavalheri / laravel-abacatepay
Laravel-native SDK for the AbacatePay API v2.
Requires
- php: ^8.3
- guzzlehttp/guzzle: ^7.9
- illuminate/http: ^13.0
- illuminate/routing: ^13.0
- illuminate/support: ^13.0
- illuminate/view: ^13.0
Requires (Dev)
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
This package is auto-updated.
Last update: 2026-05-23 02:04:55 UTC
README
Laravel-native SDK for the AbacatePay API v2.
Documentação
Site de documentação com suporte a Português (padrão) e English:
cd docs
npm install
npm run dev
Build para produção:
npm run build npm run serve
Para gerar URLs canônicas e metadados Open Graph completos no build de produção, defina a URL pública do site:
DOCS_SITE_URL=https://seu-dominio.com npm run build
Na Vercel, configure o Root Directory como docs. O arquivo docs/vercel.json já aponta o output para docs/.vitepress/dist. A URL da Vercel é detectada automaticamente para SEO; use DOCS_SITE_URL se tiver domínio customizado.
A documentação abre em português. Use o seletor de idioma no topo para alternar para inglês (/en/).
Requisitos
- PHP 8.3 or higher
- Laravel 13.x
- Composer
Installation
composer require cavalheri/laravel-abacatepay
Publish The Configuration
php artisan vendor:publish --tag=abacatepay-config
The published file will be available at config/abacatepay.php.
Environment Variables
ABACATEPAY_API_KEY= ABACATEPAY_WEBHOOK_SECRET= ABACATEPAY_DEV_MODE=false ABACATEPAY_PLAYGROUND_ENABLED=true
Playground (interactive SDK explorer)
Horizon-style UI to try AbacatePay SDK calls and watch the matching Laravel code update in real time.
Enabled by default in local. Open:
http://localhost/abacatepay/playground
Configure in config/abacatepay.php:
'playground' => [ 'enabled' => env('ABACATEPAY_PLAYGROUND_ENABLED', env('APP_ENV') === 'local'), 'path' => env('ABACATEPAY_PLAYGROUND_PATH', 'abacatepay/playground'), 'middleware' => ['web'], 'authorize' => fn ($request) => app()->environment('local'), ],
The authorize callback lets you lock the playground down in shared environments.
Usage With The Facade
use Cavalheri\LaravelAbacatePay\Facades\AbacatePay; $checkout = AbacatePay::checkouts()->forProduct('prod_abc123xyz'); return redirect()->away($checkout->url);
Usage With Dependency Injection
use Cavalheri\LaravelAbacatePay\AbacatePayManager; public function __invoke(AbacatePayManager $abacatePay) { $checkout = $abacatePay->checkouts()->forProduct('prod_abc123xyz'); return redirect()->away($checkout->url); }
Customers
$customer = AbacatePay::customers()->firstOrCreate([ 'email' => 'lover@example.com', 'name' => 'Abacate Lover', 'tax_id' => '12345678901', ]);
You can also use the full v2 customer resource methods:
$customer = AbacatePay::customers()->create([...]); $customers = AbacatePay::customers()->list(['limit' => 50]); $customer = AbacatePay::customers()->get('cust_abcdefghij'); $deleted = AbacatePay::customers()->delete('cust_abcdefghij');
Coupons
$coupon = AbacatePay::coupons()->percentage('WELCOME10', 10, [ 'max_redeems' => -1, ]);
Fixed amount coupons use cents:
$coupon = AbacatePay::coupons()->fixed('PROMO20', 2000);
You can also use the full v2 coupon resource methods:
$coupon = AbacatePay::coupons()->create([...]); $coupons = AbacatePay::coupons()->list(['status' => 'ACTIVE']); $coupon = AbacatePay::coupons()->get('WELCOME10'); $coupon = AbacatePay::coupons()->toggle('WELCOME10'); $deleted = AbacatePay::coupons()->delete('WELCOME10');
Products
Create a one-time product:
$product = AbacatePay::products()->oneTime('PRO-PLAN', 'Pro plan', 10000);
Create a subscription product:
$product = AbacatePay::products()->subscription('PRO-MONTHLY', 'Pro monthly', 10000, 'MONTHLY');
You can also use the full v2 product resource methods:
$product = AbacatePay::products()->create([ 'external_id' => 'PRO-PLAN', 'name' => 'Pro plan', 'price' => 10000, 'description' => 'Professional plan', ]); $products = AbacatePay::products()->list(['status' => 'ACTIVE']); $product = AbacatePay::products()->get('prod_abc123xyz'); $product = AbacatePay::products()->get(['external_id' => 'PRO-PLAN']); $deleted = AbacatePay::products()->delete('prod_abc123xyz');
Checkouts
Create a hosted checkout for a product:
$checkout = AbacatePay::checkouts()->forProduct('prod_abc123xyz'); return redirect()->away($checkout->url);
Create a PIX-only checkout:
$checkout = AbacatePay::checkouts()->pix('prod_abc123xyz', 1, [ 'customer_id' => 'cust_abcdefghij', ]);
Create a card checkout with installments:
$checkout = AbacatePay::checkouts()->card('prod_abc123xyz', 1, [ 'max_installments' => 12, ]);
You can also use the full v2 checkout resource methods:
$checkout = AbacatePay::checkouts()->create([ 'items' => [ ['id' => 'prod_abc123xyz', 'quantity' => 1], ], 'methods' => ['PIX', 'CARD'], 'return_url' => route('checkout.index'), 'completion_url' => route('checkout.success'), ]); $checkouts = AbacatePay::checkouts()->list(['status' => 'PENDING']); $checkout = AbacatePay::checkouts()->get('bill_abc123xyz'); $refund = AbacatePay::checkouts()->refund('bill_abc123xyz', 'Customer canceled the order.');
Payment Links
Create a reusable payment link for a product:
$paymentLink = AbacatePay::paymentLinks()->forProduct('prod_abc123xyz'); return redirect()->away($paymentLink->url);
Create a PIX-only payment link:
$paymentLink = AbacatePay::paymentLinks()->pix('prod_abc123xyz');
You can also use the full v2 payment link resource methods:
$paymentLink = AbacatePay::paymentLinks()->create([ 'items' => [ ['id' => 'prod_abc123xyz', 'quantity' => 1], ], 'methods' => ['PIX', 'CARD'], 'return_url' => route('checkout.index'), 'completion_url' => route('checkout.success'), ]); $paymentLinks = AbacatePay::paymentLinks()->list(['status' => 'PENDING']); $paymentLink = AbacatePay::paymentLinks()->get('bill_link123xyz'); $refund = AbacatePay::paymentLinks()->refund('bill_link789xyz', 'Duplicated charge.');
Transparent Checkouts
Create a PIX QR Code without redirecting the customer:
$charge = AbacatePay::transparentCheckouts()->pix(10000, [ 'description' => 'Order #123', 'metadata' => ['order_id' => 'ORDER-123'], ]); echo $charge->brCode;
Create a boleto with alternative PIX:
$charge = AbacatePay::transparentCheckouts()->boleto(25000, [ 'name' => 'Abacate Lover', 'tax_id' => '12345678901', ]);
You can also use the full v2 transparent checkout methods:
$charge = AbacatePay::transparentCheckouts()->create([ 'method' => 'PIX', 'data' => [ 'amount' => 10000, 'expires_in' => 3600, ], ]); $status = AbacatePay::transparentCheckouts()->check('pix_char_abc123xyz'); $charge = AbacatePay::transparentCheckouts()->simulatePayment('pix_char_abc123xyz'); $charges = AbacatePay::transparentCheckouts()->list(['status' => 'PENDING']); $refund = AbacatePay::transparentCheckouts()->refund('pix_char_abc123xyz', 'Customer paid twice.');
Payouts
Create a payout in one line:
$payout = AbacatePay::payouts()->withdraw(10000, 'withdraw-123');
You can also use the full v2 payout resource methods:
$payout = AbacatePay::payouts()->create([ 'amount' => 10000, 'external_id' => 'withdraw-123', 'description' => 'Weekly withdrawal', ]); $payout = AbacatePay::payouts()->get('withdraw-123'); $payouts = AbacatePay::payouts()->list(['status' => 'PENDING']);
PIX Transfers
Send PIX to a key in one line:
$pix = AbacatePay::pixTransfers()->toPhone(10000, 'pix-123', '11987654321');
Use the helper that matches the key type:
AbacatePay::pixTransfers()->toEmail(10000, 'pix-124', 'supplier@example.com'); AbacatePay::pixTransfers()->toCpf(10000, 'pix-125', '12345678901'); AbacatePay::pixTransfers()->toCnpj(10000, 'pix-126', '12345678000199'); AbacatePay::pixTransfers()->toRandomKey(10000, 'pix-127', 'random-key'); AbacatePay::pixTransfers()->toBrCode(10000, 'pix-128', '000201...');
You can also use the full v2 PIX transfer methods:
$pix = AbacatePay::pixTransfers()->send([ 'amount' => 10000, 'external_id' => 'pix-123', 'description' => 'Supplier payment', 'pix' => [ 'key' => '11987654321', 'type' => 'PHONE', ], ]); $pix = AbacatePay::pixTransfers()->get('txn_pix_abc123'); $pix = AbacatePay::pixTransfers()->getByExternalId('pix-123'); $pixTransfers = AbacatePay::pixTransfers()->list(['status' => 'PENDING']);
Subscriptions
Create a subscription checkout in one line:
$checkout = AbacatePay::subscriptions()->card('prod_monthly_abc123');
You can also use the full v2 subscription checkout payload:
$checkout = AbacatePay::subscriptions()->create([ 'items' => [ ['id' => 'prod_monthly_abc123', 'quantity' => 1], ], 'methods' => ['CARD'], 'customer_id' => 'cust_abc123xyz', 'external_id' => 'sub-123', 'metadata' => ['plan' => 'monthly'], ]); $subscriptions = AbacatePay::subscriptions()->list(['status' => 'PAID']);
Manage active subscriptions:
$subscription = AbacatePay::subscriptions()->cancel('subs_abc123xyz'); $update = AbacatePay::subscriptions()->changePlan('subs_abc123xyz', 'prod_plano_pro', 1); $usage = AbacatePay::subscriptions()->addUsage('subs_abc123xyz', 'prod_api_calls', 50); $usage = AbacatePay::subscriptions()->subtractUsage('subs_abc123xyz', 'prod_api_calls', 10);
Store
Get your store details and balance in one line:
$store = AbacatePay::store()->get(); $availableBalance = $store->balance->available;
Public MRR
Get public merchant metrics in one line:
$mrr = AbacatePay::publicMrr()->mrr();
You can also use the full v2 public MRR methods:
$merchant = AbacatePay::publicMrr()->merchantInfo(); $mrr = AbacatePay::publicMrr()->mrr(); $revenue = AbacatePay::publicMrr()->revenue('2024-01-01', '2024-01-31'); $revenue = AbacatePay::publicMrr()->revenueForPeriod([ 'start_date' => '2024-01-01', 'end_date' => '2024-01-31', ]);
Webhooks
Create a webhook with a fluent, Laravel-friendly flow:
$webhook = AbacatePay::webhooks() ->checkoutEvents() ->at('https://example.com/webhooks/abacatepay') ->named('Checkout payments') ->create();
Use official event presets, or subscribe to one exact event:
use Cavalheri\LaravelAbacatePay\Webhooks\WebhookEvent; AbacatePay::webhooks()->subscriptionEvents()->at($url)->named('Subscriptions')->create(); AbacatePay::webhooks()->payoutEvents()->at($url)->named('Payouts')->create(); AbacatePay::webhooks()->listenTo(WebhookEvent::CHECKOUT_COMPLETED)->at($url)->named('Paid checkouts')->create();
You can still use the raw v2 resource methods when you need full control:
$webhook = AbacatePay::webhooks()->create([ 'name' => 'Webhook de Pagamentos', 'endpoint' => 'https://example.com/webhooks/abacatepay', 'secret' => env('ABACATEPAY_WEBHOOK_SECRET'), 'events' => [ WebhookEvent::CHECKOUT_COMPLETED, WebhookEvent::SUBSCRIPTION_RENEWED, ], ]); $webhooks = AbacatePay::webhooks()->list(['search' => 'pagamentos']); $webhook = AbacatePay::webhooks()->get('webh_abc123xyz'); $deleted = AbacatePay::webhooks()->delete('webh_abc123xyz');
Validate incoming webhook requests with the URL secret and HMAC signature:
$isValid = AbacatePay::webhooks()->verify( rawBody: $request->getContent(), signature: $request->header('X-Webhook-Signature'), secret: $request->query('webhookSecret'), );
Running Tests
composer test
Or run Pest directly:
vendor/bin/pest
Creating This Package From Scratch
mkdir laravel-abacatepay
cd laravel-abacatepay
composer init --name=cavalheri/laravel-abacatepay --type=library
composer require php:^8.3 illuminate/support:^13.0 guzzlehttp/guzzle
composer require --dev orchestra/testbench:^11.0 pestphp/pest:^4.0 pestphp/pest-plugin-laravel:^4.0
mkdir -p config src/Exceptions src/Facades src/Http tests/Feature
After creating the package files, refresh Composer autoloading:
composer dump-autoload
Publishing To Packagist
- Push the repository to GitHub.
- Create a release tag, for example
v0.1.0. - Sign in to Packagist.
- Submit the repository URL.
- Enable GitHub synchronization so Packagist updates on each new tag.
- Install the package in a Laravel 13 application and run a smoke test before announcing it.
Contributing
Pull requests are welcome. Please include tests for new behavior and keep changes focused.
Author
Created and maintained by Lucas Cavalheri.
Learn more about the creator: Portfolio · GitHub · LinkedIn
License
The MIT License (MIT). Please see LICENSE for more information.