PHPackages                             subtain/laravel-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. subtain/laravel-payments

ActiveLibrary[Payment Processing](/categories/payments)

subtain/laravel-payments
========================

A clean, extensible multi-gateway payment package for Laravel. Supports Fanbasis, PremiumPay, Match2Pay out of the box — and any custom gateway you build.

v5.2.14(2w ago)1252↓100%MITPHPPHP ^8.1

Since Apr 12Pushed 2w agoCompare

[ Source](https://github.com/subtain-haider/laravel-payments)[ Packagist](https://packagist.org/packages/subtain/laravel-payments)[ Docs](https://github.com/subtain-haider/laravel-payments)[ RSS](/packages/subtain-laravel-payments/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (8)Versions (33)Used By (0)

Laravel Payments
================

[](#laravel-payments)

A unified, production-ready payment SDK for Laravel. Write your checkout and webhook logic once — switch gateways, add new ones, and scale without changing a line of application code.

[![License: MIT](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667)](LICENSE)[![Latest Version](https://camo.githubusercontent.com/75cd2cacde716c9d8f1049398a348c20c65d6dcfdebd41efb19af3da5a6594c7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7375627461696e2f6c61726176656c2d7061796d656e74732e737667)](https://packagist.org/packages/subtain/laravel-payments)

---

Features
--------

[](#features)

- **6 production-ready gateways** — Fanbasis, Match2Pay (crypto), Rebornpay (UPI/India), FxPay (UPI/India), PremiumPay, Whop (one-time + subscriptions)
- **Payment records** — full DB tracking with polymorphic ownership, status machine, and audit trail
- **Automatic webhook handling** — signature verification, status transitions, event dispatch for every gateway
- **Discount codes** — gateway-agnostic, auto-applied and auto-recorded on webhook confirmation
- **Sandbox mode** — simulate full payment flows without real charges, on any environment
- **Centralized logging** — per-gateway channel routing, level control, sensitive field redaction
- **API key fingerprinting** — post-rotation audit trail on every payment record and log entry
- **Extensible** — add any PSP in 3 steps, gets all features for free

---

Supported Gateways
------------------

[](#supported-gateways)

GatewayTypeCheckoutWebhooksFull APIDocs**Fanbasis**Cards, MoROne-time, Subscriptions, Embedded, Static12 event types, HMAC-SHA256Customers, Subscribers, Discount Codes, Products, Transactions, Refunds, Webhooks[→](docs/gateways/fanbasis.md)**Match2Pay**Crypto (USDT, BTC, ETH, BNB, 40+)API checkout, 2-step selectionSHA-384 (DONE only)Deposits, Withdrawals[→](docs/gateways/match2pay.md)**Rebornpay**UPI / IMPS (India)API checkoutMD5 + Python-reprPay-in, Status checks, UTR storage[→](docs/gateways/rebornpay.md)**FxPay**UPI (India)API checkoutHMAC-SHA256 raw bodyOrders[→](docs/gateways/fxpay.md)**Whop**Cards, PayPal, 100+ methodsOne-time, Subscriptions, Trial periodsStandard Webhooks (HMAC-SHA256), full lifecycleCheckout configurations, Memberships[→](docs/gateways/whop.md)**PremiumPay**CardsAPI checkoutCallback-basedCheckout onlySee below**Your gateway**AnyImplement interfaceYour logicYour logic[→ Custom gateways](docs/custom-gateways.md)---

Documentation
-------------

[](#documentation)

TopicDescription**[Payments](docs/payments.md)**PaymentService, CheckoutRequest, Payment model, status machine, HasPayments trait, webhooks, events**[Discount Codes](docs/discounts.md)**Creating codes, auto-apply, validate, audit trail, model API, idempotency**[Sandbox Mode](docs/sandbox.md)**Environment sandbox, per-user bypass, confirm endpoint, QA flows**[Logging](docs/logging.md)**Channel routing, log levels, redaction, recipes for Slack/Telegram/DB/ClickHouse**[Key Fingerprinting](docs/key-fingerprinting.md)**Post-rotation auditing, database column, log context, custom gateways**[Custom Gateways](docs/custom-gateways.md)**Interface, registration, PaymentLogger usage, what you get for free**[Fanbasis](docs/gateways/fanbasis.md)**All checkout modes, full API suite, webhook event reference**[Match2Pay](docs/gateways/match2pay.md)**Crypto checkout, cryptocurrency reference, withdrawal API, wallet expiry**[Rebornpay](docs/gateways/rebornpay.md)**UPI/IMPS, INR conversion, status checks, UTR storage, signature verification**[FxPay](docs/gateways/fxpay.md)**UPI checkout, HMAC-SHA256 webhook signature, discount &amp; sandbox support**[Whop](docs/gateways/whop.md)**One-time + subscription checkout, Standard Webhooks signature, full lifecycle event mapping, direct client access---

Install
-------

[](#install)

```
composer require subtain/laravel-payments
php artisan vendor:publish --tag=payments-config
php artisan vendor:publish --tag=payments-migrations
php artisan migrate
```

---

Quick Start
-----------

[](#quick-start)

### 1. Set gateway credentials

[](#1-set-gateway-credentials)

```
FANBASIS_API_KEY=your-key
FANBASIS_WEBHOOK_SECRET=your-secret
```

Each gateway has its own env vars. See the gateway docs linked above.

### 2. Initiate a payment

[](#2-initiate-a-payment)

```
use Subtain\LaravelPayments\PaymentService;
use Subtain\LaravelPayments\DTOs\CheckoutRequest;

$result = app(PaymentService::class)->initiate(
    gateway: 'fanbasis',
    request: new CheckoutRequest(
        amount:      299.00,
        productName: 'Pro Plan',
        webhookUrl:  route('payments.webhook', 'fanbasis'),
        successUrl:  'https://app.com/success',
        invoiceId:   (string) $order->id,
    ),
    payable: $order,
);

return redirect($result->redirectUrl);
```

The package creates an `lp_payments` record, calls the gateway, and returns the checkout URL. When the webhook arrives, it verifies the signature, updates the payment status, and dispatches events — all automatically.

### 3. Handle the result

[](#3-handle-the-result)

```
// In your EventServiceProvider
protected $listen = [
    \Subtain\LaravelPayments\Events\PaymentSucceeded::class => [
        \App\Listeners\FulfillOrder::class,
    ],
    \Subtain\LaravelPayments\Events\PaymentFailed::class => [
        \App\Listeners\NotifyCustomer::class,
    ],
];
```

```
class FulfillOrder
{
    public function handle(PaymentSucceeded $event): void
    {
        $payment = $event->payment;   // Payment model
        $order   = $payment->payable; // your Order model

        // Provision accounts, send emails, etc.
    }
}
```

**[→ Full payment documentation](docs/payments.md)**

---

Gateways
--------

[](#gateways)

### Fanbasis

[](#fanbasis)

```
use Subtain\LaravelPayments\Facades\Payment;

// One-time
Payment::gateway('fanbasis')->checkout(new CheckoutRequest(
    amount: 299.00, productName: 'Pro Plan',
    webhookUrl: route('payments.webhook', 'fanbasis'),
    successUrl: 'https://app.com/success',
));

// Subscription
Payment::gateway('fanbasis')->checkout(new CheckoutRequest(
    amount: 29.99, productName: 'Monthly',
    webhookUrl: route('payments.webhook', 'fanbasis'),
    extra: ['subscription' => ['frequency_days' => 30]],
));

// Full API access
$fb = Payment::gateway('fanbasis');
$fb->customers()->list(['search' => 'jane@example.com']);
$fb->refunds()->create('txn_abc');
$fb->webhooks()->create([...]);
```

**[→ Full Fanbasis documentation](docs/gateways/fanbasis.md)**

### Match2Pay (Crypto)

[](#match2pay-crypto)

```
Payment::gateway('match2pay')->checkout(new CheckoutRequest(
    amount: 299.00, currency: 'USD',
    webhookUrl: route('payments.webhook', 'match2pay'),
    successUrl: 'https://app.com/success',
    extra: [
        'payment_currency'     => 'USX',        // USDT TRC20
        'payment_gateway_name' => 'USDT TRC20', // omit for 2-step selection
    ],
));
```

**[→ Full Match2Pay documentation](docs/gateways/match2pay.md)**

### Rebornpay (UPI / IMPS — India)

[](#rebornpay-upi--imps--india)

```
Payment::gateway('rebornpay')->checkout(new CheckoutRequest(
    amount: 92000.00, currency: 'INR',
    invoiceId: 'order_123', customerName: 'Raj Kumar',
    successUrl: 'https://app.com/success',
));
```

**[→ Full Rebornpay documentation](docs/gateways/rebornpay.md)**

### FxPay (UPI — India)

[](#fxpay-upi--india)

```
Payment::gateway('fxpay')->checkout(new CheckoutRequest(
    amount:        1500.50,
    invoiceId:     'order_123',
    customerName:  'Rahul Sharma',
    customerEmail: 'rahul@example.com',
    webhookUrl:    route('payments.webhook', 'fxpay'),
    productName:   'Challenge Purchase',
));
```

**[→ Full FxPay documentation](docs/gateways/fxpay.md)**

### Whop

[](#whop)

```
// One-time
Payment::gateway('whop')->checkout(new CheckoutRequest(
    amount:    299.00,
    currency:  'USD',
    invoiceId: 'order_123',
    successUrl: 'https://app.com/success',
));

// Subscription
Payment::gateway('whop')->checkout(new CheckoutRequest(
    amount:     29.99,
    currency:   'USD',
    invoiceId:  'sub_order_456',
    successUrl: 'https://app.com/subscription/activated',
    extra: [
        'plan_type'      => 'renewal',
        'billing_period' => 30,   // every 30 days
    ],
));
```

**[→ Full Whop documentation](docs/gateways/whop.md)**

### PremiumPay

[](#premiumpay)

```
Payment::gateway('premiumpay')->checkout(new CheckoutRequest(
    amount: 99.00, invoiceId: 'inv_456',
    customerEmail: 'user@example.com',
    customerIp: request()->ip(),
    productName: 'Starter Package',
    successUrl: 'https://app.com/success',
    webhookUrl: route('payments.webhook', 'premiumpay'),
));
```

---

Discount Codes
--------------

[](#discount-codes)

Gateway-agnostic. The package validates, calculates the discount, and records usage after webhook confirmation — automatically.

```
// Pass discountCode on the CheckoutRequest — that's all
$result = app(PaymentService::class)->initiate(
    gateway: 'fanbasis',
    request: new CheckoutRequest(
        amount:       299.00,
        webhookUrl:   route('payments.webhook', 'fanbasis'),
        discountCode: $request->input('discount_code'), // 'LAUNCH50'
        userId:       auth()->id(),
    ),
    payable: $order,
);
// Gateway receives 249.00. usage is auto-recorded on successful webhook.
```

```
use Subtain\LaravelPayments\Models\DiscountCode;

DiscountCode::create([
    'code' => 'LAUNCH50', 'type' => 'fixed', 'value' => 50,
    'max_total_uses' => 100, 'max_uses_per_user' => 1,
]);
```

**[→ Full discount documentation](docs/discounts.md)**

---

Sandbox Mode
------------

[](#sandbox-mode)

Simulate the full payment flow without real charges. Every DB record, log, and event fires identically.

```
# .env.local or .env.staging
PAYMENTS_SANDBOX=true
```

QA trigger endpoint (simulates a successful webhook):

```
GET /payments/webhook/sandbox/confirm/{invoice_id}

```

Per-user bypass on production (internal QA accounts):

```
'sandbox' => [
    'bypass_user_ids' => [1, 42],
    'bypass_roles'    => ['qa_tester'],
],
```

**[→ Full sandbox documentation](docs/sandbox.md)**

---

Logging
-------

[](#logging)

Zero config required. Logs to your app's default channel out of the box.

```
// config/lp_payments.php
'logging' => [
    'level'    => env('PAYMENTS_LOG_LEVEL', 'info'),
    'channels' => [
        'default'   => env('PAYMENTS_LOG_CHANNEL', null),
        'match2pay' => 'slack',     // route a gateway to Slack
        'rebornpay' => 'telegram',  // or Telegram
    ],
    'redact' => ['api_key', 'secret', 'token', 'password'],
],
```

Log format:

```
[payments:fanbasis:checkout] checkout.initiated
[payments:match2pay:webhook] webhook.signature_failed

```

**[→ Full logging documentation](docs/logging.md)**

---

API Key Fingerprinting
----------------------

[](#api-key-fingerprinting)

Every `lp_payments` row stores a `first4****last4` fingerprint of the API key active at initiation time. Solve post-rotation audit questions instantly.

```
$payment->key_fingerprint;  // "sk_l****z789"
Payment::where('key_fingerprint', 'sk_l****z789')->get();
```

**[→ Full key fingerprinting documentation](docs/key-fingerprinting.md)**

---

Add a Custom Gateway
--------------------

[](#add-a-custom-gateway)

```
// 1. Implement the interface (3 methods)
class StripeGateway implements PaymentGateway
{
    public function name(): string { return 'stripe'; }
    public function checkout(CheckoutRequest $request): CheckoutResult { /* ... */ }
    public function parseWebhook(array $payload): WebhookResult { /* ... */ }
    public function verifyWebhook(array $payload, array $headers = []): bool { /* ... */ }
}

// 2. Register in config/lp_payments.php
'stripe' => [
    'driver'     => \App\Gateways\StripeGateway::class,
    'api_key'    => env('STRIPE_API_KEY'),
    'key_fields' => ['api_key'],
],

// 3. Use it — identical to built-in gateways
Payment::gateway('stripe')->checkout($checkoutRequest);
app(PaymentService::class)->initiate('stripe', $checkoutRequest, $order);
```

Your gateway automatically gets DB tracking, webhook handling, sandbox support, logging, key fingerprinting, and discounts.

**[→ Full custom gateway documentation](docs/custom-gateways.md)**

---

Testing
-------

[](#testing)

```
Payment::shouldReceive('gateway->checkout')
    ->andReturn(new CheckoutResult(redirectUrl: 'https://test.com', gateway: 'fanbasis'));
```

For full integration tests, use `PAYMENTS_SANDBOX=true` in `phpunit.xml` and hit the sandbox confirm endpoint to simulate successful payments.

---

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

[](#requirements)

- PHP 8.1+
- Laravel 10 / 11 / 12

---

License
-------

[](#license)

MIT — [LICENSE](LICENSE)

Author
------

[](#author)

**Syed Subtain Haider** — [GitHub](https://github.com/subtain-haider)

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance96

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

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.

###  Release Activity

Cadence

Every ~1 days

Total

32

Last Release

20d ago

Major Versions

v1.0.0 → v2.0.02026-04-12

v2.0.0 → v3.0.02026-04-12

v3.4.0 → v4.0.02026-04-16

v4.3.0 → v5.0.02026-04-17

### Community

Maintainers

![](https://www.gravatar.com/avatar/e8a9416371a3e2ddbfd493f7e4b15ef6b1db6ec78e2685cd4cb51cf42bf7434a?d=identicon)[subtain-haider](/maintainers/subtain-haider)

---

Tags

laravelwebhookspaymentscheckoutpayment gatewayupifanbasispremiumpaymatch2payrebornpayfxpay

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/subtain-laravel-payments/health.svg)

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

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76318.2M110](/packages/laravel-mcp)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9732.3M121](/packages/roots-acorn)[api-platform/laravel

API Platform support for Laravel

59156.3k10](/packages/api-platform-laravel)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1232.2k16](/packages/fleetbase-core-api)

PHPackages © 2026

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