# Introduction

Plutu provides a REST API for developers to integrate Plutu's payment gateways and services with their own applications. The Plutu API uses HTTP methods for making requests and returns responses in JSON format, making it easy for developers to interact with the platform.&#x20;

The Plutu API is available in two modes: Live Mode and Test Mode. Live Mode is intended for production use and requires a valid API access token to authenticate requests. On the other hand, Test Mode is designed for experimentation and testing purposes, allowing developers to test their code without making any live transactions. To switch between these modes, developers simply need to specify the appropriate API access token in their requests.

## Getting Started <a href="#getting-started" id="getting-started"></a>

To get started with Plutu you will have to follow these steps :&#x20;

### Create an Account <a href="#id-1-create-an-account" id="id-1-create-an-account"></a>

If you have not yet created an account, you can begin by visiting the [Sign-up page](https://my.plutus.ly/register/) on the dashboard. From there, you will need to provide your email address and create a password to complete the registration process.

### Prepare Your Access Token

After signing in to the dashboard and verifying your account, [get your API key and Access token](https://my.plutus.ly/api-management/api-keys-tokens) to authenticate your API request.

Once you have signed in to the dashboard and verified your account, you will need to obtain your [API key and Access token](https://my.plutus.ly/api-management/api-keys-tokens) to authenticate your API requests. These credentials will be used to access the Plutu API and enable you to make authenticated requests to the platform.


# Authentication

Plutu API authentication

To authenticate your account when using the API, including your API key and access token in the request. You can manage your access tokens, such as getting a test or production live access token or renewing them, in the Dashboard. It's important to keep your API access token secret since it carries many privileges.

To access the API, Plutu uses access tokens. You must pass the access token and API key with all endpoint requests.

{% hint style="info" %}

* Do not store them in insecure or easily accessible locations. Client-side files, such as JavaScript or HTML files, should never be used to store sensitive information, as these can easily be accessed.
* Do not store access tokens in code files that can be decompiled, such as Native iOS, Android, or Windows Application code files.&#x20;
* When making calls, always pass access tokens over a secure (HTTPS) connection.
  {% endhint %}

### &#x20;**Generating Access Token**

1. Click on **Configurations** on the sidebar.
2. Click on the **API Keys & Token**.
3. Under the **Access token** section.
4. Select what environment to generate an access token and then click "**Generate**".


# IP Whitelist

IP Whitelist filters requests to allow only from your own servers and reject others.

IP Whitelist is an optional but recommended feature for your account, especially for your (Production) Live Environment. It automatically filters your requests to whitelist them if they are coming from your own servers or reject them otherwise. whether the key is live or test. That means when you, for example, enable IP Whitelist for your account, you will be restricting all requests with a whitelist.

When IP Whitelist is enabled for your account, and Plutu receives an HTTP request authenticated with your access token, Plutu will validate the IP Address of this incoming request, then the request will be automatically rejected if the IP Address is not whitelisted in your IP Whitelist.

### How to add an IP  to the whitelist?

To add an IP to the whitelist, go to your Dashboard and visit your account **Configurations** > **API Whitelisted IPs**.<br>


# Payments

Our platform supports a range of payment gateways and services to help you accept payments from your customers easily and securely. Here are the Plutu payment gateways that we currently support:

* [**Sadad**](/api-documentation/payments/sadad)
* [**Adfali**](/api-documentation/payments/adfali)
* [**Local Bank Cards**](/api-documentation/payments/local-bank-cards)
* [**MPGS**](/api-documentation/payments/mpgs)
* [**T-Lync Service**](/api-documentation/payments/t-lync)


# Sadad

Mobile payment service provided by Al-Madar

#### Send OTP

&#x20;This request will validate the customer identity, send OTP and register an unpaid invoice.

## Send OTP

<mark style="color:green;">`POST`</mark> `https://api.plutus.ly/api/v1/transaction/sadadapi/verify`

Send the OTP to the customer's phone number to initiate the transaction

#### Headers

| Name                                            | Type   | Description             |
| ----------------------------------------------- | ------ | ----------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer: \[Access token] |
| X-API-KEY<mark style="color:red;">\*</mark>     | String | API Key                 |

#### Request Body

| Name                                             | Type   | Description                                                                                                                                                                       |
| ------------------------------------------------ | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| mobile\_number<mark style="color:red;">\*</mark> | String | Starts with 091 or 093                                                                                                                                                            |
| birth\_year<mark style="color:red;">\*</mark>    | String | 4 digits XXXX                                                                                                                                                                     |
| amount<mark style="color:red;">\*</mark>         | String | <p>Transaction amount in Libyan dinars.</p><p>Formatting is allowed with a maximum of two decimal places: <strong>XXX</strong>, <strong>XX.X</strong>, <strong>XX.XX</strong></p> |

{% tabs %}
{% tab title="200: OK Successful response" %}

```javascript
{
    "status": 200,
    "result": {
        "process_id": xxxxxxxxxxxxx
    },
    "message": "OTP has been sent to your mobile number"
}
```

{% endtab %}

{% tab title="400: Bad Request Error response" %}

```javascript
{
    "error": {
        "status": 4xx,
        "code": "ERROR_CODE_PLACEHOLDER",
        "message": "ERROR_MESSAGE_PLACEHOLDER"
    }
}
```

You can review the [Errors](/api-documentation/errors) section for all possible errors
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="CURL" %}
{% code overflow="wrap" %}

```php
curl --location --request POST 'https://api.plutus.ly/api/v1/transaction/sadadapi/verify' \
--header 'X-API-KEY: [API_KEY]' \
--header 'Authorization: Bearer [ACCESS_TOEKN]' \
--form 'mobile_number="[MOBILE_NUMBER]"' \
--form 'amount="[AMONUT]"' \
--form 'birth_year="[BIRTH_YEAR]"'
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code overflow="wrap" lineNumbers="true" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.plutus.ly/api/v1/transaction/sadadapi/verify',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
    'mobile_number' => '[MOBILE_NUMBER]', 
    'amount' => '[AMONUT]', 
    'birth_year' => '[BIRTH_YEAR]'
  ),
  CURLOPT_HTTPHEADER => array(
    'X-API-KEY: [API_KEY]',
    'Authorization: Bearer [ACCESS_TOEKN]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}
{% endtab %}

{% tab title="Plutu PHP Package" %}
{% code lineNumbers="true" %}

```php
<?php

use Plutu\Services\PlutuSadad;

$mobileNumber = '090000000'; // Mobile number should start with 09
$birthYear = '1991'; // Birth year
$amount = 5.0; // amount in float format

try {

    $api = new PlutuSadad;
    $api->setCredentials('api_key', 'access_token');
    $apiResponse = $api->verify($mobileNumber, $birthYear, $amount);

    if ($apiResponse->getOriginalResponse()->isSuccessful()) {

        // Process ID should be sent in the confirmation step
        $processId = $apiResponse->getProcessId();

    } elseif ($apiResponse->getOriginalResponse()->hasError()) {

        // Possible errors from Plutu API
        // @see https://docs.plutu.ly/api-documentation/errors Plutu API Error Documentation
        $errorCode = $apiResponse->getOriginalResponse()->getErrorCode();
        $errorMessage = $apiResponse->getOriginalResponse()->getErrorMessage();
        $statusCode = $apiResponse->getOriginalResponse()->getStatusCode();
        $responseData = $apiResponse->getOriginalResponse()->getBody();

    }

// Handle exceptions that may be thrown during the execution of the code
// The following are the expected exceptions that may be thrown:
// Check the "Handle Exceptions and Errors" section for more details
// 
// InvalidAccessTokenException, InvalidApiKeyException
// InvalidMobileNumberException, InvalidBirthYearException, InvalidAmountException
} catch (\Exception $e) {
    $exception = $e->getMessage();
}
```

{% endcode %}

Check out the example [Verify Process (Send OTP)](https://github.com/getplutu/plutu-php/blob/main/examples.md#verify-process-send-otp-1) in the Plutu PHP Examples document on GitHub.
{% endtab %}
{% endtabs %}

#### Confirm

Pay the unpaid transaction

## Confirm

<mark style="color:green;">`POST`</mark> `https://api.plutus.ly/api/v1/transaction/sadadapi/confirm`

Confirm to pay the transaction

#### Headers

| Name                                            | Type   | Description             |
| ----------------------------------------------- | ------ | ----------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer: \[Access token] |
| X-API-KEY<mark style="color:red;">\*</mark>     | String | API Key                 |

#### Request Body

| Name                                          | Type   | Description                                                                                                                                                                       |
| --------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| process\_id<mark style="color:red;">\*</mark> | String | Process ID is returned in the verify step                                                                                                                                         |
| code<mark style="color:red;">\*</mark>        | String | OTP code is sent to customer's phone number                                                                                                                                       |
| amount<mark style="color:red;">\*</mark>      | String | <p>Transaction amount in Libyan dinars.</p><p>Formatting is allowed with a maximum of two decimal places: <strong>XXX</strong>, <strong>XX.X</strong>, <strong>XX.XX</strong></p> |
| invoice\_no<mark style="color:red;">\*</mark> | String | Invoice number associated with transaction, **must be unique and not previously used.**                                                                                           |
| customer\_ip                                  | String | Customer IP address                                                                                                                                                               |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "status": 200,
    "result": {
        "transaction_id": xxxxxxxxxxxxx,
        "amount": xxxxxxxxxxxxx
    },
    "message": "Transaction completed successfully"
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```javascript
{
    "error": {
        "status": 4xx,
        "code": "ERROR_CODE_PLACEHOLDER",
        "message": "ERROR_MESSAGE_PLACEHOLDER"
    }
}
```

You can review the [Errors](/api-documentation/errors) section for all possible errors
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="CURL" %}
{% code overflow="wrap" %}

```php
curl --location --request POST 'https://api.plutus.ly/api/v1/transaction/sadadapi/confirm'
--header 'X-API-KEY: API_KEY]'
--header 'Authorization: Bearer [ACCESS_TOEKN]'
--form 'code="[OTP]"'
--form 'amount="[AMONUT]"'
--form 'invoice_no="[INVOICE_NO]"'
--form 'process_id="[PROCESS_ID]"'
--form 'customer_ip="[CUSTOMER_IP]"'
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code overflow="wrap" lineNumbers="true" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.plutus.ly/api/v1/transaction/sadadapi/confirm',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
    'code' => '[OTP]', 
    'amount' => '[AMONUT]', 
    'invoice_no' => '[INVOICE_NO]', 
    'process_id' => '[PROCESS_ID]', 
    'customer_ip' => '[CUSTOMER_IP]'
  ),
  CURLOPT_HTTPHEADER => array(
    'X-API-KEY: [API_KEY]',
    'Authorization: Bearer [ACCESS_TOEKN]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}
{% endtab %}

{% tab title="Plutu PHP Package" %}

```php
<?php

use Plutu\Services\PlutuSadad;

$processId = 'xxxxx'; // the Process ID that received in the verification step
$code = '111111'; // OTP
$amount = 5.0; // amount in float format
$invoiceNo = 'inv-12345'; // invoice number
    
try {

    $api = new PlutuSadad;
    $api->setCredentials('api_key', 'access_token');
    $apiResponse = $api->confirm($processId, $code, $amount, $invoiceNo);

    if($apiResponse->getOriginalResponse()->isSuccessful()){

        // The transaction has been completed
        // Plutu Transaction ID
        $transactionId = $apiResponse->getTransactionId();
        // Response Data
        $data = $apiResponse->getOriginalResponse()->getBody();

    } elseif($apiResponse->getOriginalResponse()->hasError()) {

        // Possible errors from Plutu API
        // @see https://docs.plutu.ly/api-documentation/errors Plutu API Error Documentation
        $errorCode = $apiResponse->getOriginalResponse()->getErrorCode();
        $errorMessage = $apiResponse->getOriginalResponse()->getErrorMessage();
        $statusCode = $apiResponse->getOriginalResponse()->getStatusCode();
        $responseData = $apiResponse->getOriginalResponse()->getBody();

    }

// Handle exceptions that may be thrown during the execution of the code
// The following are the expected exceptions that may be thrown:
// Check the "Handle Exceptions and Errors" section for more details
// 
// InvalidAccessTokenException, InvalidApiKeyException
// InvalidProcessIdException, InvalidCodeException, InvalidAmountException, InvalidInvoiceNoException
} catch (\Exception $e) {
    $exception = $e->getMessage();
}
```

Check out the example [Confirm Process (Pay)](https://github.com/getplutu/plutu-php/blob/main/examples.md#confirm-process-pay-1) in the Plutu PHP Examples document on GitHub.
{% endtab %}
{% endtabs %}


# Adfali

Provided by the Bank of Commerce and Development

#### Send OTP

&#x20;This request will validate the customer identity, send OTP and register an unpaid invoice.

## Send OTP

<mark style="color:green;">`POST`</mark> `https://api.plutus.ly/api/v1/transaction/edfali/verify`

Send the OTP to the customer's phone number to initiate the transaction

#### Headers

| Name                                            | Type   | Description             |
| ----------------------------------------------- | ------ | ----------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer: \[Access token] |
| X-API-KEY<mark style="color:red;">\*</mark>     | String | API Key                 |

#### Request Body

| Name                                             | Type   | Description                                                                                                                                                                       |
| ------------------------------------------------ | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| mobile\_number<mark style="color:red;">\*</mark> | String | Mobile number 09XXXXXXXX                                                                                                                                                          |
| amount<mark style="color:red;">\*</mark>         | String | <p>Transaction amount in Libyan dinars.</p><p>Formatting is allowed with a maximum of two decimal places: <strong>XXX</strong>, <strong>XX.X</strong>, <strong>XX.XX</strong></p> |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "status": 200,
    "result": {
        "process_id": xxxxxxxxxxxxx
    },
    "message": "OTP has been sent to your mobile number"
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```javascript
{
    "error": {
        "status": 4xx,
        "code": "ERROR_CODE_PLACEHOLDER",
        "message": "ERROR_MESSAGE_PLACEHOLDER"
    }
}
```

You can review the [Errors](/api-documentation/errors) section for all possible errors
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="CURL" %}
{% code overflow="wrap" %}

