PHPackages                             sitehandy/omnipay-toyyibpay - 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. sitehandy/omnipay-toyyibpay

ActiveLibrary[Payment Processing](/categories/payments)

sitehandy/omnipay-toyyibpay
===========================

toyyibPay driver for the Omnipay payment processing library

1.0.0(7mo ago)42.0k↓100%6[1 PRs](https://github.com/sitehandy/omnipay-toyyibpay/pulls)MITPHPPHP ^7.4 || ^8.0

Since Aug 16Pushed 7mo ago1 watchersCompare

[ Source](https://github.com/sitehandy/omnipay-toyyibpay)[ Packagist](https://packagist.org/packages/sitehandy/omnipay-toyyibpay)[ Docs](https://github.com/sitehandy/omnipay-toyyibpay)[ RSS](/packages/sitehandy-omnipay-toyyibpay/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (6)Versions (2)Used By (0)

Omnipay: toyyibPay
==================

[](#omnipay-toyyibpay)

**toyyibPay driver for the Omnipay PHP payment processing library**

[![Latest Stable Version](https://camo.githubusercontent.com/34e695c6016bc2a934a96bed696e29b2f2ab562a7134d65a55d00653cd506bea/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d312e302e302d626c75652e737667)](https://github.com/sitehandy/omnipay-toyyibpay/releases/tag/v1.0.0)[![PHP Version](https://camo.githubusercontent.com/248632894d9d27a25ffd8e154ef857059e7aedef81ab34c3a5b19fd6a912d3a0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d372e342532422d626c75652e737667)](https://php.net)[![License](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)](LICENSE)

[Omnipay](https://github.com/thephpleague/omnipay) is a framework agnostic, multi-gateway payment processing library for PHP. This package implements toyyibPay support for Omnipay.

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

[](#requirements)

- PHP 7.4 or higher
- PHP 8.0, 8.1, 8.2, 8.3, 8.4 supported
- cURL extension
- JSON extension
- Omnipay 3.x

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

[](#installation)

Omnipay is installed via [Composer](http://getcomposer.org/). To install, simply require `league/omnipay` and `sitehandy/omnipay-toyyibpay` with Composer:

```
composer require league/omnipay sitehandy/omnipay-toyyibpay
```

> **Note**: Composer will automatically select the latest stable version. If you need a specific version, you can specify it, but using version constraints like `^1.0` may cause warnings.

### Version Information

[](#version-information)

- **v1.0.0**: First stable release with PHP 7.4-8.4 support, modern HTTP client, and comprehensive testing
- **Requirements**: PHP 7.4+ with cURL and JSON extensions
- **Compatibility**: Omnipay 3.x framework

Table of Contents
-----------------

[](#table-of-contents)

- [Basic Usage](#basic-usage)
- [Quick Start](#quick-start)
- [Advanced Configuration](#advanced-configuration)
- [Error Handling](#error-handling)
- [Testing](#testing)
- [Security Best Practices](#security-best-practices)
- [Troubleshooting](#troubleshooting)
- [API Reference](#api-reference)

Basic Usage
-----------

[](#basic-usage)

For general usage instructions, please see the main [Omnipay](https://github.com/thephpleague/omnipay)repository.

toyyibPay Category &amp; Bill
-----------------------------

[](#toyyibpay-category--bill)

Each payment is a `Bill`, which is under a `Category`. To begin, you need to open an account at [toyyibPay.com](https://toyyibpay.com/e/2238297686400) and then create a Category. Then, retrieve the `Category Code` for the gateway setup.

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

[](#quick-start)

```
use Omnipay\Omnipay;

// Initialize the gateway
$gateway = Omnipay::create('ToyyibPay');
$gateway->setTestMode(true); // Use false for production

// Create a simple payment
$response = $gateway->purchase([
    'userSecretKey' => 'your-secret-key',
    'categoryCode' => 'your-category-code',
    'billName' => 'Product Purchase',
    'billDescription' => 'Payment for product XYZ',
    'billAmount' => 50.00, // RM 50.00
    'billReturnUrl' => 'https://yoursite.com/return',
    'billCallbackUrl' => 'https://yoursite.com/callback',
    'billExternalReferenceNo' => 'ORDER-' . time(),
    'billTo' => 'John Doe',
    'billEmail' => 'john@example.com',
    'billPhone' => '0123456789'
])->send();

if ($response->isRedirect()) {
    $response->redirect();
} else {
    echo 'Error: ' . $response->getMessage();
}
```

Advanced Configuration
----------------------

[](#advanced-configuration)

### Complete Payment with All Options

[](#complete-payment-with-all-options)

```
use Omnipay\Omnipay;

$gateway = Omnipay::create('ToyyibPay');
$gateway->setTestMode(true);

$response = $gateway->purchase([
    // Required parameters
    'userSecretKey' => 'your-secret-key',
    'categoryCode' => 'your-category-code',
    'billName' => 'Premium Product Package',
    'billDescription' => 'Complete package with premium features',
    'billAmount' => 299.99,
    'billReturnUrl' => 'https://yoursite.com/payment/return',
    'billCallbackUrl' => 'https://yoursite.com/payment/callback',
    'billExternalReferenceNo' => 'ORD-' . date('YmdHis') . '-' . rand(1000, 9999),
    'billTo' => 'Jane Smith',
    'billEmail' => 'jane.smith@example.com',
    'billPhone' => '+60123456789',

    // Optional parameters
    'billPriceSetting' => 0, // 0=fixed, 1=open amount
    'billPayorInfo' => 1, // 0=optional, 1=required
    'billSplitPayment' => 0, // 0=disabled, 1=enabled
    'billSplitPaymentArgs' => '', // JSON string for split payment
    'billPaymentChannel' => 0, // 0=all, 1=FPX only, 2=credit card only
    'billDisplayMerchant' => 1, // 0=hide, 1=show merchant info
    'billContentEmail' => 'Thank you for your purchase! Your order will be processed within 24 hours.',
    'billChargeToCustomer' => 2, // 1=merchant, 2=customer pays fees

    // Custom fields (JSON encoded)
    'billAdditionalField' => [
        'product_id' => 'PROD-12345',
        'customer_tier' => 'premium',
        'promotion_code' => 'SAVE20',
        'notes' => 'Express delivery requested'
    ]
])->send();

if ($response->isRedirect()) {
    // Store transaction details before redirect
    $_SESSION['transaction_id'] = $response->getTransactionReference();
    $_SESSION['order_id'] = $options['billExternalReferenceNo'];

    $response->redirect();
} else {
    throw new Exception('Payment creation failed: ' . $response->getMessage());
}
```

### Split Payment Configuration

[](#split-payment-configuration)

```
// Example for split payment between multiple merchants
$splitPaymentArgs = [
    [
        'userSecretKey' => 'merchant1-secret-key',
        'amount' => 150.00
    ],
    [
        'userSecretKey' => 'merchant2-secret-key',
        'amount' => 149.99
    ]
];

$response = $gateway->purchase([
    'userSecretKey' => 'main-merchant-secret-key',
    'categoryCode' => 'your-category-code',
    'billName' => 'Marketplace Order',
    'billDescription' => 'Order from multiple vendors',
    'billAmount' => 299.99,
    'billSplitPayment' => 1,
    'billSplitPaymentArgs' => json_encode($splitPaymentArgs),
    // ... other required parameters
])->send();
```

### Custom Payment Channels

[](#custom-payment-channels)

```
// FPX (Online Banking) only
$response = $gateway->purchase([
    'billPaymentChannel' => 1, // FPX only
    // ... other parameters
]);

// Credit/Debit Card only
$response = $gateway->purchase([
    'billPaymentChannel' => 2, // Card only
    // ... other parameters
]);

// All payment methods (default)
$response = $gateway->purchase([
    'billPaymentChannel' => 0, // All methods
    // ... other parameters
]);
```

Example
-------

[](#example)

### How to create a Bill

[](#how-to-create-a-bill)

Reference:

Bill serves as an invoice to your customer. The example below explains how you can create a toyyibPay Bill and then redirect the customer to the payment page.

```
$gateway = Omnipay::create('ToyyibPay');

// Use sandbox mode for testing
$gateway->setTestMode(1);

// You need to pass the following parameters to generate bill code
$options = [
    'userSecretKey' => 'YOURSECRETKEY',
    'categoryCode' => 'CATEGORYCODE',
    'billName' => 'Product Name',
    'billDescription' => 'Product Description',
    'billPriceSetting'=> 0,
    'billPayorInfo'=> 1,
    'billAmount'=> 1,
    'billReturnUrl'=>'https://yourwebsite.com/returnurl',
    'billCallbackUrl'=>'https://yourwebsite.com/callbackurl',
    'billExternalReferenceNo' => 'ORDER123',
    'billTo'=>'Customer Name',
    'billEmail'=>'customer@sampleemail.test',
    'billPhone'=>'0123456789',
    'billSplitPayment'=> 0,
    'billSplitPaymentArgs'=>'',
    'billPaymentChannel'=> 0,
    'billDisplayMerchant'=> 1,
    'billContentEmail' => 'Sample email content',
    'billChargeToCustomer' => 2
];

// Send a purchase request to create a bill
$response = $gateway->purchase($options)->send();

// Available response method
// $response->isSuccessful(); // is the response successful?
// $response->isRedirect(); // is the response a redirect?
// $response->getTransactionReference(); // a reference generated by the payment gateway
// $response->getTransactionId(); // the reference set by the originating website if available.
// $response->getMessage(); // a message generated by the payment gateway

// Now redirect the customer to the toyyibPay bill payment page
if ($response->isRedirect())
{
    // Do whatever you want here for example saving the data to the database etc
    // and then redirect the customer to the offsite payment gateway
    $response->redirect();
}
else
{
    // Display error message
    exit($response->getMessage());
}
```

### How to get Bill Transactions

[](#how-to-get-bill-transactions)

Reference:

You may check bill payment status by submitting Bill Code and Bill Payment Status(Optional).

The code below gives an example how to retrieve the bill transactions from the payment gateway server:

```
$gateway = Omnipay::create('ToyyibPay');

// Parameters required
$options = [
    'billCode' => 'samplebillcode'
];

// Send a complete purchase request to get the bill transactions
$response = $gateway->completePurchase($options)->send();

// Available response method
// $response->isSuccessful(); // is the response successful?
// $response->isRedirect(); // is the response a redirect?
// $response->getTransactionReference(); // a reference generated by the payment gateway
// $response->getTransactionId(); // the reference set by the originating website if available.
// $response->getMessage(); // a message generated by the payment gateway

if ($response->isSuccessful())
{
    // Do whatever you want here for example saving the data to the database etc
    echo $responsive->getTransactionReference();
}
elseif ($response->isRedirect())
{
    // If the payment is not successful, redirect the customer to the payment page for completion
    $response->redirect();
}
else
{
    // Display error message
    exit($response->getMessage());
}
```

Error Handling
--------------

[](#error-handling)

### Comprehensive Error Handling

[](#comprehensive-error-handling)

```
use Omnipay\Omnipay;
use Omnipay\Common\Exception\InvalidRequestException;
use Exception;

try {
    $gateway = Omnipay::create('ToyyibPay');
    $gateway->setTestMode(true);

    $response = $gateway->purchase([
        'userSecretKey' => 'your-secret-key',
        'categoryCode' => 'your-category-code',
        'billName' => 'Test Payment',
        'billDescription' => 'Test payment description',
        'billAmount' => 10.00,
        'billReturnUrl' => 'https://yoursite.com/return',
        'billCallbackUrl' => 'https://yoursite.com/callback',
        'billExternalReferenceNo' => 'TEST-' . time(),
        'billTo' => 'Test Customer',
        'billEmail' => 'test@example.com',
        'billPhone' => '0123456789'
    ])->send();

    if ($response->isRedirect()) {
        // Success - redirect to payment page
        $response->redirect();
    } else {
        // Handle payment creation failure
        $errorMessage = $response->getMessage();
        error_log('toyyibPay payment creation failed: ' . $errorMessage);

        // Show user-friendly error message
        throw new Exception('Unable to process payment. Please try again later.');
    }

} catch (InvalidRequestException $e) {
    // Handle validation errors (missing required fields, etc.)
    error_log('toyyibPay validation error: ' . $e->getMessage());
    throw new Exception('Payment information is incomplete. Please check your details.');

} catch (Exception $e) {
    // Handle general errors
    error_log('toyyibPay general error: ' . $e->getMessage());
    throw new Exception('Payment service is temporarily unavailable. Please try again later.');
}
```

### Payment Completion Error Handling

[](#payment-completion-error-handling)

```
try {
    $response = $gateway->completePurchase([
        'billCode' => $_GET['billcode'] ?? null
    ])->send();

    if ($response->isSuccessful()) {
        // Payment successful
        $transactionId = $response->getTransactionId();
        $transactionRef = $response->getTransactionReference();

        // Update your database
        updateOrderStatus($transactionId, 'paid');

        // Redirect to success page
        header('Location: /payment/success?ref=' . $transactionRef);
        exit;

    } elseif ($response->isRedirect()) {
        // Payment still pending - redirect back to payment page
        $response->redirect();

    } else {
        // Payment failed
        $errorMessage = $response->getMessage();
        error_log('Payment verification failed: ' . $errorMessage);

        // Redirect to failure page
        header('Location: /payment/failed?error=' . urlencode($errorMessage));
        exit;
    }

} catch (Exception $e) {
    error_log('Payment completion error: ' . $e->getMessage());
    header('Location: /payment/error');
    exit;
}
```

Testing
-------

[](#testing)

### Unit Testing Example

[](#unit-testing-example)

```
use PHPUnit\Framework\TestCase;
use Omnipay\Omnipay;

class ToyyibPayGatewayTest extends TestCase
{
    private $gateway;

    protected function setUp(): void
    {
        $this->gateway = Omnipay::create('ToyyibPay');
        $this->gateway->setTestMode(true);
    }

    public function testPurchaseSuccess()
    {
        $options = [
            'userSecretKey' => 'test-secret-key',
            'categoryCode' => 'test-category',
            'billName' => 'Test Product',
            'billDescription' => 'Test Description',
            'billAmount' => 50.00,
            'billReturnUrl' => 'https://example.com/return',
            'billCallbackUrl' => 'https://example.com/callback',
            'billExternalReferenceNo' => 'TEST-123',
            'billTo' => 'John Doe',
            'billEmail' => 'john@example.com',
            'billPhone' => '0123456789'
        ];

        $response = $this->gateway->purchase($options)->send();

        $this->assertTrue($response->isRedirect());
        $this->assertFalse($response->isSuccessful());
        $this->assertNotEmpty($response->getRedirectUrl());
    }

    public function testPurchaseWithMissingParameters()
    {
        $this->expectException(InvalidRequestException::class);

        $response = $this->gateway->purchase([
            'billName' => 'Test Product'
            // Missing required parameters
        ])->send();
    }

    public function testCompletePurchase()
    {
        $response = $this->gateway->completePurchase([
            'billCode' => 'test-bill-code'
        ])->send();

        // Response should be either successful, redirect, or have error message
        $this->assertTrue(
            $response->isSuccessful() ||
            $response->isRedirect() ||
            !empty($response->getMessage())
        );
    }
}
```

### Integration Testing with Mock Data

[](#integration-testing-with-mock-data)

```
// Test with sandbox environment
$gateway = Omnipay::create('ToyyibPay');
$gateway->setTestMode(true); // Always use test mode for testing

// Use test credentials (get these from toyyibPay sandbox)
$testOptions = [
    'userSecretKey' => 'sandbox-secret-key',
    'categoryCode' => 'sandbox-category-code',
    'billName' => 'Test Payment - ' . date('Y-m-d H:i:s'),
    'billDescription' => 'Integration test payment',
    'billAmount' => 1.00, // Use small amount for testing
    'billReturnUrl' => 'https://httpbin.org/get?return=true',
    'billCallbackUrl' => 'https://httpbin.org/post',
    'billExternalReferenceNo' => 'TEST-' . uniqid(),
    'billTo' => 'Test Customer',
    'billEmail' => 'test@example.com',
    'billPhone' => '0123456789'
];

$response = $gateway->purchase($testOptions)->send();

if ($response->isRedirect()) {
    echo "Test payment created successfully!\n";
    echo "Payment URL: " . $response->getRedirectUrl() . "\n";
    echo "Bill Code: " . $response->getTransactionReference() . "\n";
} else {
    echo "Test failed: " . $response->getMessage() . "\n";
}
```

Security Best Practices
-----------------------

[](#security-best-practices)

### 1. Secure Credential Management

[](#1-secure-credential-management)

```
// Use environment variables for sensitive data
$gateway = Omnipay::create('ToyyibPay');
$gateway->setTestMode(getenv('TOYYIBPAY_TEST_MODE') === 'true');

$options = [
    'userSecretKey' => getenv('TOYYIBPAY_SECRET_KEY'), // Never hardcode
    'categoryCode' => getenv('TOYYIBPAY_CATEGORY_CODE'),
    // ... other options
];
```

### 2. Validate Callback Data

[](#2-validate-callback-data)

```
// In your callback handler
function handleCallback()
{
    // Verify the callback is from toyyibPay
    $billCode = $_POST['billcode'] ?? null;
    $status = $_POST['status_id'] ?? null;

    if (!$billCode || !$status) {
        http_response_code(400);
        exit('Invalid callback data');
    }

    // Verify payment status with toyyibPay API
    $gateway = Omnipay::create('ToyyibPay');
    $response = $gateway->completePurchase(['billCode' => $billCode])->send();

    if ($response->isSuccessful()) {
        // Update order status in your database
        updateOrderStatus($billCode, 'paid');

        // Send confirmation email
        sendPaymentConfirmation($billCode);
    }

    // Always respond with 200 OK to acknowledge receipt
    http_response_code(200);
    echo 'OK';
}
```

### 3. Input Validation and Sanitization

[](#3-input-validation-and-sanitization)

```
function createPayment($orderData)
{
    // Validate and sanitize input data
    $billAmount = filter_var($orderData['amount'], FILTER_VALIDATE_FLOAT);
    if ($billAmount === false || $billAmount  $billAmount,
        'billEmail' => $billEmail,
        'billPhone' => $billPhone,
        'billName' => $billName,
        'billTo' => $billTo
    ];
}
```

Troubleshooting
---------------

[](#troubleshooting)

### Common Issues and Solutions

[](#common-issues-and-solutions)

#### 1. "Invalid Secret Key" Error

[](#1-invalid-secret-key-error)

**Problem**: Getting authentication errors when creating bills.

**Solutions**:

- Verify your secret key is correct and active
- Check if you're using the right environment (sandbox vs production)
- Ensure the secret key matches the category code

```
// Debug: Check your credentials
$gateway = Omnipay::create('ToyyibPay');
$gateway->setTestMode(true); // Make sure this matches your secret key environment

// Test with minimal required parameters first
$response = $gateway->purchase([
    'userSecretKey' => 'your-secret-key',
    'categoryCode' => 'your-category-code',
    'billName' => 'Debug Test',
    'billDescription' => 'Testing credentials',
    'billAmount' => 1.00,
    'billReturnUrl' => 'https://example.com/return',
    'billCallbackUrl' => 'https://example.com/callback',
    'billExternalReferenceNo' => 'DEBUG-' . time(),
    'billTo' => 'Test',
    'billEmail' => 'test@example.com',
    'billPhone' => '0123456789'
])->send();
```

#### 2. Callback Not Working

[](#2-callback-not-working)

**Problem**: Not receiving payment notifications.

**Solutions**:

- Ensure callback URL is publicly accessible (not localhost)
- Check server logs for incoming requests
- Verify callback URL returns HTTP 200 status
- Test callback URL manually

```
// Debug callback handler
function debugCallback()
{
    // Log all incoming data
    error_log('Callback received: ' . print_r($_POST, true));
    error_log('Headers: ' . print_r(getallheaders(), true));

    // Always respond with 200
    http_response_code(200);
    echo 'OK';
}
```

#### 3. Amount Formatting Issues

[](#3-amount-formatting-issues)

**Problem**: Incorrect amount being charged.

**Solution**: toyyibPay expects amount in cents (multiply by 100).

```
// Correct amount formatting
$amountInRM = 50.00; // RM 50.00
$response = $gateway->purchase([
    'billAmount' => $amountInRM, // Library handles conversion automatically
    // ... other parameters
]);

// The library automatically converts RM to cents internally
// RM 50.00 becomes 5000 cents
```

#### 4. SSL/TLS Issues

[](#4-ssltls-issues)

**Problem**: Connection errors when making API calls.

**Solutions**:

- Ensure your server supports TLS 1.2 or higher
- Update cURL and OpenSSL libraries
- Check firewall settings

```
// Test SSL connectivity
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://toyyibpay.com/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);

$result = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);

if ($error) {
    echo "SSL Error: " . $error;
} else {
    echo "SSL connection successful";
}
```

### Debug Mode

[](#debug-mode)

```
// Enable debug logging
$gateway = Omnipay::create('ToyyibPay');
$gateway->setTestMode(true);

// Log all requests and responses
class DebugHttpClient implements \Http\Client\HttpClient
{
    private $client;

    public function __construct($client)
    {
        $this->client = $client;
    }

    public function sendRequest($request)
    {
        error_log('Request: ' . $request->getMethod() . ' ' . $request->getUri());
        error_log('Body: ' . $request->getBody());

        $response = $this->client->sendRequest($request);

        error_log('Response: ' . $response->getStatusCode());
        error_log('Response Body: ' . $response->getBody());

        return $response;
    }
}

// Use debug client
$gateway->setHttpClient(new DebugHttpClient($gateway->getHttpClient()));
```

API Reference
-------------

[](#api-reference)

### Gateway Methods

[](#gateway-methods)

#### `purchase(array $options)`

[](#purchasearray-options)

Creates a new bill for payment.

**Required Parameters:**

- `userSecretKey` (string): Your toyyibPay secret key
- `categoryCode` (string): Category code from your toyyibPay account
- `billName` (string): Name/title of the bill
- `billDescription` (string): Description of the payment
- `billAmount` (float): Amount in RM (e.g., 50.00 for RM 50)
- `billReturnUrl` (string): URL to redirect after payment
- `billCallbackUrl` (string): URL for payment notifications
- `billExternalReferenceNo` (string): Your internal reference number
- `billTo` (string): Customer name
- `billEmail` (string): Customer email
- `billPhone` (string): Customer phone number

**Optional Parameters:**

- `billPriceSetting` (int): 0=fixed amount, 1=open amount
- `billPayorInfo` (int): 0=optional customer info, 1=required
- `billSplitPayment` (int): 0=disabled, 1=enabled
- `billSplitPaymentArgs` (string): JSON string for split payment configuration
- `billPaymentChannel` (int): 0=all methods, 1=FPX only, 2=cards only
- `billDisplayMerchant` (int): 0=hide merchant info, 1=show
- `billContentEmail` (string): Custom email content
- `billChargeToCustomer` (int): 1=merchant pays fees, 2=customer pays fees
- `billAdditionalField` (array): Custom fields (will be JSON encoded)

#### `completePurchase(array $options)`

[](#completepurchasearray-options)

Retrieves bill transaction status.

**Required Parameters:**

- `billCode` (string): Bill code returned from purchase request

**Optional Parameters:**

- `billpaymentStatus` (int): Filter by payment status

### Response Methods

[](#response-methods)

#### Purchase Response

[](#purchase-response)

- `isRedirect()`: Returns true if customer should be redirected
- `getRedirectUrl()`: Gets the payment page URL
- `getTransactionReference()`: Gets the bill code
- `getMessage()`: Gets error message if failed

#### Complete Purchase Response

[](#complete-purchase-response)

- `isSuccessful()`: Returns true if payment was successful
- `isRedirect()`: Returns true if payment is still pending
- `getTransactionId()`: Gets the payment invoice number
- `getTransactionReference()`: Gets the bill permalink
- `getMessage()`: Gets status message

### Payment Status Codes

[](#payment-status-codes)

- `1`: Successful transaction
- `2`: Pending transaction
- `3`: Unsuccessful transaction
- `4`: Pending (alternative status)

Support
-------

[](#support)

If you are having general issues with Omnipay, we suggest posting on [Stack Overflow](http://stackoverflow.com/). Be sure to add the [omnipay tag](http://stackoverflow.com/questions/tagged/omnipay) so it can be easily found.

If you want to keep up to date with release anouncements, discuss ideas for the project, or ask more detailed questions, there is also a [mailing list](https://groups.google.com/forum/#!forum/omnipay) which you can subscribe to.

If you believe you have found a bug, please report it using the [GitHub issue tracker](https://github.com/sitehandy/omnipay-toyyibpay/issues), or better yet, fork the library and submit a pull request.

###  Health Score

37

—

LowBetter than 84% of packages

Maintenance64

Regular maintenance activity

Popularity23

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

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

Unknown

Total

1

Last Release

219d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ecbe713eb8a62b8aaf0a6e86eb18bad1a1e6410fc8d2b4a47da6dbfeeff5d16c?d=identicon)[sitehandy](/maintainers/sitehandy)

---

Top Contributors

[![amirolzolkifli](https://avatars.githubusercontent.com/u/6100743?v=4)](https://github.com/amirolzolkifli "amirolzolkifli (11 commits)")[![sitehandy](https://avatars.githubusercontent.com/u/22477788?v=4)](https://github.com/sitehandy "sitehandy (6 commits)")

---

Tags

paymentgatewaypaymerchantomnipayMalaysiafpxtoyyibpay

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/sitehandy-omnipay-toyyibpay/health.svg)

```
[![Health](https://phpackages.com/badges/sitehandy-omnipay-toyyibpay/health.svg)](https://phpackages.com/packages/sitehandy-omnipay-toyyibpay)
```

###  Alternatives

[omnipay/payfast

PayFast driver for the Omnipay payment processing library

24622.6k3](/packages/omnipay-payfast)

PHPackages © 2026

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