PHPackages                             rainwaves/payfast-payment - 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. rainwaves/payfast-payment

ActiveLibrary[Payment Processing](/categories/payments)

rainwaves/payfast-payment
=========================

This is a PHP package for integrating with the PayFast.co.za payment gateway. It provides a convenient way to handle one-time payments and recurring billing in your PHP applications, with support for both vanilla PHP and Laravel.

v1.7.0(2mo ago)01.1kMITPHPPHP ^7.4|^8.0|^8.1|^8.2|^8.3|^8.4|^8.5

Since Jul 13Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/Magnificent-Big-J/payfast-payment)[ Packagist](https://packagist.org/packages/rainwaves/payfast-payment)[ RSS](/packages/rainwaves-payfast-payment/feed)WikiDiscussions main Synced today

READMEChangelog (8)Dependencies (5)Versions (10)Used By (0)

Payfast Payment Package
=======================

[](#payfast-payment-package)

A PHP package for integrating with the PayFast payment gateway. Supports one-time payments, recurring subscriptions, and ITN (Instant Transaction Notification) validation — for both vanilla PHP and Laravel.

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

[](#installation)

```
composer require rainwaves/payfast-payment
```

Compatibility
-------------

[](#compatibility)

PackagePHPLaravelv1.7.x7.4 – 8.510 – 13Laravel 10+ requires PHP 8.1+. Laravel 11+ requires PHP 8.2+. Laravel 12+ requires PHP 8.2+. Laravel 13+ requires PHP 8.3+.

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

[](#configuration)

### Laravel

[](#laravel)

Publish the config file:

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

Then set your credentials in `.env`:

```
PAYFAST_MERCHANT_ID=10000100
PAYFAST_MERCHANT_KEY=46f0cd694581a
PAYFAST_ENV=local
PAYFAST_RETURN_URL=https://example.com/success
PAYFAST_CANCEL_URL=https://example.com/cancel
PAYFAST_NOTIFY_URL=https://example.com/notify
PAYFAST_PASS_PHRASE=your_passphrase
```

> **Note:** The legacy unprefixed env names (`MERCHANT_ID`, `MERCHANT_KEY`, `ENVIRONMENT`, etc.) still work as fallbacks, but `PAYFAST_` prefixed names are recommended to avoid conflicts with other packages.

### Vanilla PHP

[](#vanilla-php)

Pass a config array directly:

```
$config = [
    'merchant_id'  => '10000100',
    'merchant_key' => '46f0cd694581a',
    'env'          => 'local',           // 'local' or 'production'
    'return_url'   => 'https://example.com/success',
    'cancel_url'   => 'https://example.com/cancel',
    'notify_url'   => 'https://example.com/notify',
    'pass_phrase'  => 'your_passphrase',
];
```

Usage
-----

[](#usage)

### One-time Payment (Vanilla PHP)

[](#one-time-payment-vanilla-php)

```
require 'vendor/autoload.php';

use rainwaves\PayfastPayment\PayFast;

$payFast = new PayFast($config);

$input = [
    'amount'             => 100.00,
    'item_name'          => 'Test Product',
    'name_first'         => 'John',
    'name_last'          => 'Doe',
    'email_address'      => 'john@example.com',
    'm_payment_id'       => 'order-1234',
    'email_confirmation' => true,
    'custom_str1'        => 'internal-ref',
];

echo $payFast->makePaymentWithAForm($input)->createForm();
```

A hidden-field HTML form is returned, which submits the user to PayFast.

### One-time Payment (Laravel — dependency injection)

[](#one-time-payment-laravel--dependency-injection)

```
use rainwaves\PayfastPayment\Contract\PayFastInterface;

class PaymentController extends Controller
{
    public function __construct(private PayFastInterface $payFast) {}

    public function checkout(Request $request): string
    {
        $input = [
            'amount'        => 100.00,
            'item_name'     => 'Gold Plan',
            'email_address' => $request->user()->email,
            'm_payment_id'  => $request->user()->id,
        ];

        return $this->payFast->makePaymentWithAForm($input)->createForm();
    }
}
```

### Subscriptions

[](#subscriptions)

```
use rainwaves\PayfastPayment\PayFastSubscription;
use rainwaves\PayfastPayment\Model\Frequency;

$payFast = new PayFastSubscription($config);

$input = [
    'amount'                    => 100.00,
    'item_name'                 => 'Gold Plan',
    'billing_date'              => '2026-05-01',
    'recurring_amount'          => 100.00,
    'frequency'                 => Frequency::MONTHLY,
    'cycles'                    => 0,   // 0 = indefinite
    'subscription_notify_email'   => true,
    'subscription_notify_webhook' => true,
    'subscription_notify_buyer'   => true,
];

echo $payFast->createSubscriptionWithAForm($input)->createForm();
```

### Optional Payment Fields

[](#optional-payment-fields)

FieldDescription`payment_method`Restrict to one method: `eft`, `cc`, `dc`, `bc`, `mp`, `mc`, `cd`, `sc``email_confirmation`Send buyer a confirmation email (`true`/`false`)`confirmation_address`Override email for confirmation`custom_int1..5`Integer custom fields (passed through ITN)`custom_str1..5`String custom fields, max 255 chars each### Frequency Constants

[](#frequency-constants)

```
Frequency::DAILY      // 1
Frequency::WEEKLY     // 2
Frequency::MONTHLY    // 3
Frequency::QUARTERLY  // 4
Frequency::BI_ANNUAL  // 5
Frequency::ANNUAL     // 6
```

ITN (Instant Transaction Notification) Validation
-------------------------------------------------

[](#itn-instant-transaction-notification-validation)

PayFast POSTs an ITN to your `notify_url` after each payment. **Validate all four checks** before acting on the notification.

```
use rainwaves\PayfastPayment\Itn\PayFastItnValidator;
use rainwaves\PayfastPayment\Model\Route;

$payload = $_POST;
$rawBody = file_get_contents('php://input');
$isSandbox = config('payfast.env') !== 'production';

$validator = new PayFastItnValidator(
    $payload,
    config('payfast.pass_phrase'),
    $rawBody
);

// 1. Source IP — always first
if (!$validator->validateSourceIp($_SERVER['REMOTE_ADDR'], $isSandbox)) {
    http_response_code(403);
    exit;
}

// 2. Signature
if (!$validator->validateSignature()) {
    http_response_code(400);
    exit;
}

// 3. Amount — compare against your stored order amount
if (!$validator->validateAmount('100.00')) {
    http_response_code(400);
    exit;
}

// 4. Merchant ID
if (!$validator->validateMerchantId(config('payfast.merchant_id'))) {
    http_response_code(400);
    exit;
}

// 5. (Optional) Server-side confirmation with PayFast endpoint
$validateUrl = Route::getValidationUrl(config('payfast.env'));
if (!$validator->validateWithPayFastEndpoint($validateUrl)) {
    http_response_code(400);
    exit;
}

// 6. Replay-attack protection — pf_payment_id must be unique
$paymentId = $validator->getPaymentId();
// … check that $paymentId hasn't been processed before …

// 7. Handle the response
$response = $validator->response();

if ($response->isComplete()) {
    // fulfil order
}
```

> **Tip:** PayFast requires a passphrase on your account for recurring billing. Without one, subscription signatures will fail.

Testing
-------

[](#testing)

```
vendor/bin/phpunit
```

License
-------

[](#license)

MIT

###  Health Score

48

—

FairBetter than 93% of packages

Maintenance86

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 94.6% 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.

###  Release Activity

Cadence

Every ~145 days

Recently: every ~252 days

Total

8

Last Release

70d ago

PHP version history (2 changes)v1.0.0PHP ^7.4|^8.0|^8.1|^8.2

v1.7.0PHP ^7.4|^8.0|^8.1|^8.2|^8.3|^8.4|^8.5

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/30896750?v=4)[Joel Mnisi](/maintainers/Magnificent-Big-J)[@Magnificent-Big-J](https://github.com/Magnificent-Big-J)

---

Top Contributors

[![Magnificent-Big-J](https://avatars.githubusercontent.com/u/30896750?v=4)](https://github.com/Magnificent-Big-J "Magnificent-Big-J (53 commits)")[![mnisij](https://avatars.githubusercontent.com/u/14214514?v=4)](https://github.com/mnisij "mnisij (3 commits)")

### Embed Badge

![Health badge](/badges/rainwaves-payfast-payment/health.svg)

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

###  Alternatives

[linkxtr/laravel-qrcode

A clean, modern, and easy-to-use QR code generator for Laravel

3720.4k](/packages/linkxtr-laravel-qrcode)

PHPackages © 2026

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