```php
curl --location --request POST 'https://api.plutus.ly/api/v1/transaction/edfali/verify' \
--header 'X-API-KEY: [API_KEY]' \
--header 'Authorization: Bearer [ACCESS_TOEKN]' \
--form 'mobile_number="[MOBILE_NUMBER]"' \
--form 'amount="[AMONUT]"'
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code overflow="wrap" lineNumbers="true" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.plutus.ly/api/v1/transaction/edfali/verify',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
    'mobile_number' => '[MOBILE_NUMBER]', 
    'amount' => '[AMONUT]', 
  ),
  CURLOPT_HTTPHEADER => array(
    'X-API-KEY: [API_KEY]',
    'Authorization: Bearer [ACCESS_TOEKN]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}
{% endtab %}

{% tab title="Plutu PHP Package" %}
{% code lineNumbers="true" %}

```php
<?php

use Plutu\Services\PlutuAdfali;

$mobileNumber = '090000000'; // Mobile number should start with 09
$amount = 5.0; // amount in float format

try {
    $api = new PlutuAdfali;
    $api->setCredentials('api_key', 'access_token');

    $apiResponse = $api->verify($mobileNumber, $amount);

    if ($apiResponse->getOriginalResponse()->isSuccessful()) {

        // Process ID should be sent in the confirmation step
        $processId = $apiResponse->getProcessId();

    } elseif ($apiResponse->getOriginalResponse()->hasError()) {

        // Possible errors from Plutu API
        // @see https://docs.plutu.ly/api-documentation/errors Plutu API Error Documentation
        $errorCode = $apiResponse->getOriginalResponse()->getErrorCode();
        $errorMessage = $apiResponse->getOriginalResponse()->getErrorMessage();
        $statusCode = $apiResponse->getOriginalResponse()->getStatusCode();
        $responseData = $apiResponse->getOriginalResponse()->getBody();

    }

// Handle exceptions that may be thrown during the execution of the code
// The following are the expected exceptions that may be thrown:
// Check the "Handle Exceptions and Errors" section for more details
// 
// InvalidAccessTokenException, InvalidApiKeyException
// InvalidMobileNumberException, InvalidAmountException
} catch (\Exception $e) {
    $exception = $e->getMessage();
}
```

{% endcode %}

Check out the example [Verify Process (Send OTP)](https://github.com/getplutu/plutu-php/blob/main/examples.md#verify-process-send-otp) in the Plutu PHP Examples document on GitHub.
{% endtab %}
{% endtabs %}

#### Confirm

Pay the unpaid transaction

## Confirm

<mark style="color:green;">`POST`</mark> `https://api.plutus.ly/api/v1/transaction/edfali/confirm`

