cavalheri/laravel-abacatepay

Laravel-native SDK for the AbacatePay API v2.

Maintainers

Package info

github.com/LucasCavalheri/laravel-abacatepay

pkg:composer/cavalheri/laravel-abacatepay

Statistics

Installs: 15

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v2.1.3 2026-05-23 02:04 UTC

README

Tests Latest Version on Packagist Total Downloads License

PHP Version Laravel Documentation

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

  1. Push the repository to GitHub.
  2. Create a release tag, for example v0.1.0.
  3. Sign in to Packagist.
  4. Submit the repository URL.
  5. Enable GitHub synchronization so Packagist updates on each new tag.
  6. 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.