PHPackages                             tumelo/laravel-payfast - 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. tumelo/laravel-payfast

ActiveLibrary[Payment Processing](/categories/payments)

tumelo/laravel-payfast
======================

A modern, feature-complete Laravel package for PayFast payment gateway integration. Supports redirect payments, onsite payments, ITN webhooks, subscriptions, refunds, split payments, and SPA frontends (Vue 3 + React).

10PHP

Since Feb 18Pushed 3mo agoCompare

[ Source](https://github.com/RockHardJim/laravel-payfast)[ Packagist](https://packagist.org/packages/tumelo/laravel-payfast)[ RSS](/packages/tumelo-laravel-payfast/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Laravel PayFast
===============

[](#laravel-payfast)

A modern, feature-complete Laravel package for [PayFast](https://www.payfast.co.za) payment gateway integration. Built with PHP 8.3+ and supports Laravel 11/12.

Features
--------

[](#features)

- **Redirect Payments** - Standard PayFast hosted payment page
- **Onsite Payments** - Embedded payment engine (no redirect)
- **ITN Webhooks** - Automatic signature &amp; IP validation with Laravel events
- **Subscriptions** - Standard recurring and ad hoc (tokenization) billing
- **Refunds** - Full and partial refund processing
- **Transaction History** - Date range queries with pagination
- **Split Payments** - Automatic fund splitting between accounts
- **SPA Support** - JSON API endpoints with Vue 3 and React components
- **Blade Components** - Drop-in payment form components
- **Sandbox Support** - Toggle between test and production environments

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

[](#requirements)

- PHP 8.3+
- Laravel 11 or 12

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

[](#installation)

```
composer require tumelo/laravel-payfast
```

Publish the configuration file:

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

Add your PayFast credentials to `.env`:

```
PAYFAST_MERCHANT_ID=your_merchant_id
PAYFAST_MERCHANT_KEY=your_merchant_key
PAYFAST_PASSPHRASE=your_passphrase
PAYFAST_TESTING=true

PAYFAST_RETURN_URL=https://yourapp.com/payment/success
PAYFAST_CANCEL_URL=https://yourapp.com/payment/cancel
PAYFAST_NOTIFY_URL=https://yourapp.com/payfast/webhook
```

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

[](#quick-start)

### Simple Payment (Redirect)

[](#simple-payment-redirect)

```
use Tumelo\PayFast\Facades\PayFast;
use Tumelo\PayFast\Data\PaymentData;
use Tumelo\PayFast\Data\CustomerData;

// In your controller
public function checkout()
{
    $formData = PayFast::buildFormData(new PaymentData(
        merchantPaymentId: 'ORDER-001',
        amount: 199.99,
        itemName: 'Premium Widget',
        customer: new CustomerData(
            firstName: 'John',
            lastName: 'Doe',
            email: 'john@example.com',
        ),
    ));

    return view('payment.redirect', [
        'formData' => $formData,
        'processUrl' => PayFast::getProcessUrl(),
    ]);
}
```

### Onsite Payment (Embedded)

[](#onsite-payment-embedded)

```
$result = PayFast::onsite(new PaymentData(
    merchantPaymentId: 'ORDER-002',
    amount: 99.99,
    itemName: 'Basic Widget',
));

// Returns: ['uuid' => '...', 'form_data' => [...], 'process_url' => '...']
```

### Blade Component

[](#blade-component)

```
{{-- Redirect payment form --}}

{{-- With auto-submit (redirect immediately) --}}

{{-- Custom submit button text --}}

{{-- Onsite (embedded) payment --}}

```

Subscriptions
-------------

[](#subscriptions)

### Create a Subscription

[](#create-a-subscription)

```
use Tumelo\PayFast\Data\SubscriptionData;
use Tumelo\PayFast\Enums\SubscriptionType;
use Tumelo\PayFast\Enums\BillingFrequency;

$formData = PayFast::buildSubscriptionFormData(new SubscriptionData(
    merchantPaymentId: 'SUB-001',
    amount: 49.99,
    itemName: 'Monthly Plan',
    subscriptionType: SubscriptionType::STANDARD,
    frequency: BillingFrequency::MONTHLY,
    cycles: 0, // indefinite
    customer: new CustomerData(
        firstName: 'Jane',
        lastName: 'Smith',
        email: 'jane@example.com',
    ),
));
```

### Manage Subscriptions

[](#manage-subscriptions)

```
// Fetch subscription details
$details = PayFast::subscriptions()->fetch('subscription-token');

// Pause for 2 cycles
PayFast::subscriptions()->pause('subscription-token', 2);

// Resume
PayFast::subscriptions()->unpause('subscription-token');

// Cancel
PayFast::subscriptions()->cancel('subscription-token');

// Update
PayFast::subscriptions()->update('subscription-token', [
    'cycles' => 6,
    'amount' => 5999,
]);

// Ad hoc charge (tokenized billing)
PayFast::subscriptions()->adhocCharge(
    token: 'subscription-token',
    amount: 149.99,
    itemName: 'One-time upgrade',
);
```

Refunds
-------

[](#refunds)

```
use Tumelo\PayFast\Data\RefundData;

$result = PayFast::refund(new RefundData(
    paymentId: 'pf_123456',
    amount: 50.00,
    reason: 'Customer request',
));

if ($result->isSuccessful()) {
    // Refund processed
}
```

Transaction History
-------------------

[](#transaction-history)

```
// Fetch by date range
$transactions = PayFast::transactionHistory(
    from: now()->subMonth(),
    to: now(),
);

// Convenience methods
$today = PayFast::transactions()->daily(now());
$thisWeek = PayFast::transactions()->weekly(now());
$thisMonth = PayFast::transactions()->monthly(now());

// Fetch single transaction
$transaction = PayFast::fetchTransaction('pf_payment_id');
```

Webhook Events
--------------

[](#webhook-events)

The package automatically handles ITN (Instant Transaction Notification) callbacks and dispatches Laravel events. Register listeners in your app:

```
// In EventServiceProvider or using Event::listen
use Tumelo\PayFast\Events\PaymentCompleted;
use Tumelo\PayFast\Events\PaymentFailed;
use Tumelo\PayFast\Events\PaymentPending;
use Tumelo\PayFast\Events\SubscriptionCreated;
use Tumelo\PayFast\Events\SubscriptionCancelled;
use Tumelo\PayFast\Events\RefundProcessed;

Event::listen(PaymentCompleted::class, function (PaymentCompleted $event) {
    $event->merchantPaymentId;       // Your order ID
    $event->payFastPaymentId;        // PayFast's payment ID
    $event->transaction->amountGross; // Total amount
    $event->transaction->amountNet;   // After fees
    $event->transaction->customer;    // CustomerData object
    $event->raw;                      // Raw ITN array
});

Event::listen(SubscriptionCreated::class, function (SubscriptionCreated $event) {
    $event->token;      // Subscription token for future API calls
    $event->transaction; // TransactionResult
});
```

### Webhook Route

[](#webhook-route)

The ITN webhook endpoint is automatically registered at `/payfast/webhook` (configurable in `config/payfast.php`). It includes:

- **IP validation** - Ensures requests come from PayFast servers
- **Signature validation** - Verifies request integrity
- **Merchant ID validation** - Confirms the request is for your account

SPA Integration (Vue 3 / React)
-------------------------------

[](#spa-integration-vue-3--react)

### Enable API Endpoints

[](#enable-api-endpoints)

In your `.env`:

```
PAYFAST_SPA_ENABLED=true
```

### Publish Frontend Components

[](#publish-frontend-components)

```
# Vue 3
php artisan vendor:publish --tag=payfast-vue

# React
php artisan vendor:publish --tag=payfast-react
```

### Vue 3 Usage

[](#vue-3-usage)

```

import { PayFastPayment } from './components/payfast/PayFastPayment.vue'

function handleSuccess(data) { /* ... */ }
function handleCancelled() { /* ... */ }
function handleError(error) { /* ... */ }

```

**Using the composable directly:**

```
import { usePayFast } from './components/payfast/usePayFast'

const { initiatePayment, loading, error, result, submitRedirectForm } = usePayFast()

async function pay() {
    const response = await initiatePayment({
        merchant_payment_id: 'ORDER-001',
        amount: 99.99,
        item_name: 'Widget',
    })

    if (response?.type === 'redirect') {
        submitRedirectForm(response.process_url, response.form_data)
    }
}
```

### React Usage

[](#react-usage)

```
import { PayFastPayment } from './components/payfast/PayFastPayment'

function CheckoutPage() {
    return (
         console.log('Success:', data)}
            onCancelled={() => console.log('Cancelled')}
            onError={(error) => console.error(error)}
        />
    )
}
```

**Using the hook directly:**

```
import { usePayFast } from './components/payfast/usePayFast'

function CheckoutPage() {
    const { initiatePayment, loading, error, submitRedirectForm } = usePayFast()

    async function handleCheckout() {
        const response = await initiatePayment({
            merchant_payment_id: 'ORDER-001',
            amount: 99.99,
            item_name: 'Widget',
        })

        if (response?.type === 'redirect') {
            submitRedirectForm(response.process_url!, response.form_data!)
        }
    }

    return Pay Now
}
```

### API Endpoints

[](#api-endpoints)

When SPA mode is enabled, these JSON endpoints are available:

MethodEndpointDescriptionPOST`/api/payfast/initiate`Create payment (redirect or onsite)POST`/api/payfast/subscription`Create subscriptionGET`/api/payfast/transaction/{id}`Fetch transaction statusPOST`/api/payfast/refund`Process refundGET`/api/payfast/history`Fetch transaction historyCustom Fields
-------------

[](#custom-fields)

Pass custom data through PayFast for retrieval in ITN callbacks:

```
$payment = new PaymentData(
    merchantPaymentId: 'ORDER-001',
    amount: 100.00,
    itemName: 'Widget',
    customStrings: [
        'custom_str1' => 'order-reference',
        'custom_str2' => 'user-metadata',
    ],
    customIntegers: [
        'custom_int1' => 42,
    ],
);
```

Access them in your event listener:

```
Event::listen(PaymentCompleted::class, function ($event) {
    $ref = $event->transaction->customStrings['custom_str1']; // 'order-reference'
    $meta = $event->transaction->customIntegers['custom_int1']; // 42
});
```

Signature Generation
--------------------

[](#signature-generation)

Generate and verify PayFast signatures:

```
$signature = PayFast::generateSignature($data);
$isValid = PayFast::isValidSignature($data, $signature);
```

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

[](#configuration)

Full configuration options in `config/payfast.php`:

```
return [
    'merchant_id'  => env('PAYFAST_MERCHANT_ID'),
    'merchant_key' => env('PAYFAST_MERCHANT_KEY'),
    'passphrase'   => env('PAYFAST_PASSPHRASE'),
    'testing'      => env('PAYFAST_TESTING', true),
    'return_url'   => env('PAYFAST_RETURN_URL'),
    'cancel_url'   => env('PAYFAST_CANCEL_URL'),
    'notify_url'   => env('PAYFAST_NOTIFY_URL'),

    'urls' => [
        'sandbox'    => 'https://sandbox.payfast.co.za',
        'production' => 'https://www.payfast.co.za',
    ],

    'itn' => [
        'validate_ip'        => true,
        'allowed_ips'        => ['197.97.145.144/28', '41.74.179.192/27'],
        'validate_signature' => true,
    ],

    'webhook_route' => '/payfast/webhook',

    'spa' => [
        'enabled'    => env('PAYFAST_SPA_ENABLED', false),
        'prefix'     => 'api/payfast',
        'middleware'  => ['api', 'auth:sanctum'],
    ],
];
```

Testing
-------

[](#testing)

The package includes a full test suite:

```
composer test
```

Or run specific suites:

```
vendor/bin/phpunit --testsuite=Unit
vendor/bin/phpunit --testsuite=Feature
```

Sandbox Testing
---------------

[](#sandbox-testing)

1. Create a sandbox account at [sandbox.payfast.co.za](https://sandbox.payfast.co.za)
2. Set `PAYFAST_TESTING=true` in your `.env`
3. Use sandbox credentials for `PAYFAST_MERCHANT_ID` and `PAYFAST_MERCHANT_KEY`
4. All payments will use the sandbox environment

Publishing Assets
-----------------

[](#publishing-assets)

```
# Config only
php artisan vendor:publish --tag=payfast-config

# Blade views (for customization)
php artisan vendor:publish --tag=payfast-views

# Vue 3 components
php artisan vendor:publish --tag=payfast-vue

# React components
php artisan vendor:publish --tag=payfast-react
```

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

###  Health Score

19

—

LowBetter than 10% of packages

Maintenance55

Moderate activity, may be stable

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

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

---

Top Contributors

[![RockHardJim](https://avatars.githubusercontent.com/u/11999830?v=4)](https://github.com/RockHardJim "RockHardJim (1 commits)")

### Embed Badge

![Health badge](/badges/tumelo-laravel-payfast/health.svg)

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

###  Alternatives

[omnipay/paypal

PayPal gateway for Omnipay payment processing library

3156.8M53](/packages/omnipay-paypal)[eduardokum/laravel-boleto

Biblioteca com boletos para o laravel

626351.9k2](/packages/eduardokum-laravel-boleto)[tbbc/money-bundle

This is a Symfony bundle that integrates moneyphp/money library (Fowler pattern): https://github.com/moneyphp/money.

1961.9M](/packages/tbbc-money-bundle)[2checkout/2checkout-php

2Checkout PHP Library

83740.3k2](/packages/2checkout-2checkout-php)[smhg/sepa-qr-data

Generate QR code data for SEPA payments

61717.2k5](/packages/smhg-sepa-qr-data)[omnipay/dummy

Dummy driver for the Omnipay payment processing library

271.2M33](/packages/omnipay-dummy)

PHPackages © 2026

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