Confirm to pay the transaction

#### Headers

| Name                                            | Type   | Description             |
| ----------------------------------------------- | ------ | ----------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer: \[Access token] |
| X-API-KEY<mark style="color:red;">\*</mark>     | String | API Key                 |

#### Request Body

| Name                                          | Type   | Description                                                                                                                                                                       |
| --------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| process\_id<mark style="color:red;">\*</mark> | String | Process ID is returned in the verify step                                                                                                                                         |
| code<mark style="color:red;">\*</mark>        | String | OTP code is sent to customer's phone number                                                                                                                                       |
| amount<mark style="color:red;">\*</mark>      | String | <p>Transaction amount in Libyan dinars.</p><p>Formatting is allowed with a maximum of two decimal places: <strong>XXX</strong>, <strong>XX.X</strong>, <strong>XX.XX</strong></p> |
| invoice\_no<mark style="color:red;">\*</mark> | String | Invoice number associated with transaction, **must be unique and not previously used.**                                                                                           |
| customer\_ip                                  | String | Customer IP address                                                                                                                                                               |

{% tabs %}
{% tab title="200: OK Successful response" %}

```javascript
{
    "status": 200,
    "result": {
        "transaction_id": xxxxxxxxxxxxx,
        "amount": xxxxxxxxxxxxx
    },
    "message": "Transaction completed successfully"
}
```

{% endtab %}

{% tab title="400: Bad Request Error response" %}

```javascript
{
    "error": {
        "status": 4xx,
        "code": "ERROR_CODE_PLACEHOLDER",
        "message": "ERROR_MESSAGE_PLACEHOLDER"
    }
}
```

You can review the [Errors](/api-documentation/errors) section for all possible errors
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="CURL" %}
{% code overflow="wrap" %}

```php
curl --location --request POST 'https://api.plutus.ly/api/v1/transaction/edfali/confirm'
--header 'X-API-KEY: API_KEY]'
--header 'Authorization: Bearer [ACCESS_TOEKN]'
--form 'code="[OTP]"'
--form 'amount="[AMONUT]"'
--form 'invoice_no="[INVOICE_NO]"'
--form 'process_id="[PROCESS_ID]"'
--form 'customer_ip="[CUSTOMER_IP]"'
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code overflow="wrap" lineNumbers="true" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.plutus.ly/api/v1/transaction/edfali/confirm',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
    'code' => '[OTP]', 
    'amount' => '[AMONUT]', 
    'invoice_no' => '[INVOICE_NO]', 
    'process_id' => '[PROCESS_ID]', 
    'customer_ip' => '[CUSTOMER_IP]'
  ),
  CURLOPT_HTTPHEADER => array(
    'X-API-KEY: [API_KEY]',
    'Authorization: Bearer [ACCESS_TOEKN]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}
{% endtab %}

{% tab title="Plutu PHP Package" %}
{% code lineNumbers="true" %}

```php
<?php

use Plutu\Services\PlutuAdfali;

$processId = 'xxxxx'; // the Process ID that received in the verification step
$code = '1111'; // OTP
$amount = 5.0; // amount in float format
$invoiceNo = 'inv-12345'; // invoice number

try {

    $api = new PlutuAdfali;
    $api->setCredentials('api_key', 'access_token');

    $apiResponse = $api->confirm($processId, $code, $amount, $invoiceNo);

    if($apiResponse->getOriginalResponse()->isSuccessful()){

        // The transaction has been completed
        // Plutu Transaction ID
        $transactionId = $apiResponse->getTransactionId();
        // Response Data
        $data = $apiResponse->getOriginalResponse()->getBody();

    } elseif($apiResponse->getOriginalResponse()->hasError()) {

        // Possible errors from Plutu API
        // @see https://docs.plutu.ly/api-documentation/errors Plutu API Error Documentation
        $errorCode = $apiResponse->getOriginalResponse()->getErrorCode();
        $errorMessage = $apiResponse->getOriginalResponse()->getErrorMessage();
        $statusCode = $apiResponse->getOriginalResponse()->getStatusCode();
        $responseData = $apiResponse->getOriginalResponse()->getBody();

    }

// Handle exceptions that may be thrown during the execution of the code
// The following are the expected exceptions that may be thrown:
// Check the "Handle Exceptions and Errors" section for more details
// 
// InvalidAccessTokenException, InvalidApiKeyException
// InvalidProcessIdException, InvalidCodeException, InvalidAmountException, InvalidInvoiceNoException
} catch (\Exception $e) {
    $exception = $e->getMessage();
}
```

{% endcode %}

Check out the example [Confirm Process (Pay)](https://github.com/getplutu/plutu-php/blob/main/examples.md#confirm-process-pay) in the Plutu PHP Examples document on GitHub.
{% endtab %}
{% endtabs %}


# Local Bank Cards

Local bank cards managed by Numo network

#### Pay

Pay the transaction.

## Confirm (Pay)

<mark style="color:green;">`POST`</mark> `https://api.plutus.ly/api/v1/transaction/localbankcards/confirm`

Pay the transaction

#### Headers

| Name                                            | Type   | Description             |
| ----------------------------------------------- | ------ | ----------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer: \[Access token] |
| X-API-KEY<mark style="color:red;">\*</mark>     | String | API Key                 |

#### Request Body

| Name                                          | Type   | Description                                                                                                                                                                       |
| --------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| amount<mark style="color:red;">\*</mark>      | String | <p>Transaction amount in Libyan dinars.</p><p>Formatting is allowed with a maximum of two decimal places: <strong>XXX</strong>, <strong>XX.X</strong>, <strong>XX.XX</strong></p> |
| invoice\_no<mark style="color:red;">\*</mark> | String | Invoice number associated with transaction, **must be unique and not previously used.**                                                                                           |
| return\_url<mark style="color:red;">\*</mark> | String | Redirect URL after completing the payments                                                                                                                                        |
| customer\_ip                                  | String | \[Optional] Customer IP address                                                                                                                                                   |
| lang                                          | String | \[Optional] Accepts **ar** or **en**, by default **ar**                                                                                                                           |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "status": 200,
    "result": {
        "code": "CHECKOUT_REDIRECT",
        "redirect_url": "https://xxxxxxxxxxxxxxx"
    }
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```javascript
{
    "error": {
        "status": 4xx,
        "code": "ERROR_CODE_PLACEHOLDER",
        "message": "ERROR_MESSAGE_PLACEHOLDER"
    }
}
```

