Looking to hire Laravel developers? Try LaraJobs

laravel-abacatepay maintained by cavalheri

Description
Laravel-native SDK for the AbacatePay API v2.
Last update
2026/05/23 04:04 (dev-master)
License
Links
Downloads
15

Comments
comments powered by Disqus

Laravel AbacatePay

Laravel-native wrapper for the official AbacatePay PHP SDK.

Requirements

  • PHP 8.3 or higher
  • Laravel 13.x
  • Composer

Installation

composer require cavalheri/laravel-abacatepay

This package requires the official SDK:

composer require abacatepay/php-sdk

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

Usage With The Facade

use Cavalheri\LaravelAbacatePay\Facades\AbacatePay;

$billing = AbacatePay::billing()->create([
    'frequency' => 'ONE_TIME',
    'methods' => ['PIX'],
    'products' => [
        [
            'external_id' => 'PRO-PLAN',
            'name' => 'Pro plan',
            'quantity' => 1,
            'price' => 1000,
        ],
    ],
    'metadata' => [
        'return_url' => route('dashboard'),
        'completion_url' => route('billing.success'),
    ],
]);

Usage With Dependency Injection

use Cavalheri\LaravelAbacatePay\AbacatePayManager;

public function __invoke(AbacatePayManager $abacatePay)
{
    return $abacatePay->billing()->create([
        'frequency' => 'ONE_TIME',
        'methods' => ['PIX'],
        'products' => [
            [
                'external_id' => 'PRO-PLAN',
                'name' => 'Pro plan',
                'quantity' => 1,
                'price' => 1000,
            ],
        ],
        'metadata' => [
            'return_url' => route('dashboard'),
            'completion_url' => route('billing.success'),
        ],
    ]);
}

Creating A PIX Billing

$billing = AbacatePay::billing()->create([
    'frequency' => 'ONE_TIME',
    'methods' => ['PIX'],
    'products' => [
        [
            'external_id' => 'ORDER-123',
            'name' => 'Order #123',
            'description' => 'Example order',
            'quantity' => 1,
            'price' => 4990,
        ],
    ],
    'metadata' => [
        'return_url' => route('checkout.index'),
        'completion_url' => route('checkout.success'),
    ],
    'customer_id' => 'cust_abcdefghij',
]);

return redirect()->away($billing->url);

You may also send customer data directly:

$billing = AbacatePay::billing()->create([
    'frequency' => 'ONE_TIME',
    'methods' => ['PIX'],
    'products' => [
        [
            'external_id' => 'ORDER-123',
            'name' => 'Order #123',
            'quantity' => 1,
            'price' => 4990,
        ],
    ],
    'metadata' => [
        'return_url' => route('checkout.index'),
        'completion_url' => route('checkout.success'),
    ],
    'customer' => [
        'name' => 'Abacate Lover',
        'email' => 'lover@example.com',
        'cellphone' => '11999999999',
        'tax_id' => '12345678901',
    ],
]);

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 abacatepay/php-sdk
composer require --dev orchestra/testbench:^11.0 pestphp/pest:^4.0 pestphp/pest-plugin-laravel:^4.0
mkdir -p config src/Clients src/Exceptions src/Facades 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.

License

The MIT License (MIT). Please see LICENSE for more information.