PHPackages                             whilesmart/eloquent-payments - 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. whilesmart/eloquent-payments

ActiveLibrary[Payment Processing](/categories/payments)

whilesmart/eloquent-payments
============================

Polymorphic payment records for Laravel: gateway-agnostic audit trail attachable to invoices, expenses, subscriptions, or any payable.

05PHP

Since Apr 24Pushed 1mo agoCompare

[ Source](https://github.com/whilesmartphp/eloquent-payments)[ Packagist](https://packagist.org/packages/whilesmart/eloquent-payments)[ RSS](/packages/whilesmart-eloquent-payments/feed)WikiDiscussions dev Synced 1w ago

READMEChangelogDependenciesVersions (3)Used By (0)

Eloquent Payments
=================

[](#eloquent-payments)

Polymorphic, gateway-agnostic payment records for Laravel. Attaches to invoices, expenses, subscriptions, orders, or any payable model.

Why
---

[](#why)

`whilesmart/eloquent-invoices` tracks payment state as scalars on the invoice row (`amount_paid_cents`, `paid_at`). That is a good summary view but there is no audit trail: no per-event log, no gateway reference, no multi-installment history, no refund chain, no failed-attempt record.

This package is that audit trail. Invoices, expenses, or anything else payable gets a `payments()` relationship; each `Payment` row is a single event.

Install
-------

[](#install)

```
composer require whilesmart/eloquent-payments
php artisan migrate

```

Attach the `HasPayments` trait to any payable:

```
use Whilesmart\Payments\Contracts\Payable;
use Whilesmart\Payments\Traits\HasPayments;

class Invoice extends Model implements Payable
{
    use HasPayments;
}
```

Data model
----------

[](#data-model)

Every `Payment` row captures:

- **`payable`** (morph) -- what's being paid for.
- **`owner`** (nullable morph) -- who initiated / owns the payment, typically the workspace.
- **`amount_cents`**, **`currency`**.
- **`status`** -- `pending | authorized | succeeded | failed | refunded | partially_refunded | cancelled`.
- **`direction`** -- `inbound` (collection) / `outbound` (payout, refund).
- **`gateway`**, **`gateway_reference`** -- provider + its ID. Unique pair.
- **`method`** -- free-form string (`card`, `mobile_money`, `bank_transfer`, ...). See `PaymentMethod` enum for canonical values.
- **Audit timestamps** -- `authorized_at`, `succeeded_at`, `failed_at`, `refunded_at`.
- **`failure_reason`** -- text.
- **`parent_payment_id`** -- for refunds, points to the original payment.
- **`metadata`** -- JSON.

Reflecting onto the payable
---------------------------

[](#reflecting-onto-the-payable)

The `HasPayments` trait includes `recordPayment()` which creates a Payment AND, when `payments.auto_reflect_on_payable` is on (default), syncs the payable's own summary fields:

```
$invoice->recordPayment([
    'amount_cents'      => 50000,
    'currency'          => 'USD',
    'status'            => 'succeeded',
    'method'            => 'card',
    'gateway'           => 'stripe',
    'gateway_reference' => 'ch_123...',
    'succeeded_at'      => now(),
]);

// Effect:
//   invoice.amount_paid_cents  += 50000 (or rather, set to sum of succeeded payments)
//   invoice.paid_at             = now() if cumulative >= total_cents
```

If the payable has no `amount_paid_cents` column, reflection is silently skipped -- the package never errors out of ignorance of your schema.

Routes
------

[](#routes)

Registers an `apiResource` at the configured prefix:

```
GET    /api/payments
POST   /api/payments
GET    /api/payments/{payment}
PUT    /api/payments/{payment}
DELETE /api/payments/{payment}

```

Index filters: `payable_type`, `payable_id`, `owner_type`, `owner_id`, `status`, `direction`, `gateway`, `per_page`.

Config
------

[](#config)

`php artisan vendor:publish --tag=payments-config`:

```
return [
    'register_routes' => env('PAYMENTS_REGISTER_ROUTES', true),
    'route_prefix' => env('PAYMENTS_ROUTE_PREFIX', 'api'),
    'route_middleware' => ['api', 'auth:sanctum'],
    'table' => env('PAYMENTS_TABLE', 'payments'),
    'auto_reflect_on_payable' => env('PAYMENTS_AUTO_REFLECT', true),
];
```

Siblings
--------

[](#siblings)

- `whilesmart/eloquent-invoices` -- invoices (money in). Implement `Payable`, attach `HasPayments`.
- `whilesmart/eloquent-expenses` -- expenses (money out). Same pattern; the `Payment` direction flips to `outbound`.
- `whilesmart/eloquent-subscriptions` (future) -- recurring billing.

###  Health Score

22

—

LowBetter than 22% of packages

Maintenance60

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity15

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/a1ca6f6e01ecbfe6640ff410c4f0321054fb48d05a5f843c2b89887b90369bcd?d=identicon)[whilesmart](/maintainers/whilesmart)

---

Top Contributors

[![nfebe](https://avatars.githubusercontent.com/u/14317775?v=4)](https://github.com/nfebe "nfebe (3 commits)")

### Embed Badge

![Health badge](/badges/whilesmart-eloquent-payments/health.svg)

```
[![Health](https://phpackages.com/badges/whilesmart-eloquent-payments/health.svg)](https://phpackages.com/packages/whilesmart-eloquent-payments)
```

###  Alternatives

[omnipay/coinbase

Coinbase driver for the Omnipay payment processing library

18570.2k1](/packages/omnipay-coinbase)[yenepay/php-sdk

YenePay SDK for PHP

112.7k](/packages/yenepay-php-sdk)

PHPackages © 2026

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