You can review the [Errors](/api-documentation/errors) section for all possible errors
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="CURL" %}
{% code overflow="wrap" %}

```php
curl --location --request POST 'https://api.plutus.ly/api/v1/transaction/localbankcards/confirm' \
--header 'X-API-KEY: [API_KEY]' \
--header 'Authorization: Bearer [ACCESS_TOKEN]' \
--form 'amount="[AMONUT]"' \
--form 'invoice_no="[INVOICE_NO]"' \
--form 'return_url="[RETURN_URL]"' \
--form 'customer_ip="[CUSTOMER_IP]"'
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code overflow="wrap" lineNumbers="true" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.plutus.ly/api/v1/transaction/localbankcards/confirm',
  CURLOPT_RETURNTRANSFER => true,

  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
    'amount' => '[AMONUT]', 
    'invoice_no' => '[INVOICE_NO]', 
    'return_url' => '[RETURN_URL]', 
    'customer_ip' => '[CUSTOMER_IP]'
  ),
  CURLOPT_HTTPHEADER => array(
    'X-API-KEY: [API_KEY]',
    'Authorization: Bearer [ACCESS_TOKEN]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}
{% endtab %}

{% tab title="Plutu PHP Package" %}
{% code lineNumbers="true" %}

```php
<?php

use Plutu\Services\PlutuLocalBankCards;

$amount = 5.0; // amount in float format
$invoiceNo = 'inv-12345'; // invoice number
$returnUrl = 'https://example.com/callback/handler'; // the url to handle the callback from plutu

try {

    $api = new PlutuLocalBankCards;
    $api->setCredentials('api_key', 'access_token', 'secret_key');
    $apiResponse = $api->confirm($amount, $invoiceNo, $returnUrl);

    if ($apiResponse->getOriginalResponse()->isSuccessful()) {

        // Redirect URL for Plutu checkout page
        $redirectUrl = $apiResponse->getRedirectUrl();

        // You should rediect the customer to payment checkout page
        // header("location: " . $redirectUrl);

    } elseif ($apiResponse->getOriginalResponse()->hasError()) {

        // Possible errors from Plutu API
        // @see https://docs.plutu.ly/api-documentation/errors Plutu API Error Documentation
        $errorCode = $apiResponse->getOriginalResponse()->getErrorCode();
        $errorMessage = $apiResponse->getOriginalResponse()->getErrorMessage();
        $statusCode = $apiResponse->getOriginalResponse()->getStatusCode();
        $responseData = $apiResponse->getOriginalResponse()->getBody();

    }

// Handle exceptions that may be thrown during the execution of the code
// The following are the expected exceptions that may be thrown:
// Check the "Handle Exceptions and Errors" section for more details
// 
// InvalidAccessTokenException, InvalidApiKeyException, InvalidSecretKeyException,
// InvalidAmountException, InvalidInvoiceNoException, InvalidReturnUrlException
} catch (\Exception $e) {
    $exception = $e->getMessage();
}
```

{% endcode %}

Check out the example [Confirm (Pay)](https://github.com/getplutu/plutu-php/blob/main/examples.md#confirm-pay) in the Plutu PHP Examples document on GitHub.
{% endtab %}
{% endtabs %}

### Callback handler

The callback will be received from Plutu when the transaction is completed or canceled. This gives a Merchant better control of how the transaction is processed on the Merchant's side. This is useful e.g. when you want to mark an order as paid, update your shop's inventory, or add appropriate records to Merchant’s internal accounting system.

**Callback response parameters:**

The callback is called with HTTP **GET** and with the same query string parameters as in the redirect

<table><thead><tr><th width="150">Parameter</th><th>Description</th><th data-hidden>Value</th></tr></thead><tbody><tr><td>gateway</td><td>Gateway name: <strong>localbankcards</strong></td><td></td></tr><tr><td>approved</td><td>It will only be returned if the transaction is approved and completed, <strong>and</strong> <strong>must be checked</strong> <strong>to be 1 (true)</strong></td><td>1</td></tr><tr><td>canceled</td><td>It will only be returned if the transaction is canceled by the customer</td><td></td></tr><tr><td>invoice_no</td><td>Invoice number sent in the pay request</td><td></td></tr><tr><td>amount</td><td>amount sent in the request</td><td></td></tr><tr><td>transaction_id</td><td>Plutu transaction id</td><td></td></tr><tr><td>hashed</td><td>Hash message authorization code (HMAC) is used to verify both the data integrity and the authorization of a message.</td><td></td></tr></tbody></table>

{% hint style="info" %}
SHA-256 HMAC is calculated as follows:

* The SHA-256 HMAC calculation includes all response query string parameters and key-value pairs except the “**hashed**” parameter.&#x20;
* Create an SHA-256 HMAC of the resultant string using the secret key created in the Plutu account, convert it to uppercase, and compare it with the “**hashed**” parameter received in the callback.
  {% endhint %}


# MPGS

Mastercard Payment Gateway Services (MPGS) is a secure payment gateway that enables businesses to accept online payments from customers through various payment channels.

#### Pay

Pay the transaction.

## Confirm (Pay)

<mark style="color:green;">`POST`</mark> `https://api.plutus.ly/api/v1/transaction/mpgs/confirm`

Pay the transaction

#### Headers

| Name                                            | Type   | Description             |
| ----------------------------------------------- | ------ | ----------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer: \[Access token] |
| X-API-KEY<mark style="color:red;">\*</mark>     | String | API Key                 |

#### Request Body

| Name                                          | Type   | Description                                                                                                                                                                    |
| --------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| amount<mark style="color:red;">\*</mark>      | String | <p>Transaction amount in US dollars.</p><p>Formatting is allowed with a maximum of two decimal places: <strong>XXX</strong>, <strong>XX.X</strong>, <strong>XX.XX</strong></p> |
| invoice\_no<mark style="color:red;">\*</mark> | String | Invoice number associated with transaction, **must be unique and not previously used.**                                                                                        |
| return\_url<mark style="color:red;">\*</mark> | String | Redirect URL after completing the payments                                                                                                                                     |
| customer\_ip                                  | String | \[Optional] Customer IP address                                                                                                                                                |
| lang                                          | String | \[Optional] Accepts **ar** or **en**, by default **ar**                                                                                                                        |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "status": 200,
    "result": {
        "code": "CHECKOUT_REDIRECT",
        "redirect_url": "https://xxxxxxxxxxxxxxx"
    }
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```javascript
{
    "error": {
        "status": 4xx,
        "code": "ERROR_CODE_PLACEHOLDER",
        "message": "ERROR_MESSAGE_PLACEHOLDER"
    }
}
```

You can review the [Errors](/api-documentation/errors#mpgs-errors) section for all possible errors
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="CURL" %}
{% code overflow="wrap" %}

