NAV

Introduction

Welcome to the Fena PHP Payment SDK guide. Before we dive into integration, let us explain how this system works.

How Fena online payments works

The Fena Online Payment system consists of three main parts

  1. A webpage that initiates a request to Fena to make a payment.
  2. A page on your webserver that Fena to notify you when a payment has been made.
  3. A webpage that confirms the above payment and passes the customer on to the next phase of your application, such as your ‘order confirmation’ or 'Thank You' page.

Parts 1 and 3 can be accessed by customers on your website/app. Part 2 is only visible to Fena. This diagram illustrates the interaction between your customer, Fena and your application.

Installation

Fena PHP Payment SDK can be installed via Composer.

Run the following command in your terminal:

composer require faizpay/php-payment-sdk

To use the sdk, use Composer's autoload:

require_once('vendor/autoload.php');

Quick Start

Before we start, make sure you have Fena SDK installed. To install SDK please check our installation section

Create a Token and Redirect to Fena

Create a connection object

use FaizPay\PaymentSDK\Connection;
use FaizPay\PaymentSDK\Payment;

$connection = Connection::createConnection(
    $terminalId = '8afa74ae-6ef9-48bb-93b2-9fe8be53db50',
    $terminalSecret = '55d7d5ed-be22-4321-bb3f-aec8524d8be2'
);

Make sure to use your own $terminalId and $terminalSecret values.

Create the payment object

$payment = Payment::createPayment(
    $connection,
    $orderId = 'AA-11',
    $amount = '10.00'
);

Make sure to set the orderID to your internal order ID (for tracking).

Then finally call the process on the payment object. This will redirect the browser to the Fena system.

$payment->process();

You can also pass false to process function this will return the url as string.

Setup Webhook / Notification Endpoint

  1. Create a connection object
  2. Create a NotificationHandler object
  3. Get your Order ID from token
  4. Fetch the order detail from database
  5. Validate requested payment matches with Token
  6. Update your database with payment completed
use FaizPay\PaymentSDK\Connection;
use FaizPay\PaymentSDK\NotificationHandler;

$connection = Connection::createConnection($terminalId, $terminalSecret);

Make sure to use your own $terminalId and $terminalSecret values.

$notificationHandler = NotificationHandler::createNotificationHandler(
    $connection,
    $token = $_POST['token']
);

Fena post the token in "token" variable to the webhook endpoint

// get the order id
$orderId = $notificationHandler->getOrderID();

// fetch the order from your database
$data = findFromDatabase($orderId);

// if order is not found in system
if (checkIfEntryFound($data)) {
    echo "Invalid Token";
    die();
}

// validate if the requested payment matches with token
if (!$notificationHandler->validateAmount($data['amount'])) {
    echo "Invalid Token";
    die();
}

// all checks are passed - update the database to mark payment complete
updateDatabase($orderId, ['completed' => true]);

Setup Redirect Page

User will be redirected back to yours redirect endpoint with yours Order ID in query as "order" And Payment Status in query as "status" as query parameter.

You can read more about the Redirect page in our Redirect Handling section.

Connection

Our SDK uses connection objects for most requests. To create a new connection object call a static method of FaizPay\PaymentSDK\Connection::createConnection.

use FaizPay\PaymentSDK\Connection;

$connection = Connection::createConnection(
    $terminalId = '8afa74ae-6ef9-48bb-93b2-9fe8be53db50',
    $terminalSecret = '55d7d5ed-be22-4321-bb3f-aec8524d8be2'
);

Make sure to use your own $terminalId and $terminalSecret values.

Input Arguments

Argument Required Description
Terminal Id Yes Terminal ID of terminal. Must be UUID 4.
Terminal Secret Yes Terminal Secret of terminal. Must be UUID 4.

If valid, arguments are given object of FaizPay\PaymentSDK\Connection will be returned. Otherwise, Object of FaizPay\PaymentSDK\Error will be returned.

Return Object

Operation Class Object
Success FaizPay\PaymentSDK\Connection
Error FaizPay\PaymentSDK\Error Code 1
Error FaizPay\PaymentSDK\Error Code 2

Payment

To create a new payment call a static method of FaizPay\PaymentSDK\Payment::createPayment.

use FaizPay\PaymentSDK\Payment;
$payment = Payment::createPayment(
    $connection,
    $orderId = 'AA-11',
    $amount = '10.00'
);

Make sure your orderId is unique. If the payment for the given orderId has completed before for your terminal user will be redirected to your redirect endpoint without executing the payment. This is designed to avoid any duplicated payments.

Input Arguments

Argument Required Description
Connection Yes Connection object.
Order Id Yes Your Order ID. Must not be empty and cannot be more than 255 characters.
Amount Yes Amount requested must be in 2 decimal places, string and greater than 0.00.

If valid, arguments are given object of FaizPay\PaymentSDK\Payment will be returned. Otherwise, Object of FaizPay\PaymentSDK\Error will be returned.

Return Object

Operation Class Object
Success FaizPay\PaymentSDK\Payment
Error FaizPay\PaymentSDK\Error Code 3
Error FaizPay\PaymentSDK\Error Code 4
Error FaizPay\PaymentSDK\Error Code 5
Error FaizPay\PaymentSDK\Error Code 6

Payment Process

To process payment call Process on the Payment object. You can also pass false to process function this will return the url as string.

$payment->process();

Input Arguments

