PHPackages                             puntodev/payables - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. puntodev/payables

ActiveLibrary[Payment Processing](/categories/payments)

puntodev/payables
=================

015[1 PRs](https://github.com/puntodev/payables/pulls)PHP

Since May 24Pushed 2w ago1 watchersCompare

[ Source](https://github.com/puntodev/payables)[ Packagist](https://packagist.org/packages/puntodev/payables)[ RSS](/packages/puntodev-payables/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependenciesVersions (1)Used By (0)

Payables
========

[](#payables)

[![Latest Version on Packagist](https://camo.githubusercontent.com/ac52e8e9c6ac88aa199feae63efbda949078e4392a63478e35ae01e45c66416a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f70756e746f6465762f70617961626c65732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/puntodev/payables)[![Total Downloads](https://camo.githubusercontent.com/41a3c472bebb8c3f7f831ea700982c0c47d6e5cdb5b4765cb2f9c9a35c18813c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f70756e746f6465762f70617961626c65732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/puntodev/payables)

A gateway-agnostic payments abstraction for Laravel. Charge any of your Eloquent models, collect payments through a payment gateway, and reconcile them automatically from incoming webhooks.

The package ships its own `Order`/`Payment` models, migrations, webhook routes and a `Payments` facade. It is built around small contracts that your application implements, so the rest of your code never talks to a specific provider directly.

Currently bundled gateway: **MercadoPago** (via [`puntodev/mercadopago`](https://github.com/puntodev/mercadopago)).

Requirements
------------

[](#requirements)

- PHP `>=8.4`
- Laravel `^12.0`

Installation
------------

[](#installation)

Install via composer:

```
composer require puntodev/payables
```

Publish and run the migrations:

```
php artisan vendor:publish --tag=migrations
php artisan migrate
```

This creates the `orders` and `payments` tables.

How it works
------------

[](#how-it-works)

The library models payments around a few small interfaces (`Puntodev\Payables\Contracts`):

ContractImplemented byPurpose`Payable`your "thing to charge" modelConverts itself into a `PaymentOrder``PaymentOrder`a value object you buildCheckout details: items, payer, back URLs`PaymentOrderItem`a value object you buildA single line item`Merchant`your account model (or the default)Holds gateway credentials`Gateway`the package (e.g. MercadoPago)Creates orders and processes webhooks`GatewayPaymentOrder`the packageResult of a checkout (redirect link, ids)There are also two traits to drop on your models:

- `HasOrders` — for your **payable** model. Adds `orders()`, `isPaid()`, `isRefunded()`, `paidOn()`.
- `OwnsPayments` — for your **merchant** model. Adds `orders()`.

> **Note:** amounts are stored in cents in the database, but the `Order`/`Payment`models expose them as decimals through accessors. Always read/write `amount` through the models.

Usage
-----

[](#usage)

### 1. Make a model payable

[](#1-make-a-model-payable)

```
use Illuminate\Database\Eloquent\Model;
use Puntodev\Payables\Concerns\HasOrders;
use Puntodev\Payables\Contracts\Payable;
use Puntodev\Payables\Contracts\PaymentOrder;

class Product extends Model implements Payable
{
    use HasOrders;

    public function toPaymentOrder(): PaymentOrder
    {
        return new ProductPaymentOrder($this);
    }
}
```

Your `PaymentOrder` implementation describes the checkout — its items, the payer's details, the URLs MercadoPago should redirect to, excluded payment methods and an optional expiration. Each item implements `PaymentOrderItem` (`amount`, `quantity`, `currency`, `description`).

### 2. Create a checkout

[](#2-create-a-checkout)

Using a specific merchant (a model that implements `Merchant` and uses `OwnsPayments`):

```
use Puntodev\Payables\Facades\Payments;

$order = Payments::checkout('mercado_pago', $product, $merchant);

return redirect($order->redirectLink());
```

Or, if you operate a single MercadoPago account, use the default merchant (credentials read from `config('mercadopago.*')`):

```
$order = Payments::checkoutForDefaultMerchant('mercado_pago', $product);

return redirect($order->redirectLink());
```

This persists a local `Order`, creates the payment preference on the gateway, and returns a `GatewayPaymentOrder` exposing `gateway()`, `id()`, `redirectLink()` and `externalId()`.

### 3. Receive webhooks

[](#3-receive-webhooks)

The package registers webhook routes automatically (prefixed with `payments` by default):

- `POST /payments/{gateway}/{merchantType}/{merchantId}` — per-merchant
- `POST /payments/{gateway}` — default merchant

Point your gateway's notification URL there (it is set automatically when the order is created). Incoming notifications are handled by a queued `StorePayment` job that fetches the order from the gateway and upserts the corresponding `Payment`, mapping it to `paid` / `refunded` / `created`.

### 4. Query payment status

[](#4-query-payment-status)

```
$product->isPaid();     // bool
$product->isRefunded(); // bool
$product->paidOn();     // ?Carbon
```

Configuration
-------------

[](#configuration)

Publish the config if you need to customize gateways, the route prefix or middleware:

```
php artisan vendor:publish --provider="Puntodev\Payables\PaymentsServiceProvider"
```

```
// config/payments.php
return [
    'gateways'   => ['mercado_pago' => MercadoPagoGateway::class],
    'prefix'     => 'payments',
    'middleware' => 'web',
];
```

### Adding a new gateway

[](#adding-a-new-gateway)

Implement `Puntodev\Payables\Contracts\Gateway`, register it in the `gateways` map, and bind it in a service provider if it has constructor dependencies. The rest of your code keeps using the `Payments` facade unchanged.

Testing
-------

[](#testing)

```
composer test                 # run the test suite
composer test-f       # run a single test by name
composer test-coverage        # generate an HTML coverage report
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email instead of using the issue tracker.

Credits
-------

[](#credits)

- [Mariano Goldman](https://github.com/marianogoldman)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

28

—

LowBetter than 52% of packages

Maintenance63

Regular maintenance activity

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity30

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/7201db0e06c12ae2e12e1cf4ee5806b5b465dc538bee3cab6bfb1c0ec52e4dce?d=identicon)[Mariano Goldman](/maintainers/Mariano%20Goldman)

---

Top Contributors

[![marianogoldman](https://avatars.githubusercontent.com/u/959563?v=4)](https://github.com/marianogoldman "marianogoldman (14 commits)")

### Embed Badge

![Health badge](/badges/puntodev-payables/health.svg)

```
[![Health](https://phpackages.com/badges/puntodev-payables/health.svg)](https://phpackages.com/packages/puntodev-payables)
```

###  Alternatives

[msilabs/bkash

bKash Payment Gateway API for Laravel Framework.

181.2k](/packages/msilabs-bkash)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