```php
curl --location --request POST 'https://api.plutus.ly/api/v1/transaction/mpgs/confirm' \
--header 'X-API-KEY: [API_KEY]' \
--header 'Authorization: Bearer [ACCESS_TOKEN]' \
--form 'amount="[AMONUT]"' \
--form 'invoice_no="[INVOICE_NO]"' \
--form 'return_url="[RETURN_URL]"' \
--form 'customer_ip="[CUSTOMER_IP]"'
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code overflow="wrap" lineNumbers="true" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.plutus.ly/api/v1/transaction/mpgs/confirm',
  CURLOPT_RETURNTRANSFER => true,

  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
    'amount' => '[AMONUT]', 
    'invoice_no' => '[INVOICE_NO]', 
    'return_url' => '[RETURN_URL]', 
    'customer_ip' => '[CUSTOMER_IP]'
  ),
  CURLOPT_HTTPHEADER => array(
    'X-API-KEY: [API_KEY]',
    'Authorization: Bearer [ACCESS_TOKEN]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}
{% endtab %}

{% tab title="Plutu PHP Package" %}
{% code lineNumbers="true" %}

```php
<?php

use Plutu\Services\PlutuMpgs;

$amount = 5.0; // amount in float format
$invoiceNo = 'inv-12345'; // invoice number
$returnUrl = 'https://example.com/callback/handler'; // the url to handle the callback from plutu

try {

    $api = new PlutuMpgs;
    $api->setCredentials('api_key', 'access_token', 'secret_key');
    $apiResponse = $api->confirm($amount, $invoiceNo, $returnUrl);

    if ($apiResponse->getOriginalResponse()->isSuccessful()) {

        // Redirect URL for Plutu checkout page
        $redirectUrl = $apiResponse->getRedirectUrl();

        // You should rediect the customer to payment checkout page
        // header("location: " . $redirectUrl);

    } elseif ($apiResponse->getOriginalResponse()->hasError()) {

        // Possible errors from Plutu API
        // @see https://docs.plutu.ly/api-documentation/errors Plutu API Error Documentation
        $errorCode = $apiResponse->getOriginalResponse()->getErrorCode();
        $errorMessage = $apiResponse->getOriginalResponse()->getErrorMessage();
        $statusCode = $apiResponse->getOriginalResponse()->getStatusCode();
        $responseData = $apiResponse->getOriginalResponse()->getBody();

    }

// Handle exceptions that may be thrown during the execution of the code
// The following are the expected exceptions that may be thrown:
// Check the "Handle Exceptions and Errors" section for more details
// 
// InvalidAccessTokenException, InvalidApiKeyException, InvalidSecretKeyException,
// InvalidAmountException, InvalidInvoiceNoException, InvalidReturnUrlException
} catch (\Exception $e) {
    $exception = $e->getMessage();
}
```

{% endcode %}

Check out the example [Confirm (Pay)](https://github.com/getplutu/plutu-php/blob/main/examples.md#confirm-pay-2) in the Plutu PHP Examples document on GitHub.
{% endtab %}
{% endtabs %}

### Callback handler

The callback will be received from Plutu when the transaction is completed or canceled. This gives a Merchant better control of how the transaction is processed on the Merchant's side. This is useful e.g. when you want to mark an order as paid, update your shop's inventory, or add appropriate records to Merchant’s internal accounting system.

**Callback response parameters:**

The callback is called with HTTP **GET** and with the same query string parameters as in the redirect

<table><thead><tr><th width="150">Parameter</th><th>Description</th><th data-hidden>Value</th></tr></thead><tbody><tr><td>gateway</td><td>Gateway name: <strong>mpgs</strong></td><td></td></tr><tr><td>approved</td><td>It will only be returned if the transaction is approved and completed <strong>and</strong> <strong>must be checked</strong> <strong>to be 1 (true)</strong></td><td>1</td></tr><tr><td>canceled</td><td>It will only be returned if the transaction is canceled by the customer</td><td></td></tr><tr><td>amount</td><td>amount sent in the request</td><td></td></tr><tr><td>currency</td><td>Transaction currency refers to the currency used for processing payments through MPGS and is configured in your Plutu account. It currently supports <strong>USD</strong></td><td></td></tr><tr><td>invoice_no</td><td>Invoice number sent in the pay request</td><td></td></tr><tr><td>transaction_id</td><td>Plutu transaction id</td><td></td></tr><tr><td>hashed</td><td>Hash message authorization code (HMAC) is used to verify both the data integrity and the authorization of a message.</td><td></td></tr></tbody></table>

{% hint style="info" %}
SHA-256 HMAC is calculated as follows:

* The SHA-256 HMAC calculation includes all response query string parameters and key-value pairs except the “**hashed**” parameter.&#x20;
* Create an SHA-256 HMAC of the resultant string using the secret key created in the Plutu account and convert it to uppercase and compare it with the “**hashed**” parameter received in the callback.
  {% endhint %}


# T-Lync Service

T-Lync service from Tadawul digital solution provider

#### Pay

Pay the transaction.

## Confirm (Pay)

<mark style="color:green;">`POST`</mark> `https://api.plutus.ly/api/v1/transaction/tlync/confirm`

Pay the transaction

#### Headers

| Name                                            | Type   | Description             |
| ----------------------------------------------- | ------ | ----------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Bearer: \[Access token] |
| X-API-KEY<mark style="color:red;">\*</mark>     | String | API Key                 |

#### Request Body

| Name                                             | Type   | Description                                                                                                                                                                                                                                     |
| ------------------------------------------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| amount<mark style="color:red;">\*</mark>         | String | <p>Transaction amount in Libyan dinars.</p><p>Formatting is allowed with a maximum of two decimal places: <strong>XXX</strong>, <strong>XX.X</strong>, <strong>XX.XX</strong></p>                                                               |
| invoice\_no<mark style="color:red;">\*</mark>    | String | Invoice number associated with transaction, **must be unique and not previously used.**                                                                                                                                                         |
| mobile\_number<mark style="color:red;">\*</mark> | String | Valid mobile number format start with 9x or 09                                                                                                                                                                                                  |
| email                                            | String | \[Optional] Email address                                                                                                                                                                                                                       |
| return\_url<mark style="color:red;">\*</mark>    | String | URL after payment is completed to allow the customer to return to the order/invoice                                                                                                                                                             |
| callback\_url<mark style="color:red;">\*</mark>  | String | <p>The URL of your Instant update Server URL to track your order/invoice, instantly sent by Plutu when the transaction is complete.<br><strong>This URL must be publicly accessible; private and localhost URLs are not supported.</strong></p> |
| customer\_ip                                     | String | \[Optional] Customer IP address                                                                                                                                                                                                                 |
| lang                                             | String | \[Optional]  **ar** or **en**, by default **ar**                                                                                                                                                                                                |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "status": 200,
    "result": {
        "code": "CHECKOUT_REDIRECT",
        "redirect_url": "https://xxxxxxxxxxxxxxx"
    }
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```javascript
{
    "error": {
        "status": 4xx,
        "code": "ERROR_CODE_PLACEHOLDER",
        "message": "ERROR_MESSAGE_PLACEHOLDER"
    }
}
```

You can review the [Errors](/api-documentation/errors) section for all possible errors
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="CURL" %}
{% code overflow="wrap" %}

```php
curl --location --request POST 'https://api.plutus.ly/api/v1/transaction/tlync/confirm' \
--header 'X-API-KEY: [API_KEY]' \
--header 'Authorization: Bearer [ACCESS_TOKEN]' \
--form 'amount="[AMONUT]"' \
--form 'invoice_no="[INVOICE_NO]"' \
--form 'return_url="[RETURN_URL]"' \
--form 'callback_url="[CALLBACK_URL]"' \
--form 'mobile_number="[MOBILE_NUMBER]"' \
--form 'customer_ip="[CUSTOMER_IP]"'
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code overflow="wrap" lineNumbers="true" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.plutus.ly/api/v1/transaction/tlync/confirm',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
    'amount' => '[AMONUT]', 
    'invoice_no' => '[INVOICE_NO]', 
    'return_url' => '[RETURN_URL]', 
    'callback_url' => '[CALLBACK_URL]', 
    'mobile_number' => '[MOBILE_NUMBER]', 
    'customer_ip' => '[CUSTOMER_IP]'
  ),
  CURLOPT_HTTPHEADER => array(
    'X-API-KEY: [API_KEY]',
    'Authorization: Bearer [ACCESS_TOKEN]'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}
{% endtab %}

{% tab title="Plutu PHP Package" %}
{% code lineNumbers="true" %}

```php
<?php