Argument Required Description
Browser redirect No If set to yes browser will be redirected using header method location method. If set to no a url will be returned.

Provider

If you want to predefine the account provider or force the customer to pay from a certain account you can use the Provider object. To Create a new Provider call a static method of FaizPay\PaymentSDK\Provider::createProvider and then call setProvider on payment object with provider object as argument.

use FaizPay\PaymentSDK\Provider;
$provider = Provider::createProvider(
    $providerId = 'ob-lloyds-personal',
    $sortCode = '123456',
    $accountNumber = '12345678'
);

$payment->setProvider($provider);

Full list of supported provider ids can be found using this endpoint https://app.fena.co/api/providers

Input Arguments

Argument Required Description
Provider ID Yes Must be a value of provider given by Fena.
Sort Code *No Must be 6 digits and numeric. Cannot empty if Account Number is given.
Account Number *No Must be 8 digits and numeric. Cannot empty if Sort Code is given.

If valid, arguments are given object of FaizPay\PaymentSDK\Provider will be returned. Otherwise, Object of FaizPay\PaymentSDK\Error will be returned.

Return Object

Operation Class Object
Success FaizPay\PaymentSDK\Provider
Error FaizPay\PaymentSDK\Error Code 7
Error FaizPay\PaymentSDK\Error Code 8
Error FaizPay\PaymentSDK\Error Code 9
Error FaizPay\PaymentSDK\Error Code 10

User

If you want to send the customers details to Fena. You can set customer detail using User object. To Create a new User call a static method of FaizPay\PaymentSDK\User::createUser and then call setUser on payment object with user object as argument.

use FaizPay\PaymentSDK\User;
$user = User::createUser(
    $email = 'john.doe@test.com',
    $firstName = 'John',
    $lastName = 'Doe',
    $contactNumber = '07000845953'
);

$payment->setUser($user);

Input Arguments

Argument Required Description
Email No Must be valid email. Can be null. Must not be more than 255 characters.
First Name No Can be null. Must not be more than 255 characters.
Last Name No Can be null. Must not be more than 255 characters.

If valid, arguments are given object of FaizPay\PaymentSDK\User will be returned. Otherwise, Object of FaizPay\PaymentSDK\Error will be returned.

Return Object

Operation Class Object
Success FaizPay\PaymentSDK\User
Error FaizPay\PaymentSDK\Error Code 12
Error FaizPay\PaymentSDK\Error Code 13
Error FaizPay\PaymentSDK\Error Code 14
Error FaizPay\PaymentSDK\Error Code 15

Notification Handling

Fena calls the webhook or notification endpoint with post request of encoded as "application/x-www-form-urlencoded" with token in key called "token".

Fena will only make a notification request if the payment is successful.

Only one request will be made per your unique order id. This is to prevent any duplicated payments.

To handle the webhook or notification of payment call a static method of FaizPay\PaymentSDK\NotificationHandler::createNotificationHandler.

use FaizPay\PaymentSDK\NotificationHandler;
$notificationHandler = NotificationHandler::createNotificationHandler(
                        $connection, $token = $_POST['token']
);

Input Arguments

Argument Required Description
Connection Yes Connection object.
token Yes Token sent by Fena. Fena post token with key of "token". Usually it can be accessed via $_POST['token'].

If valid, arguments are given object of FaizPay\PaymentSDK\NotificationHandler will be returned. Otherwise, Object of FaizPay\PaymentSDK\Error will be returned.

Return Object

Operation Class Object
Success FaizPay\PaymentSDK\NotificationHandler
Error FaizPay\PaymentSDK\Error Code 16
Error FaizPay\PaymentSDK\Error Code 17
Error FaizPay\PaymentSDK\Error Code 18

NotificationHandler Functions

Once the NotificationHandler objected is created you can call the following functions.

Operation Argument Class Object
getOrderID get the order id set in the payment object
getRequestedAmount get the requested amount
getNetAmount get the net amount paid
getId get the Fena transaction id
validateAmount amountRequested return true or false by validating amount requested in token matches your amountRequested in database

We recommend amount should be validated using "validateAmount" to make sure user has paid the requested amount.

Redirect Handling

On payment completion, or rejection, the user will be redirected to the "Redirect Endpoint" configured in terminal setting along with two query parameters:

Yours Order ID as "order"

Payment Status as "status"

Example:

https://www.test.com/thankyou?order=aa-bb-cc&status=executed

Status Description

Status Description
executed Payment has been successfully processed
rejected Payment has been rejected by the account provider

Errors

Any errors in SDK are handled via the FaizPay\PaymentSDK\Error object.

$error->getCode();
$error->getMessage();

error object has 2 methods

The PHP SDK uses the following error codes:

Error Code Meaning
1 Invalid Terminal ID - Should be valid UUID4
2 Invalid Terminal Secret - Should be valid UUID4
3 Order ID cannot be empty
4 Amount cannot be empty or less than 0.01
5 Number must be 2 decimal places
6 Order ID cannot be greater than 255 characters
7 Invalid Sort Code
8 Invalid Account Number
9 Provider ID must be set to set sort code and account number
10 Sort Code and account both must be set
11 Invalid email is given
12 First name need to be less than 255
13 Last name need to be less than 255
14 Contact Number need to be less than 255
15 Email need to be less than 255
16 Unable to decode the token - Invalid / Expire token given
17 Token content missing data
18 Token terminal mismatch