use Plutu\Services\PlutuTlync;

$amount = 5.0; // amount in float format
$invoiceNo = 'inv-12345'; // invoice number
$returnUrl = 'https://example.com/return/handler'; // the url to handle the return from plutu after payment completed from T-Lync
$callbackUrl = 'https://example.com/callback/handler'; // the url to handle the callback trgigger from plutu after payment completed from T-Lync

try {

    $api = new PlutuTlync;
    $api->setCredentials('api_key', 'access_token', 'secret_key');
    $apiResponse = $api->confirm($amount, $invoiceNo, $returnUrl, $callbackUrl);

    if ($apiResponse->getOriginalResponse()->isSuccessful()) {

        // Redirect URL for Plutu and T-Lync checkout page
        $redirectUrl = $apiResponse->getRedirectUrl();

        // You should rediect the customer to payment checkout page
        // header("location: " . $redirectUrl);

    } elseif ($apiResponse->getOriginalResponse()->hasError()) {

        // Possible errors from Plutu API
        // @see https://docs.plutu.ly/api-documentation/errors Plutu API Error Documentation
        $errorCode = $apiResponse->getOriginalResponse()->getErrorCode();
        $errorMessage = $apiResponse->getOriginalResponse()->getErrorMessage();
        $statusCode = $apiResponse->getOriginalResponse()->getStatusCode();
        $responseData = $apiResponse->getOriginalResponse()->getBody();

    }

// Handle exceptions that may be thrown during the execution of the code
// The following are the expected exceptions that may be thrown:
// Check the "Handle Exceptions and Errors" section for more details
// 
// InvalidAccessTokenException, InvalidApiKeyException, InvalidSecretKeyException,
// InvalidAmountException, InvalidInvoiceNoException, InvalidReturnUrlException, InvalidCallbackUrlException
} catch (\Exception $e) {
    $exception = $e->getMessage();
}
```

{% endcode %}

Check out the example [Confirm (Pay)](https://github.com/getplutu/plutu-php/blob/main/examples.md#confirm-pay-1) in the Plutu PHP Examples document on GitHub.
{% endtab %}
{% endtabs %}

### Callback handler

The callback will be received from Plutu when the transaction is completed. This gives a Merchant better control of how the transaction is processed on the Merchant's side. This is useful e.g. when you want to mark an order as paid, update your shop's inventory, or add appropriate records to Merchant’s internal accounting system.

**Callback parameters:**

The callback is called with HTTP **POST** as JSON

<table><thead><tr><th width="150">Parameter</th><th>Description</th><th data-hidden>Value</th></tr></thead><tbody><tr><td>gateway</td><td>Gateway name: <strong>tlync</strong></td><td></td></tr><tr><td>approved</td><td>1 or 0 (true, false), the transaction is completed <strong>and</strong> <strong>must be checked</strong> <strong>to be 1 (true)</strong></td><td>1</td></tr><tr><td>invoice_no</td><td>Invoice number sent in the pay request</td><td></td></tr><tr><td>amount</td><td>The amount sent in the request</td><td></td></tr><tr><td>paymet_method</td><td>The payment method in which the transaction was completed on T-Lync.<br>Supported payment methods: tadawul, edfaly, sadad, mobicash, and moamalat</td><td></td></tr><tr><td>transaction_id</td><td>Plutu transaction id</td><td></td></tr><tr><td>hashed</td><td>Hash message authorization code (HMAC) is used to verify both the data integrity and the authorization of a message.</td><td></td></tr></tbody></table>

### Return handler

Once the payment has been completed client can be redirected to the merchant-provided return URL.

**Return parameters:**

The callback is called with HTTP **GET** and with the same query string parameters as in the redirect

<table><thead><tr><th width="150">Parameter</th><th>Description</th><th data-hidden>Value</th></tr></thead><tbody><tr><td>approved</td><td>Transaction completed</td><td>1</td></tr><tr><td>invoice_no</td><td>Invoice number sent in the pay request</td><td></td></tr><tr><td>hashed</td><td>Hash message authorization code (HMAC) is used to verify both the data integrity and the authorization of a message.</td><td></td></tr></tbody></table>

{% hint style="info" %}
SHA-256 HMAC is calculated as follows:

* The SHA-256 HMAC calculation includes all response parameters and key-value pairs except the “**hashed**” parameter.&#x20;
* Create an SHA-256 HMAC of the resultant string using the secret key created in the Plutu account, convert it to uppercase, and compare it with the “**hashed**” parameter received in the callback or return handler.
  {% endhint %}


# Errors

Plutu provides a list of error codes and messages for troubleshooting payment integration issues.

Plutu uses [HTTP response status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, etc.). Codes in the 5xx range indicate an error with Plutu's servers (these are rare).

Some 4xx errors that could be handled programmatically (e.g., an invalid gateway) include an error code—a short string with a brief explanation—as a value for code. Below is a list of possible error codes that can be returned.

{% hint style="success" %}
**200**&#x20;
{% endhint %}

{% hint style="danger" %}
**401 -403 -404 -422 -429**
{% endhint %}

{% hint style="danger" %}
**500- 502 -503 - 504 - Server Error**
{% endhint %}

| Status                                 | Description                                                                                                                                                                          |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **200 - OK**                           | indicates that the request has succeeded, and everything works as expected.                                                                                                          |
| **400 - Bad Request**                  | indicates that the server cannot or will not process the request.                                                                                                                    |
| **401 - Unauthorized**                 | indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource. An invalid access token/API key was provided. |
| **403 - Forbidden**                    | indicates that the server understands the request but refuses to authorize it. API key doesn't have permission to perform the request.                                               |
| **404 - Not Found**                    | The requested resource doesn't exist.                                                                                                                                                |
| **422 - Un-processable Entity**        | Invalid fields will result in a 422 Unprocessable Entity response.                                                                                                                   |
| **429 - Too Many Requests**            | indicates the user has sent too many requests in a given amount of time.                                                                                                             |
| **500, 502, 503, 504 - Server Errors** | Something went wrong on Plutu's end. (These are rare).                                                                                                                               |

### R**EVIEWING ERRORS**

To monitor your integration and review errors, Plutu logs every API request your integration makes, whether it was successful or failed. You can access the logs section of the Dashboard under Gateways to review these errors.

### General Errors

General errors are a type of error that can occur when using a payment gateway integration. They are not specific to any particular endpoint or gateway and can be caused by a variety of issues such as incorrect input data, network connectivity problems, or errors with the integration itself. It's important to review these errors and understand their root cause in order to address them and ensure the smooth functioning of your payment gateway integration.

<table data-view="cards"><thead><tr><th>Error Code</th><th>Description</th></tr></thead><tbody><tr><td><strong>MAINTENANCE_MODE</strong></td><td>Plutu maintenance mode is enabled</td></tr><tr><td><strong>UNAUTHORIZED</strong></td><td>Invalid access token/API key provided, or your account has not been approved yet</td></tr><tr><td><strong>DENIED_ACCESS_GATEWAY</strong></td><td>Access denied, you do not have permission to access the payment method</td></tr><tr><td><strong>MISSING_PARAMETER</strong></td><td>Due to the missing payment gateway configuration</td></tr><tr><td><strong>INVALID_INPUTS</strong></td><td>Payment fields are incorrectly filled out</td></tr><tr><td><strong>BACKEND_ERROR</strong></td><td>Plutu Backend error</td></tr><tr><td><strong>FORBIDDEN_IP_ADDRESS</strong></td><td>The IP address is not whitelisted</td></tr><tr><td><strong>TEST_MODE_NOT_SUPPORTED</strong></td><td>Test mode is not supported for payment gateway</td></tr><tr><td><strong>TOO_MAY_REQUESTS</strong></td><td>Too many requests received</td></tr><tr><td><strong>INVALID_AMOUNT_FORMAT</strong></td><td>Transaction amount format is invalid, format is allowed with a maximum of two decimal places: XXX, XX.X, XX.XX</td></tr><tr><td><strong>AMOUNT_NOT_ALLOWED</strong></td><td>Amount must be greater than zero</td></tr><tr><td><strong>AMOUNT_EXCEEDED_MAXIMUM</strong></td><td>Amount exceeded the maximum amount allowed for a transaction: <strong>50000</strong> per transaction. <br>For sandbox: maximum <strong>500</strong> per transaction</td></tr><tr><td><strong>CURRENCY_NOT_SUPPORTED</strong></td><td>Currency is not supported</td></tr><tr><td><strong>SANDBOX_TRANSACTION_LIMIT_EXCEEDED</strong></td><td>Reaching the maximum number of transactions allowed during the period specified in the <strong>sandbox</strong> environment</td></tr></tbody></table>

### Sadad Errors

The following errors, as well as [General Errors](#general-errors), can be returned.

<table data-view="cards"><thead><tr><th>Error Code</th><th>Description</th></tr></thead><tbody><tr><td><strong>INVALID_AMOUNT</strong></td><td>Invalid amount</td></tr><tr><td><strong>INVALID_PROCESS_ID</strong></td><td>The process ID is invalid or does not match the value received in the (<strong><code>verify)</code></strong> request (lifetime 10 minutes)</td></tr><tr><td><strong>INVALID_MOBILE_NUMBER</strong></td><td>Incorrect mobile number</td></tr><tr><td><strong>INVALID_MOBILE_NUMBER_OR_BIRTH_YEAR</strong></td><td>Incorrect mobile number/year of birth</td></tr><tr><td><strong>INVLIAD_OTP</strong></td><td>Invalid OTP. please check your code and try again</td></tr><tr><td><strong>INVALID_INVOICE_AMOUNT_OR_NUMBER</strong></td><td>Invoice number already exists</td></tr><tr><td><strong>EMPTY_MOBILE_NUMBER</strong></td><td>The mobile number is empty</td></tr><tr><td><strong>EMPTY_BIRTH_YEAR</strong></td><td>Birth year is empty</td></tr><tr><td><strong>OTP_EXPIRED</strong></td><td>The OTP has exceeded the time allowed for its use</td></tr><tr><td><strong>OTP_WAIT_BEFORE_RESNED</strong></td><td>Please wait a while before requesting an OTP resend again</td></tr><tr><td><strong>INVALID_MERCHANT_CATEGORY</strong></td><td>Merchant category configuration is missing</td></tr><tr><td><strong>UNAUTHORIZED_MERCHANT_ACCOUNT</strong></td><td>Unauthorized merchant account</td></tr><tr><td><strong>NOT_ALLOWED_AMOUNT</strong></td><td>Transaction amount is not allowed</td></tr><tr><td><strong>INSUFFICIENT_BALANCE</strong></td><td>Insufficient balance for the transaction</td></tr><tr><td><strong>PHONE_NUMBER_IS_LOCKED</strong></td><td>Phone number is locked</td></tr><tr><td><strong>EXCEED_MONTHLY_AMOUNT</strong></td><td>The customer has exceeded the allowed monthly amount</td></tr><tr><td><strong>SERVICE_NOT_AVAILABLE</strong></td><td>Sadad payment service is not available, Please contact Sadad to ensure that the service is activated</td></tr><tr><td><strong>ALLOWED_ATTEMPTS_EXCEEDED</strong></td><td>You have exceeded the number of allowed transaction attempts</td></tr><tr><td><strong>INVALID_CREDENTIALS</strong></td><td>Invalid Sadad credentials</td></tr><tr><td><strong>UNKNOWN</strong></td><td>Unknown error, related to the service provider</td></tr></tbody></table>

### Adfali Errors

The following errors, as well as [General Errors](#general-errors), can be returned.

<table data-view="cards"><thead><tr><th>Error Code</th><th>Description</th></tr></thead><tbody><tr><td><strong>NOT_SUBSCRIBED</strong></td><td>The mobile number is not subscribed to Adfali service</td></tr><tr><td><strong>INVALID_AMOUNT</strong></td><td>Invalid amount</td></tr><tr><td><strong>INVALID_PROCESS_ID</strong></td><td>The process ID is invalid or does not match the value received in the (<strong><code>verify)</code></strong> request (lifetime 10 minutes)</td></tr><tr><td><strong>CONFIRMATION_ERROR</strong></td><td>Payment confirmation error, check OTP code</td></tr><tr><td><strong>INVALID_MOBILE_NUMBER</strong></td><td>Incorrect mobile number</td></tr><tr><td><strong>CHECK_BANK_ACCOUNT</strong></td><td>There is a problem with your account, please check with your bank account</td></tr><tr><td><strong>ADD_PAYMENT_ERROR</strong></td><td>payment error, unable to reach server or problem connecting to server</td></tr><tr><td><strong>BACKEND_SERVER_ERROR</strong></td><td>There is a problem connecting to the bank server, please try again later</td></tr><tr><td><strong>AUTH_ERROR</strong></td><td>Unable to reach the Adfali server right now</td></tr><tr><td><strong>INVALID_CREDENTIALS</strong></td><td>Invalid Adfali credentials</td></tr></tbody></table>

### Local Bank Cards&#x20;

There are no errors for Local Bank Cards, Only the [General Errors](#general-errors) can be returned

#### Lightbox Errors

On the checkout page (Lightbox), service providers may return error messages that are not specific to Plutu API. Here is an explanation for those error messages.

<table data-view="cards"><thead><tr><th>Error Message</th><th>Description</th></tr></thead><tbody><tr><td><strong>Order Not Found!</strong></td><td>General error but the credentials may be incorrect for use in a production environment</td></tr><tr><td><strong>Invalid Domain Request !</strong></td><td>The domain URL associated with your account by the bank is incorrect. The URL must be <strong>https://api.plutus.ly</strong></td></tr><tr><td><strong>Merchant or terminal is currently inactive</strong></td><td>Your account has not been activated or has been suspended by the bank or service provider</td></tr></tbody></table>

### T-Lync Errors

There are no errors for T-Lync, Only the [General Errors](#general-errors) can be returned

### MPGS Errors

The following errors, as well as [General Errors](#general-errors), can be returned.

<table data-card-size="large" data-view="cards"><thead><tr><th>Error Message</th><th>Description</th></tr></thead><tbody><tr><td><strong>CURRENCY_NOT_SUPPORTED</strong></td><td><p>Transaction currency is not supported by the merchant account. </p><p><em>You need to check your MPGS account that supports the selected currency</em></p></td></tr><tr><td><strong>INACTIVE_API</strong></td><td>MPGS account is not enabled for purchase. You need to contact your service provider to enable the 'PURCHASE' operation</td></tr></tbody></table>


# Testing

Simulate payments to test your integration with Plutu.

Before accepting live payments, we highly recommend testing your integration to ensure that it works correctly. Our test mode allows you to simulate payments and test the functionality of your integration without making any actual transactions.

To simulate a payment, you can use special test values provided by our platform. This will allow you to confirm that your integration is working as expected before going live. Please note that test payments are only valid on our test platform.

### How to use test mode?

From your account go to **Configuration** > **API Keys & Tokens** > **Access token**, you must generate the **Test Mode** access token.&#x20;

{% hint style="info" %}
You can use test mode even if your account has not yet been activated.
{% endhint %}

{% hint style="warning" %}
Rate limits

If you are testing your requests in the sandbox environment and begin to receive **429** HTTP errors, it is recommended to decrease the frequency of your requests. These errors may occur due to our rate limiter being stricter in test mode compared to production mode.
{% endhint %}

{% hint style="warning" %}
Transaction limits

Please note that there is a transaction limit per x hours in the sandbox environment to prevent misuse and ensure system stability. This limit restricts the number of transactions that can be processed within a specific time frame. Exceeding this limit may result in rejected transactions. It is important to keep track of the transaction volume and ensure it stays within the allowed limits.
{% endhint %}

{% hint style="info" %}
All mobile numbers used in the **Testing** documentation are owned by [Plutu](https://plutu.ly)
{% endhint %}

### Adfali Test

**Success**

<table><thead><tr><th width="249.46769366219854">Mobile number</th><th width="150">OTP</th><th>Status</th><th data-hidden></th></tr></thead><tbody><tr><td>0913632323</td><td>1111</td><td>Success</td><td></td></tr></tbody></table>

&#x20;**Errors**

<table><thead><tr><th width="244.66666666666663">Mobile number</th><th width="150">OTP</th><th>Error code</th><th data-hidden></th></tr></thead><tbody><tr><td>0913632323</td><td>Any OTP</td><td>CONFIRMATION_ERROR</td><td></td></tr><tr><td>0923632323</td><td>Any OTP</td><td>CHECK_BANK_ACCOUNT</td><td></td></tr><tr><td>Any mobile number</td><td>Any OTP</td><td>NOT_SUBSCRIBED</td><td></td></tr></tbody></table>

You can review the [Errors](/api-documentation/errors#adfali-errors) section for all possible errors

### Sadad Test

**Success**

<table><thead><tr><th width="202.2850551201142">Mobile number</th><th width="150">Birth year</th><th width="150">Code</th><th>Status</th></tr></thead><tbody><tr><td>0913632323</td><td>Any</td><td>111111</td><td>Success</td></tr></tbody></table>

&#x20;**Errors**

<table><thead><tr><th width="195">Mobile number</th><th width="150">Birth year</th><th width="150">Code</th><th>Error code</th></tr></thead><tbody><tr><td>0913632323</td><td>Any</td><td>888888</td><td>OTP_EXPIRED</td></tr><tr><td>0913632323</td><td>Any</td><td>999999</td><td>NOT_ALLOWED_AMOUNT</td></tr><tr><td>0913632323</td><td>Any</td><td>Any OTP</td><td>INVLIAD_OTP</td></tr><tr><td>Any mobile number</td><td>Any</td><td>Any OTP</td><td>INVALID_MOBILE_NUMBER_OR_BIRTH_YEAR</td></tr></tbody></table>

You can review the [Errors](/api-documentation/errors#sadad-errors) section for all possible errors

### Local Bank Card Test

Prior to accepting live payments through the Local Bank Card service provider, we advise you to test your integration to ensure that it functions properly. Our test platform simulates payment transactions for testing purposes only and does not involve the actual transfer of funds.

{% hint style="success" %}
To test a successful transaction, click **Pay Now** on the checkout page and the transaction will complete after which you will be redirected back to the return URL.
{% endhint %}

{% hint style="danger" %}
To test the cancellation status, after clicking **Cancel**, the transaction will be canceled and then redirected back to the return URL.
{% endhint %}

### T-Lync Test

When integrating with T-Lync for accepting payments, we recommend testing your integration using our test mode. This will allow you to simulate payment transactions without involving the T-Lync service. Test payments are only valid for testing purposes and do not involve any real transactions.

{% hint style="success" %}
To test a successful transaction, select the payment method and click **Pay Now** on the checkout page, the transaction will complete after which you will be redirected back to the return URL.
{% endhint %}

### MPGS Test

We recommend testing your MPGS integration through Plutu before accepting live payments to ensure it is working correctly. You can use our test platform to simulate payment transactions, but please note that test payments are not valid for actual transactions.

{% hint style="success" %}
To simulate a successful transaction, click the **Pay Now** button on the checkout page. The transaction will be processed and you will be redirected to the return URL once it is completed.
{% endhint %}

{% hint style="danger" %}
To test the cancellation status, click the **Cancel** button during the checkout process. The transaction will then be canceled and you will be redirected back to the return URL.
{% endhint %}


# Plutu PHP

Plutu PHP package provides a streamlined integration of Plutu's services into PHP projects. It offers a generic interface that enables easy interaction with the Plutu API and services.

{% hint style="info" %}
**For more comprehensive information and detailed documentation about Plutu PHP, please visit the** [**Plutu PHP**](https://github.com/getplutu/plutu-php) **Github repository. The repository includes a README file with installation instructions, usage, and examples.**
{% endhint %}

## Getting started

Before you can use the Plutu PHP package, you need to have a Plutu API key, access token, and secret key. You can obtain these from your [Plutu](https://plutu.ly/) account dashboard.

### Requirements

* PHP version 8.1 or higher

### Installation

You can install the Plutu PHP package via Composer by running the following command:

```php
composer require plutu/plutu-php
```

### Usage

To use the Plutu PHP package in your project, you first need to include the Composer autoload file:

```php
require_once __DIR__ . '/vendor/autoload.php';
```

### Examples

The Plutu PHP package includes several examples that demonstrate how to use the package to interact with the Plutu API. These examples cover a variety of use cases for Plutu's services and can be found in the [Examples](https://github.com/getplutu/plutu-php/blob/main/examples.md) document on GitHub


# Plutu Laravel

Plutu Laravel is the official package that builds upon the Plutu PHP package to simplify the integration of Plutu services into Laravel applications.

{% hint style="info" %}
**To access detailed documentation and comprehensive information about Plutu Laravel, please refer to the** [**Plutu Laravel**](https://github.com/getplutu/plutu-laravel) **Github repository.**
{% endhint %}

## Getting started

### Requirements

* PHP version 8.0 or higher
* Laravel version 9 or higher"

### Installation

You can install the Plutu Laravel package via Composer by running the following command:

```php
composer require plutu/plutu-laravel
```

### Publish Configuration

To publish the configuration file of Plutu Laravel package, run the following command:

```php
php artisan vendor:publish --provider="PlutuLaravel\Providers\PlutuServiceProvider"
```

This command will publish the `plutu.php` configuration file to the config directory of your application.

You can then configure the package by setting the following environment variables in your `.env` file:

```php
PLUTU_API_KEY=your_api_key
PLUTU_ACCESS_TOKEN=your_access_token
PLUTU_SECRET_KEY=your_secret_key
```

Make sure to replace your\_api\_key, your\_access\_token, and your\_secret\_key with your own API credentials provided by [Plutu](https://plutu.ly/) in your merchant account.

Alternatively, you can directly edit the config/plutu.php configuration file that was published to your application.

### Examples

{% hint style="info" %}
You can find examples in the package's main documentation here: [Plutu PHP](https://github.com/getplutu/plutu-php/blob/main/examples.md)
{% endhint %}


