Sample Code

Shipping

Overview

In this section, we provide sample codes for:


Get Shipping Countries

<?php

/* ------------------------ Configurations ---------------------------------- */
//Test
$apiURL = 'https://apitest.myfatoorah.com';
$apiKey = ''; //Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

//Live
//$apiURL = 'https://api.myfatoorah.com';
//$apiKey = ''; //Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token


/* ------------------------ Call GetCountries Endpoint ---------------------- */
$json = callAPI("$apiURL/v2/GetCountries", $apiKey, [], 'GET');

//Display the result
echo "<pre>";
print_r($json->Data);


/* ------------------------ Functions --------------------------------------- */
/*
 * Call API Endpoint Function
 */

function callAPI($endpointURL, $apiKey, $postFields = [], $requestType = 'POST') {

    $curl = curl_init($endpointURL);
    curl_setopt_array($curl, array(
        CURLOPT_CUSTOMREQUEST  => $requestType,
        CURLOPT_POSTFIELDS     => json_encode($postFields),
        CURLOPT_HTTPHEADER     => array("Authorization: Bearer $apiKey", 'Content-Type: application/json'),
        CURLOPT_RETURNTRANSFER => true,
    ));

    $response = curl_exec($curl);
    $curlErr  = curl_error($curl);

    curl_close($curl);

    if ($curlErr) {
        //Curl is not working in your server
        die("Curl Error: $curlErr");
    }

    $error = handleError($response);
    if ($error) {
        die("Error: $error");
    }

    return json_decode($response);
}

//------------------------------------------------------------------------------
/*
 * Handle Endpoint Errors Function 
 */

function handleError($response) {

    $json = json_decode($response);
    if (isset($json->IsSuccess) && $json->IsSuccess == true) {
        return null;
    }

    //Check for the errors
    if (isset($json->ValidationErrors) || isset($json->FieldsErrors)) {
        $errorsObj = isset($json->ValidationErrors) ? $json->ValidationErrors : $json->FieldsErrors;
        $blogDatas = array_column($errorsObj, 'Error', 'Name');

        $error = implode(', ', array_map(function ($k, $v) {
                    return "$k: $v";
                }, array_keys($blogDatas), array_values($blogDatas)));
    } else if (isset($json->Data->ErrorMessage)) {
        $error = $json->Data->ErrorMessage;
    }

    if (empty($error)) {
        $error = (isset($json->Message)) ? $json->Message : (!empty($response) ? $response : 'API key or API URL is not correct');
    }

    return $error;
}

/* -------------------------------------------------------------------------- */
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace ShippingCountries
{
    class Program
    {
        // You can get test token from this page  https://myfatoorah.readme.io/docs/test-token
        static string token = "";
        static string baseURL = "https://apitest.myfatoorah.com";
        static async Task Main(string[] args)
        {
            var getShippingCountriesResponse = await GetShippingCountries().ConfigureAwait(false);
            Console.WriteLine("Get Shipping Countries Response :");
            Console.WriteLine(getShippingCountriesResponse);
            Console.ReadLine();
        }
        public static async Task<string> GetShippingCountries()
        {
            string url = baseURL + $"/v2/GetCountries";

            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            var responseMessage = await client.GetAsync(url).ConfigureAwait(false);
            string response = string.Empty;
            if (!responseMessage.IsSuccessStatusCode)
            {
                response = JsonConvert.SerializeObject(new
                {
                    IsSuccess = false,
                    Message = responseMessage.StatusCode.ToString()
                });
            }
            else
            {
                response = await responseMessage.Content.ReadAsStringAsync();
            }

            return response;
        }


    }
}
# Get Countries API

# Import required libraries (make sure it is installed!)
import requests
import json
import sys

# Define Functions

def check_data(key, response_data):
    if key in response_data.keys() and response_data[key] is not None:
        return True
    else:
        return False


# Error Handle Function
def handle_response(response):
    if response.text == "":  # In case of empty response
        raise Exception("API key is not correct")

    response_data = response.json()
    response_keys = response_data.keys()

    if "IsSuccess" in response_keys and response_data["IsSuccess"] is True:
        return  # Successful
    elif check_data("ValidationErrors", response_data):
        error = []
        for i in range(len(response.json()["ValidationErrors"])):
            v_error = [response_data["ValidationErrors"][i].get(key) for key in ["Name", "Error"]]
            error.append(v_error)
    elif check_data("ErrorMessage", response_data):
        error = response_data["ErrorMessage"]
    elif check_data("Message", response_data):
        error = response_data["Message"]
    elif check_data("Data", response_data):
        error = response_data["Data"]["ErrorMessage"]
    elif check_data("ErrorMessage", response_data["Data"]):
        error = response_data["Data"]["ErrorMessage"]
    else:
        error = "An Error has occurred. API response: " + response.text
    raise Exception(error)


# Call API Function
def call_api(api_url, api_key, request_data, request_type="POST"):
    request_data = json.dumps(request_data)
    headers = {"Content-Type": "application/json", "Authorization": "Bearer " + api_key}
    response = requests.request(request_type, api_url, data=request_data, headers=headers)
    handle_response(response)
    return response



def get_countries():
    api_url = base_url + "/v2/GetCountries"
    countries_response = call_api(api_url, api_key, None, request_type = "GET").json()
    countries = countries_response["Data"]
    print(countries)
    return countries


# Test Environment
base_url = "https://apitest.myfatoorah.com"
api_key = "MyTokenValue"  # Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

# Live Environment
# base_url = "https://api.myfatoorah.com"
# api_key = "mytokenvalue" #Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token


try:
    get_countries()

    countries_list = [el["CountryName"] for el in get_countries()]
    print(countries_list)
except:
    ex_type, ex_value, ex_traceback = sys.exc_info()
    print("Exception type : %s " % ex_type.__name__)
    print("Exception message : %s" % ex_value)

Get Shipping Cities

<?php

/* ------------------------ Configurations ---------------------------------- */
//Test
$apiURL = 'https://apitest.myfatoorah.com';
$apiKey = ''; //Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

//Live
//$apiURL = 'https://api.myfatoorah.com';
//$apiKey = ''; //Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token


/* ------------------------ Call GetCities Endpoint ------------------------- */
//For DHL Shiping
$shipingMethod = 1;

//For Aramex Shiping
/* $shipingMethod = 2; */

$countryCode  = 'KW';

//optional
//$searchValue  = 'Ku'; 

$filterParams = "?shippingMethod=$shipingMethod&countryCode=$countryCode&searchValue=$searchValue";
$json         = callAPI("$apiURL/v2/GetCities$filterParams", $apiKey, [], 'GET');

//Display the result
echo "<pre>";
print_r($json->Data);


/* ------------------------ Functions --------------------------------------- */
/*
 * Call API Endpoint Function
 */

function callAPI($endpointURL, $apiKey, $postFields = [], $requestType = 'POST') {

    $curl = curl_init($endpointURL);
    curl_setopt_array($curl, array(
        CURLOPT_CUSTOMREQUEST  => $requestType,
        CURLOPT_POSTFIELDS     => json_encode($postFields),
        CURLOPT_HTTPHEADER     => array("Authorization: Bearer $apiKey", 'Content-Type: application/json'),
        CURLOPT_RETURNTRANSFER => true,
    ));

    $response = curl_exec($curl);
    $curlErr  = curl_error($curl);

    curl_close($curl);

    if ($curlErr) {
        //Curl is not working in your server
        die("Curl Error: $curlErr");
    }

    $error = handleError($response);
    if ($error) {
        die("Error: $error");
    }

    return json_decode($response);
}

//------------------------------------------------------------------------------
/*
 * Handle Endpoint Errors Function 
 */

function handleError($response) {

    $json = json_decode($response);
    if (isset($json->IsSuccess) && $json->IsSuccess == true) {
        return null;
    }

    //Check for the errors
    if (isset($json->ValidationErrors) || isset($json->FieldsErrors)) {
        $errorsObj = isset($json->ValidationErrors) ? $json->ValidationErrors : $json->FieldsErrors;
        $blogDatas = array_column($errorsObj, 'Error', 'Name');

        $error = implode(', ', array_map(function ($k, $v) {
                    return "$k: $v";
                }, array_keys($blogDatas), array_values($blogDatas)));
    } else if (isset($json->Data->ErrorMessage)) {
        $error = $json->Data->ErrorMessage;
    }

    if (empty($error)) {
        $error = (isset($json->Message)) ? $json->Message : (!empty($response) ? $response : 'API key or API URL is not correct');
    }

    return $error;
}

/* -------------------------------------------------------------------------- */
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace ShippingCities
{
    class Program
    {
        // You can get test token from this page  https://myfatoorah.readme.io/docs/test-token
        static string token = "";
        static string baseURL = "https://apitest.myfatoorah.com";
        static async Task Main(string[] args)
        {
            var getShippingCitiesResponse = await GetShippingCities().ConfigureAwait(false);
            Console.WriteLine("Get Shipping cities Response :");
            Console.WriteLine(getShippingCitiesResponse);
            Console.ReadLine();
        }
        public static async Task<string> GetShippingCities()
        {
            string shippingMethod = "1";
            string countryCode = "kw";
            string searchValue = "";
            string url = baseURL + $"/v2/GetCities?shippingMethod={shippingMethod}&countryCode={countryCode}&searchValue={searchValue}";

            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            var responseMessage = await client.GetAsync(url).ConfigureAwait(false);
            string response = string.Empty;
            if (!responseMessage.IsSuccessStatusCode)
            {
                response = JsonConvert.SerializeObject(new
                {
                    IsSuccess = false,
                    Message = responseMessage.StatusCode.ToString()
                });
            }
            else
            {
                response = await responseMessage.Content.ReadAsStringAsync();
            }

            return response;
        }

    
    }
}
# Get Cities API

# Import required libraries (make sure it is installed!)
import requests
import json
import sys
# Define Functions

def check_data(key, response_data):
    if key in response_data.keys() and response_data[key] is not None:
        return True
    else:
        return False


# Error Handle Function
def handle_response(response):
    if response.text == "":  # In case of empty response
        raise Exception("API key is not correct")

    response_data = response.json()
    response_keys = response_data.keys()

    if "IsSuccess" in response_keys and response_data["IsSuccess"] is True:
        return  # Successful
    elif check_data("ValidationErrors", response_data):
        error = []
        for i in range(len(response.json()["ValidationErrors"])):
            v_error = [response_data["ValidationErrors"][i].get(key) for key in ["Name", "Error"]]
            error.append(v_error)
    elif check_data("ErrorMessage", response_data):
        error = response_data["ErrorMessage"]
    elif check_data("Message", response_data):
        error = response_data["Message"]
    elif check_data("Data", response_data):
        error = response_data["Data"]["ErrorMessage"]
    elif check_data("ErrorMessage", response_data["Data"]):
        error = response_data["Data"]["ErrorMessage"]
    else:
        error = "An Error has occurred. API response: " + response.text
    raise Exception(error)


# Call API Function
def call_api(api_url, api_key, request_data, request_type="POST"):
    request_data = json.dumps(request_data)
    headers = {"Content-Type": "application/json", "Authorization": "Bearer " + api_key}
    response = requests.request(request_type, api_url, data=request_data, headers=headers)
    handle_response(response)
    return response



def get_countries():
    api_url = base_url + "/v2/GetCountries"
    countries_response = call_api(api_url, api_key, None, request_type = "GET").json()
    countries = countries_response["Data"]
    return countries


def get_cities(country_code, search_value):
    while True:
        api_url = base_url + "/v2/Getcities?shippingMethod=1&countryCode=" + country_code + "&searchValue=" + search_value
        cities_response = call_api(api_url, api_key, None, request_type = "GET").json()
        cities = cities_response["Data"]["CityNames"]
        if cities != []:
            break
        else:
            search_value = str(input("Try Another Search Value: ")).upper()
    print(cities)
    return cities

# Test Environment
base_url = "https://apitest.myfatoorah.com"
api_key = "MyTokenValue"  # Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

# Live Environment
# base_url = "https://api.myfatoorah.com"
# api_key = "mytokenvalue" #Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token

try:
    countries = get_countries()
    countries_list = [el["CountryName"] for el in countries]
    print(countries_list)

    while True:
        x = str(input("Enter a country name from the list: ")).upper()
        if x in countries_list:
            break
        else:
            print("Enter a value from the lis")

    country_code = [el for el in countries if el["CountryName"] == x][0]["CountryCode"]

    search_value = str(input("Enter your search value for cities (Click enter for all cities): "))

    cities = get_cities(country_code, search_value)

    while True:
        y = str(input("Enter you city value from the list (All CAPITAL letters):"))
        if y in cities:
            break
        else:
            print("Select a correct city!")

    city_value = y

    print(city_value)
except:
    ex_type, ex_value, ex_traceback = sys.exc_info()
    print("Exception type : %s " % ex_type.__name__)
    print("Exception message : %s" % ex_value)

Calculate Shipping Charge

<?php

/* ------------------------ Configurations ---------------------------------- */
//Test
$apiURL = 'https://apitest.myfatoorah.com';
$apiKey = ''; //Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

//Live
//$apiURL = 'https://api.myfatoorah.com';
//$apiKey = ''; //Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token


/* ------------------------ Call CalculateShippingCharge Endpoint ----------- */
//For DHL Shiping
$shipingMethod = 1;

//For Aramex Shiping
/* $shipingMethod = 2; */

//Fill POST fields array
$postFields = [
    'ShippingMethod' => $shipingMethod,
    'Items'          => [
        [
            'ProductName' => 'Product Name (In English)', //ISBAN, or SKU
            'Description' => 'Description (In English)',
            'Quantity'    => 2, //Item's quantity
            'UnitPrice'   => 25, //Price per item
            'Weight'      => 0.250, //Weight must be in kg.
            'Width'       => 11.4, //It must be in cm.
            'Height'      => 2.6, //It must be in cm.
            'Depth'       => 3.2, //It must be in cm.
        ]
    ],
    'CityName'       => 'DUBAI',
    'PostalCode'     => '12345',
    'CountryCode'    => 'AE'
];

//Call endpoint
$json = callAPI("$apiURL/v2/CalculateShippingCharge", $apiKey, $postFields);

//Display the result
echo 'Shipping Charge= ' . $json->Data->Fees . ' ' . $json->Data->Currency;


/* ------------------------ Functions --------------------------------------- */
/*
 * Call API Endpoint Function
 */

function callAPI($endpointURL, $apiKey, $postFields = [], $requestType = 'POST') {

    $curl = curl_init($endpointURL);
    curl_setopt_array($curl, array(
        CURLOPT_CUSTOMREQUEST  => $requestType,
        CURLOPT_POSTFIELDS     => json_encode($postFields),
        CURLOPT_HTTPHEADER     => array("Authorization: Bearer $apiKey", 'Content-Type: application/json'),
        CURLOPT_RETURNTRANSFER => true,
    ));

    $response = curl_exec($curl);
    $curlErr  = curl_error($curl);

    curl_close($curl);

    if ($curlErr) {
        //Curl is not working in your server
        die("Curl Error: $curlErr");
    }

    $error = handleError($response);
    if ($error) {
        die("Error: $error");
    }

    return json_decode($response);
}

//------------------------------------------------------------------------------
/*
 * Handle Endpoint Errors Function 
 */

function handleError($response) {

    $json = json_decode($response);
    if (isset($json->IsSuccess) && $json->IsSuccess == true) {
        return null;
    }

    //Check for the errors
    if (isset($json->ValidationErrors) || isset($json->FieldsErrors)) {
        $errorsObj = isset($json->ValidationErrors) ? $json->ValidationErrors : $json->FieldsErrors;
        $blogDatas = array_column($errorsObj, 'Error', 'Name');

        $error = implode(', ', array_map(function ($k, $v) {
                    return "$k: $v";
                }, array_keys($blogDatas), array_values($blogDatas)));
    } else if (isset($json->Data->ErrorMessage)) {
        $error = $json->Data->ErrorMessage;
    }

    if (empty($error)) {
        $error = (isset($json->Message)) ? $json->Message : (!empty($response) ? $response : 'API key or API URL is not correct');
    }

    return $error;
}

/* -------------------------------------------------------------------------- */
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace CalculateShippingCharge
{
    class Program
    {
        // You can get test token from this page  https://myfatoorah.readme.io/docs/test-token
        static string token = "";
        static string baseURL = "https://apitest.myfatoorah.com";
        static async Task Main(string[] args)
        {

            var calculateResponse = await CalculateShippingCharge().ConfigureAwait(false);
            Console.WriteLine("Calculate Shipping Charge Response :");
            Console.WriteLine(calculateResponse);

            Console.ReadLine();
        }
        public static async Task<string> CalculateShippingCharge()
        {

            var calculateShippingRequest = new
            {
                ShippingMethod = 1,
                CityName = "DUBAI",
                PostalCode = "12345",
                CountryCode = "AE",
                Items = new[] {
                        new {
                          ProductName = "item1",Description="Product Desc", Quantity = 2, UnitPrice = 500, Weight = 1, Width = 1, Height = 1, Depth = 1
                        }
                 }

            };
            var executeRequestJSON = JsonConvert.SerializeObject(calculateShippingRequest);
            return await PerformRequest(executeRequestJSON, endPoint: "CalculateShippingCharge").ConfigureAwait(false);
        }
        public static async Task<string> PerformRequest(string requestJSON, string url = "", string endPoint = "")
        {
            if (string.IsNullOrEmpty(url))
                url = baseURL + $"/v2/{endPoint}";

            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            var httpContent = new StringContent(requestJSON, System.Text.Encoding.UTF8, "application/json");
            var responseMessage = await client.PostAsync(url, httpContent).ConfigureAwait(false);
            string response = string.Empty;
            if (!responseMessage.IsSuccessStatusCode)
            {
                response = JsonConvert.SerializeObject(new
                {
                    IsSuccess = false,
                    Message = responseMessage.StatusCode.ToString()
                });
            }
            else
            {
                response = await responseMessage.Content.ReadAsStringAsync();
            }

            return response;
        }
    }

}
# Calculate Shipping Charge API

# Import required libraries (make sure it is installed!)
import requests
import json
import sys

# Define Functions

def check_data(key, response_data):
    if key in response_data.keys() and response_data[key] is not None:
        return True
    else:
        return False


# Error Handle Function
def handle_response(response):
    if response.text == "":  # In case of empty response
        raise Exception("API key is not correct")

    response_data = response.json()
    response_keys = response_data.keys()

    if "IsSuccess" in response_keys and response_data["IsSuccess"] is True:
        return  # Successful
    elif check_data("ValidationErrors", response_data):
        error = []
        for i in range(len(response.json()["ValidationErrors"])):
            v_error = [response_data["ValidationErrors"][i].get(key) for key in ["Name", "Error"]]
            error.append(v_error)
    elif check_data("ErrorMessage", response_data):
        error = response_data["ErrorMessage"]
    elif check_data("Message", response_data):
        error = response_data["Message"]
    elif check_data("Data", response_data):
        error = response_data["Data"]["ErrorMessage"]
    elif check_data("ErrorMessage", response_data["Data"]):
        error = response_data["Data"]["ErrorMessage"]
    else:
        error = "An Error has occurred. API response: " + response.text
    raise Exception(error)


# Call API Function
def call_api(api_url, api_key, request_data, request_type="POST"):
    request_data = json.dumps(request_data)
    headers = {"Content-Type": "application/json", "Authorization": "Bearer " + api_key}
    response = requests.request(request_type, api_url, data=request_data, headers=headers)
    handle_response(response)
    return response


def calculate_shipping_charge(shipping_charge_request):
    api_url = base_url + "/v2/CalculateShippingCharge"
    shipping_charge_response = call_api(api_url, api_key, shipping_charge_request).json()
    shipping_charge = shipping_charge_response["Data"]
    print(shipping_charge)
    return shipping_charge


# Test Environment
base_url = "https://apitest.myfatoorah.com"
api_key = "MyTokenValue"  # Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

# Live Environment
# base_url = "https://api.myfatoorah.com"
# api_key = "mytokenvalue" #Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token


country_code = "EG"
city_value = "5TH SETTLEMENT"

shipping_charge_request = {
                      "ShippingMethod": 1, # 1 for DHL, 2 for Aramex
                      "Items": [
                                {
                                "ProductName": "name",
                                "Description": "name",
                                "Weight": 0.5,
                                "Width": 10,
                                "Height": 15,
                                "Depth": 19,
                                "Quantity": 20,
                                "UnitPrice": 5
                            }
                            ],
                      "CityName": city_value,
                      "PostalCode": "12345",
                      "CountryCode": country_code
                    }

try:
    calculate_shipping_charge(shipping_charge_request)
except:
    ex_type, ex_value, ex_traceback = sys.exc_info()
    print("Exception type : %s " % ex_type.__name__)
    print("Exception message : %s" % ex_value)

Create Invoice Link with Shipping

<?php

/* ------------------------ Configurations ---------------------------------- */
//Test
$apiURL = 'https://apitest.myfatoorah.com';
$apiKey = ''; //Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

//Live
//$apiURL = 'https://api.myfatoorah.com';
//$apiKey = ''; //Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token


/* ------------------------ Call SendPayment Endpoint ----------------------- */
//Fill customer address array
/* $customerAddress = array(
  'Block'               => 'Blk #', //optional
  'Street'              => 'Str', //optional
  'HouseBuildingNo'     => 'Bldng #', //optional
  'Address'             => 'Addr', //optional
  'AddressInstructions' => 'More Address Instructions', //optional
  ); */

//Fill invoice item array
$invoiceItems[] = [
    'ItemName'  => 'Item Name', //ISBAN, or SKU
    'Quantity'  => '2', //Item's quantity
    'UnitPrice' => '25', //Price per item
    'weight'    => 0.250, //Weight must be in kg.
    'Width'     => 11.4, //It must be in cm.
    'Height'    => 2.6, //It must be in cm.
    'Depth'     => 3.2, //It must be in cm.
];

//Shipping Consignee
$shippingConsignee = array(
    //Fill required data
    'PersonName'  => 'fname lname',
    'Mobile'      => '1234567890',
    'LineAddress' => 'Address',
    'CityName'    => 'DUBAI',
    'PostalCode'  => '12345',
    'CountryCode' => 'AE'
        //Fill optional data
        //'EmailAddress' => '[email protected]',
);

//For DHL Shiping
$shipingMethod = 1;

//For Aramex Shiping
/* $shipingMethod = 2; */

//Fill POST fields array
$postFields = [
    //Fill required data
    'NotificationOption' => 'Lnk', //'SMS', 'EML', or 'ALL'
    'InvoiceValue'       => '50',
    'CustomerName'       => 'fname lname',
    'InvoiceItems'       => $invoiceItems,
    'ShippingConsignee'  => $shippingConsignee,
    'ShippingMethod'     => $shipingMethod,
        //Fill optional data
        //'DisplayCurrencyIso' => 'KWD',
        //'MobileCountryCode'  => '+965',
        //'CustomerMobile'     => '1234567890',
        //'CustomerEmail'      => '[email protected]',
        //'CallBackUrl'        => 'https://example.com/callback.php',
        //'ErrorUrl'           => 'https://example.com/callback.php', //or 'https://example.com/error.php'
        //'Language'           => 'en', //or 'ar'
        //'CustomerReference'  => 'orderId',
        //'CustomerCivilId'    => 'CivilId',
        //'UserDefinedField'   => 'This could be string, number, or array',
        //'ExpiryDate'         => '', //The Invoice expires after 3 days by default. Use 'Y-m-d\TH:i:s' format in the 'Asia/Kuwait' time zone.
        //'SourceInfo'         => 'Pure PHP', //For example: (Laravel/Yii API Ver2.0 integration)
        //'CustomerAddress'    => $customerAddress,   
];

//Call endpoint
$data = sendPayment($apiURL, $apiKey, $postFields);

//You can save payment data in database as per your needs
$invoiceId   = $data->InvoiceId;
$paymentLink = $data->InvoiceURL;

//Redirect your customer to the invoice page to complete the payment process
//Display the payment link to your customer
echo "Click on <a href='$paymentLink' target='_blank'>$paymentLink</a> to pay with invoiceID $invoiceId.";
die;


/* ------------------------ Functions --------------------------------------- */
/*
 * Send Payment Endpoint Function 
 */

function sendPayment($apiURL, $apiKey, $postFields) {

    $json = callAPI("$apiURL/v2/SendPayment", $apiKey, $postFields);
    return $json->Data;
}

//------------------------------------------------------------------------------
/*
 * Call API Endpoint Function
 */

function callAPI($endpointURL, $apiKey, $postFields = [], $requestType = 'POST') {

    $curl = curl_init($endpointURL);
    curl_setopt_array($curl, array(
        CURLOPT_CUSTOMREQUEST  => $requestType,
        CURLOPT_POSTFIELDS     => json_encode($postFields),
        CURLOPT_HTTPHEADER     => array("Authorization: Bearer $apiKey", 'Content-Type: application/json'),
        CURLOPT_RETURNTRANSFER => true,
    ));

    $response = curl_exec($curl);
    $curlErr  = curl_error($curl);

    curl_close($curl);

    if ($curlErr) {
        //Curl is not working in your server
        die("Curl Error: $curlErr");
    }

    $error = handleError($response);
    if ($error) {
        die("Error: $error");
    }

    return json_decode($response);
}

//------------------------------------------------------------------------------
/*
 * Handle Endpoint Errors Function
 */

function handleError($response) {

    $json = json_decode($response);
    if (isset($json->IsSuccess) && $json->IsSuccess == true) {
        return null;
    }

    //Check for the errors
    if (isset($json->ValidationErrors) || isset($json->FieldsErrors)) {
        $errorsObj = isset($json->ValidationErrors) ? $json->ValidationErrors : $json->FieldsErrors;
        $blogDatas = array_column($errorsObj, 'Error', 'Name');

        $error = implode(', ', array_map(function ($k, $v) {
                    return "$k: $v";
                }, array_keys($blogDatas), array_values($blogDatas)));
    } else if (isset($json->Data->ErrorMessage)) {
        $error = $json->Data->ErrorMessage;
    }

    if (empty($error)) {
        $error = (isset($json->Message)) ? $json->Message : (!empty($response) ? $response : 'API key or API URL is not correct');
    }

    return $error;
}

/* -------------------------------------------------------------------------- */
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace SendPaymentShipping
{
    class Program
    {
        // You can get test token from this page  https://myfatoorah.readme.io/docs/test-token
        static string token = "";
        static string baseURL = "https://apitest.myfatoorah.com";

        static async Task Main(string[] args)
        {
            var response = await SendPaymentWithShipping().ConfigureAwait(false);
            Console.WriteLine("Send Payment with shipping Response :");
            Console.WriteLine(response);

            Console.ReadLine();
        }
        public static async Task<string> SendPaymentWithShipping()
        {
            var sendPaymentRequest = new
            {
                //required fields
                CustomerName = "Customer Name",
                NotificationOption = "LNK",
                InvoiceValue = 100,
                //optional fields 
                DisplayCurrencyIso = "KWD",
                MobileCountryCode = "965",
                CustomerMobile = "12345678",
                CustomerEmail = "[email protected]",
                CallBackUrl = "https://example.com/callback",
                ErrorUrl = "https://example.com/error",
                Language = "En",
                CustomerReference = "",
                CustomerCivilId = "",
                UserDefinedField = "",
                ExpiryDate = DateTime.Now.AddYears(1),
                ShippingMethod = 1,
                CustomerAddress = new
                {
                    Block = "Bl",
                    AddressInstructions = "instr",
                    HouseBuildingNo = "11",
                    Street = "Street1"
                },
                InvoiceItems = new[] {
                        new {
                          ItemName = "item1", Quantity = 2, UnitPrice = 50, Weight = 1, Width = 1, Height = 1, Depth = 1
                        }
                 },
                ShippingConsignee = new
                {
                    PersonName = "PN",
                    CityName = "ABBASIYA",
                    CountryCode = "kw",
                    EmailAddress = "[email protected]",
                    LineAddress = "Address",
                    Mobile = "01000013",
                    PostalCode = "1111"
                }

            };
            var sendPaymentRequestJSON = JsonConvert.SerializeObject(sendPaymentRequest);
            return await PerformRequest(sendPaymentRequestJSON, "SendPayment").ConfigureAwait(false);

        }
        public static async Task<string> PerformRequest(string requestJSON, string endPoint)
        {
            string url = baseURL + $"/v2/{endPoint}";
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            var httpContent = new StringContent(requestJSON, System.Text.Encoding.UTF8, "application/json");
            var responseMessage = await client.PostAsync(url, httpContent).ConfigureAwait(false);
            string response = string.Empty;
            if (!responseMessage.IsSuccessStatusCode)
            {
                response = JsonConvert.SerializeObject(new
                {
                    IsSuccess = false,
                    Message = responseMessage.StatusCode.ToString()
                });
            }
            else
            {
                response = await responseMessage.Content.ReadAsStringAsync();
            }

            return response;
        }

    }

}
# Send Payment API

# Import required libraries (make sure it is installed!)
import requests
import json
import sys


# Define Functions

def check_data(key, response_data):
    if key in response_data.keys() and response_data[key] is not None:
        return True
    else:
        return False


# Error Handle Function
def handle_response(response):
    if response.text == "":  # In case of empty response
        raise Exception("API key is not correct")

    response_data = response.json()
    response_keys = response_data.keys()

    if "IsSuccess" in response_keys and response_data["IsSuccess"] is True:
        return  # Successful
    elif check_data("ValidationErrors", response_data):
        error = []
        for i in range(len(response.json()["ValidationErrors"])):
            v_error = [response_data["ValidationErrors"][i].get(key) for key in ["Name", "Error"]]
            error.append(v_error)
    elif check_data("ErrorMessage", response_data):
        error = response_data["ErrorMessage"]
    elif check_data("Message", response_data):
        error = response_data["Message"]
    elif check_data("ErrorMessage", response_data["Data"]):
        error = response_data["Data"]["ErrorMessage"]
    else:
        error = "An Error has occurred. API response: " + response.text
    raise Exception(error)


# Call API Function
def call_api(api_url, api_key, request_data, request_type="POST"):
    request_data = json.dumps(request_data)
    headers = {"Content-Type": "application/json", "Authorization": "Bearer " + api_key}
    response = requests.request(request_type, api_url, data=request_data, headers=headers)
    handle_response(response)
    return response


# Send Payment endpoint Function
def send_payment(sendpay_data):
    api_url = base_url + "/v2/SendPayment"
    sendpay_response = call_api(api_url, api_key, sendpay_data).json()  # RReceiving the response of MyFatoorah

    invoice_id = sendpay_response["Data"]["InvoiceId"]
    invoice_url = sendpay_response["Data"]["InvoiceURL"]
    # Send Payment output if successful
    print("InvoiceId: ", invoice_id,
          "\nInvoiceURL: ", invoice_url)
    return invoice_id, invoice_url


# Test Environment
base_url = "https://apitest.myfatoorah.com"
api_key = "MyTokenValue"  # Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

# Live Environment
# base_url = "https://api.myfatoorah.com"
# api_key = "mytokenvalue" #Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token


invoice_items = [
                {
                    "ItemName": "string",
                    "Quantity": 20,
                    "UnitPrice": 5,
                    "Description": "string",
                    "Weight": 0.5,
                    "Width": 10,
                    "Height": 15,
                    "Depth": 19
                }
                ]


shipping_consignee = {
                     "PersonName": "fname lname",
                     "Mobile": "1234567890",
                     "LineAddress": "Address",
                     "CityName": "DUBAI",
                     "PostalCode": "12345",
                     "CountryCode": "AE"
}

shipping_method = 1  # 1 for DHL, 2 for Aramex

# SendPayment Request
sendpay_data = {
                "CustomerName": "name",  # Mandatory Field ("string")
                "NotificationOption": "LNK",  # Mandatory Field ("LNK", "SMS", "EML", or "ALL")
                "InvoiceValue": 100,  # Mandatory Field (Number)
                "InvoiceItems": invoice_items,
                "ShippingConsignee": shipping_consignee,
                "ShippingMethod": shipping_method,
            # Optional Fields
                # "MobileCountryCode": "965",
                # "CustomerMobile": "12345678", #Mandatory if the NotificationOption = SMS or ALL
                # "CustomerEmail": "[email protected]", #Mandatory if the NotificationOption = EML or ALL
                # "DisplayCurrencyIso": "kwd",
                # "CallBackUrl": "https://yoursite.com/success",
                # "ErrorUrl": "https://yoursite.com/error",
                # "Language": "en",
                # "CustomerReference": "noshipping-nosupplier",
                # "CustomerAddress": {
                #     "Block": "string",
                #     "Street": "string",
                #     "HouseBuildingNo": "string",
                #     "Address": "address",
                #     "AddressInstructions": "string"
                #     },
                # "InvoiceItems": [
                #     {
                #     "ItemName": "string",
                #     "Quantity": 20,
                #     "UnitPrice": 5
                #     }
                #     ]
            }


try:
    send_payment(sendpay_data)
except:
    ex_type, ex_value, ex_traceback = sys.exc_info()
    print("Exception type : %s " % ex_type.__name__)
    print("Exception message : %s" % ex_value)

Gateway Integration with Shipping

<?php

/* ------------------------ Configurations ---------------------------------- */
//Test
$apiURL = 'https://apitest.myfatoorah.com';
$apiKey = ''; //Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

//Live
//$apiURL = 'https://api.myfatoorah.com';
//$apiKey = ''; //Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token


/* ------------------------ Call InitiatePayment Endpoint ------------------- */
//Fill POST fields array
$ipPostFields = ['InvoiceAmount' => 100, 'CurrencyIso' => 'KWD'];

//Call endpoint
$paymentMethods = initiatePayment($apiURL, $apiKey, $ipPostFields);

//You can save $paymentMethods information in database to be used later
foreach ($paymentMethods as $pm) {
    if ($pm->PaymentMethodEn == 'VISA/MASTER') {
        $paymentMethodId = $pm->PaymentMethodId;
        break;
    }
}

/* ------------------------ Call ExecutePayment Endpoint -------------------- */
//Fill customer address array
/* $customerAddress = array(
  'Block'               => 'Blk #', //optional
  'Street'              => 'Str', //optional
  'HouseBuildingNo'     => 'Bldng #', //optional
  'Address'             => 'Addr', //optional
  'AddressInstructions' => 'More Address Instructions', //optional
  ); */

//Fill invoice item array
$invoiceItems[] = [
    'ItemName'  => 'Item Name', //ISBAN, or SKU
    'Quantity'  => '2', //Item's quantity
    'UnitPrice' => '25', //Price per item
    'weight'    => 0.250, //Weight must be in kg.
    'Width'     => 11.4, //It must be in cm.
    'Height'    => 2.6, //It must be in cm.
    'Depth'     => 3.2, //It must be in cm.
];

//Shipping Consignee
$shippingConsignee = array(
    //Fill required data
    'PersonName'  => 'fname lname',
    'Mobile'      => '1234567890',
    'LineAddress' => 'Address',
    'CityName'    => 'DUBAI',
    'PostalCode'  => '12345',
    'CountryCode' => 'AE'
        //Fill optional data
        //'EmailAddress' => '[email protected]',
);

//For DHL Shiping
$shipingMethod = 1;

//For Aramex Shiping
/* $shipingMethod = 2; */

//Fill POST fields array
$postFields = [
    //Fill required data
    'paymentMethodId'   => $paymentMethodId,
    'InvoiceValue'      => '50',
    'CallBackUrl'       => 'https://example.com/callback.php',
    'ErrorUrl'          => 'https://example.com/callback.php', //or 'https://example.com/error.php'    
    'InvoiceItems'      => $invoiceItems,
    'ShippingConsignee' => $shippingConsignee,
    'ShippingMethod'    => $shipingMethod,
        //Fill optional data
        //'CustomerName'       => 'fname lname',
        //'DisplayCurrencyIso' => 'KWD',
        //'MobileCountryCode'  => '+965',
        //'CustomerMobile'     => '1234567890',
        //'CustomerEmail'      => '[email protected]',
        //'Language'           => 'en', //or 'ar'
        //'CustomerReference'  => 'orderId',
        //'CustomerCivilId'    => 'CivilId',
        //'UserDefinedField'   => 'This could be string, number, or array',
        //'ExpiryDate'         => '', //The Invoice expires after 3 days by default. Use 'Y-m-d\TH:i:s' format in the 'Asia/Kuwait' time zone.
        //'SourceInfo'         => 'Pure PHP', //For example: (Laravel/Yii API Ver2.0 integration)
        //'CustomerAddress'    => $customerAddress,
];

//Call endpoint
$data = executePayment($apiURL, $apiKey, $postFields);

//You can save payment data in database as per your needs
$invoiceId   = $data->InvoiceId;
$paymentLink = $data->PaymentURL;

//Redirect your customer to the payment page to complete the payment process
//Display the payment link to your customer
echo "Click on <a href='$paymentLink' target='_blank'>$paymentLink</a> to pay with invoiceID $invoiceId.";
die;


/* ------------------------ Functions --------------------------------------- */
/*
 * Initiate Payment Endpoint Function 
 */

function initiatePayment($apiURL, $apiKey, $postFields) {

    $json = callAPI("$apiURL/v2/InitiatePayment", $apiKey, $postFields);
    return $json->Data->PaymentMethods;
}

//------------------------------------------------------------------------------
/*
 * Execute Payment Endpoint Function 
 */

function executePayment($apiURL, $apiKey, $postFields) {

    $json = callAPI("$apiURL/v2/ExecutePayment", $apiKey, $postFields);
    return $json->Data;
}

//------------------------------------------------------------------------------
/*
 * Call API Endpoint Function
 */

function callAPI($endpointURL, $apiKey, $postFields = [], $requestType = 'POST') {

    $curl = curl_init($endpointURL);
    curl_setopt_array($curl, array(
        CURLOPT_CUSTOMREQUEST  => $requestType,
        CURLOPT_POSTFIELDS     => json_encode($postFields),
        CURLOPT_HTTPHEADER     => array("Authorization: Bearer $apiKey", 'Content-Type: application/json'),
        CURLOPT_RETURNTRANSFER => true,
    ));

    $response = curl_exec($curl);
    $curlErr  = curl_error($curl);

    curl_close($curl);

    if ($curlErr) {
        //Curl is not working in your server
        die("Curl Error: $curlErr");
    }

    $error = handleError($response);
    if ($error) {
        die("Error: $error");
    }

    return json_decode($response);
}

//------------------------------------------------------------------------------
/*
 * Handle Endpoint Errors Function 
 */

function handleError($response) {

    $json = json_decode($response);
    if (isset($json->IsSuccess) && $json->IsSuccess == true) {
        return null;
    }

    //Check for the errors
    if (isset($json->ValidationErrors) || isset($json->FieldsErrors)) {
        $errorsObj = isset($json->ValidationErrors) ? $json->ValidationErrors : $json->FieldsErrors;
        $blogDatas = array_column($errorsObj, 'Error', 'Name');

        $error = implode(', ', array_map(function ($k, $v) {
                    return "$k: $v";
                }, array_keys($blogDatas), array_values($blogDatas)));
    } else if (isset($json->Data->ErrorMessage)) {
        $error = $json->Data->ErrorMessage;
    }

    if (empty($error)) {
        $error = (isset($json->Message)) ? $json->Message : (!empty($response) ? $response : 'API key or API URL is not correct');
    }

    return $error;
}

/* -------------------------------------------------------------------------- */
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace ExecutePaymentShipping
{
    class Program
    {
        // You can get test token from this page  https://myfatoorah.readme.io/docs/test-token
        static string token = "";
        static string baseURL = "https://apitest.myfatoorah.com";

        static async Task Main(string[] args)
        {
            var executeResponse = await ExecutePayment().ConfigureAwait(false);
            Console.WriteLine("Execute Payment Response :");
            Console.WriteLine(executeResponse);

            Console.ReadLine();
        }

        public static async Task<string> ExecutePayment()
        {
            var executePaymentRequest = new
            {
                //required fields
                PaymentMethodId = "20",
                InvoiceValue = 1000,
                CallBackUrl = "https://example.com/callback",
                ErrorUrl = "https://example.com/error",
                //optional fields 
                CustomerName = "Customer Name",
                DisplayCurrencyIso = "KWD",
                MobileCountryCode = "965",
                CustomerMobile = "12345678",
                CustomerEmail = "[email protected]",
                Language = "En",
                CustomerReference = "",
                CustomerCivilId = "",
                UserDefinedField = "",
                ExpiryDate = DateTime.Now.AddYears(1),
                ShippingMethod = 1,
                CustomerAddress = new
                {
                    Block = "Bl",
                    AddressInstructions = "instr",
                    HouseBuildingNo = "11",
                    Street = "Street1"
                },
                InvoiceItems = new[] {
                        new {
                          ItemName = "item1", Quantity = 2, UnitPrice = 500, Weight = 1, Width = 1, Height = 1, Depth = 1
                        }
                 },
                ShippingConsignee = new
                {
                    PersonName = "PN",
                    CityName = "ABBASIYA",
                    CountryCode = "kw",
                    EmailAddress = "[email protected]",
                    LineAddress = "Address",
                    Mobile = "01000013",
                    PostalCode = "1111"
                }

            };
            var executeRequestJSON = JsonConvert.SerializeObject(executePaymentRequest);
            return await PerformRequest(executeRequestJSON, "ExecutePayment").ConfigureAwait(false);
        }
        public static async Task<string> PerformRequest(string requestJSON, string endPoint)
        {
            string url = baseURL + $"/v2/{endPoint}";
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            var httpContent = new StringContent(requestJSON, System.Text.Encoding.UTF8, "application/json");
            var responseMessage = await client.PostAsync(url, httpContent).ConfigureAwait(false);
            string response = string.Empty;
            if (!responseMessage.IsSuccessStatusCode)
            {
                response = JsonConvert.SerializeObject(new
                {
                    IsSuccess = false,
                    Message = responseMessage.StatusCode.ToString()
                });
            }
            else
            {
                response = await responseMessage.Content.ReadAsStringAsync();
            }

            return response;
        }
    }
}
#Execute Payment API

# Import required libraries (make sure it is installed!)
import requests
import json
import sys

# -----------------------------Define Functions

def check_data(key, response_data):
    if key in response_data.keys() and response_data[key] is not None:
        return True
    else:
        return False


# Error Handle Function
def handle_response(response):
    if response.text == "":  # In case of empty response
        raise Exception("API key is not correct")

    response_data = response.json()
    response_keys = response_data.keys()

    if "IsSuccess" in response_keys and response_data["IsSuccess"] is True:
        return  # Successful
    elif check_data("ValidationErrors", response_data):
        error = []
        for i in range(len(response.json()["ValidationErrors"])):
            v_error = [response_data["ValidationErrors"][i].get(key) for key in ["Name", "Error"]]
            error.append(v_error)
    elif check_data("ErrorMessage", response_data):
        error = response_data["ErrorMessage"]
    elif check_data("Message", response_data):
        error = response_data["Message"]
    elif check_data("ErrorMessage", response_data["Data"]):
        error = response_data["Data"]["ErrorMessage"]
    else:
        error = "An Error has occurred. API response: " + response.text
    raise Exception(error)


# Call API Function
def call_api(api_url, api_key, request_data, request_type="POST"):
    request_data = json.dumps(request_data)
    headers = {"Content-Type": "application/json", "Authorization": "Bearer " + api_key}
    response = requests.request(request_type, api_url, data=request_data, headers=headers)
    handle_response(response)
    return response


# Initiate Payment endpoint Function
def initiate_payment(initiatepay_request):
    api_url = base_url + "/v2/InitiatePayment"
    initiatedpay_response = call_api(api_url, api_key, initiatepay_request).json()
    payment_methods = initiatedpay_response["Data"]["PaymentMethods"]
    # Initiate Payment output if successful
    #print("Payment Methods: ", payment_methods)
    return payment_methods


# Execute Payment endpoint Function
def execute_payment(executepay_request):
    api_url = base_url + "/v2/ExecutePayment"
    executepay_response = call_api(api_url, api_key, executepay_request).json()
    invoice_id = executepay_response["Data"]["InvoiceId"]
    invoice_url = executepay_response["Data"]["PaymentURL"]
    # Execute Payment output if successful
    print("InvoiceId: ", invoice_id,
          "\nInvoiceURL: ", invoice_url)
    return invoice_id, invoice_url



# Test Environment
base_url = "https://apitest.myfatoorah.com"
api_key = "MyTokenValue"  # Test token value to be placed here: https:#myfatoorah.readme.io/docs/test-token

# Live Environment
# base_url = "https:#api.myfatoorah.com"
# api_key = "mytokenvalue" #Live token value to be placed here: https:#myfatoorah.readme.io/docs/live-token


# Initaite Payment request data
initiatepay_request = {
                    "InvoiceAmount": 100,
                    "CurrencyIso": "KWD"
                    }

invoice_items = [
                {
                    "ItemName": "string",
                    "Quantity": 20,
                    "UnitPrice": 5,
                    "Description": "string",
                    "Weight": 0.5,
                    "Width": 30,
                    "Height": 15,
                    "Depth": 30
                }
            ]

shipping_consignee = {
                     "PersonName": "fname lname",
                     "Mobile": "1234567890",
                     "LineAddress": "Address",
                     "CityName": "DUBAI",
                     "PostalCode": "12345",
                     "CountryCode": "AE"}

shiping_method = 1 # 1 for DHL, 2 for Aramex


# Getting the value of payment Method Id
payment_method = initiate_payment(initiatepay_request)
# payment_method_id = payment_method[-1]["PaymentMethodId"]

try:
    # Getting the value of payment Method Id
    payment_method = initiate_payment(initiatepay_request)

    # Creating a simplified list for payment methods
    payment_method_list = []
    for item in range(len(payment_method)):
        if payment_method[item]["IsDirectPayment"] == False:
            y = [payment_method[item].get(key) for key in ["PaymentMethodEn", "PaymentMethodId"]]
            payment_method_list.append(y)
    print(payment_method_list)


    # Get the payment method key.
    while True:
        payment_method_id = input("Kindly enter the number equivalent to the required payment method: ")
        try:
            if int(payment_method_id) in [el[1] for el in payment_method_list]:
                break
            else:
                print("Kindly enter a correct payment method id")
        except:
            print("The input must be a number")

    # Based on the initiate payment response, we select the value of reference number to choose payment method

    # Execute Payment Request
    executepay_request = {
                         "paymentMethodId" : payment_method_id,
                         "InvoiceValue"    : 100,
                         "CallBackUrl"     : "https://example.com/callback.php",
                         "ErrorUrl"        : "https://example.com/callback.php",
                         "InvoiceItems": invoice_items,
                         "ShippingConsignee": shipping_consignee,
                         "ShippingMethod": shiping_method,
                    # Fill optional data
                         #"CustomerName"       : "fname lname",
                         #"DisplayCurrencyIso" : "KWD",
                         #"MobileCountryCode"  : "+965",
                         #"CustomerMobile"     : "1234567890",
                         #"CustomerEmail"      : "[email protected]",
                         #"Language"           : "en", #or "ar"
                         #"CustomerReference"  : "orderId",
                         #"CustomerCivilId"    : "CivilId",
                         #"UserDefinedField"   : "This could be string, number, or array",
                         #"ExpiryDate"         : "", #The Invoice expires after 3 days by default. Use "Y-m-d\TH:i:s" format in the "Asia/Kuwait" time zone.
                         #"SourceInfo"         : "Pure PHP", #For example: (Laravel/Yii API Ver2.0 integration)
                         #"CustomerAddress"    : "customerAddress",
                         #"InvoiceItems"       : "invoiceItems",
                    }

    execute_payment(executepay_request)
except:
    ex_type, ex_value, ex_traceback = sys.exc_info()
    print("Exception type : %s " % ex_type.__name__)
    print("Exception message : %s" % ex_value)

Direct Payment with Shipping

<?php

/* ------------------------ Configurations ---------------------------------- */
//Test
$apiURL = 'https://apitest.myfatoorah.com';
$apiKey = ''; //Test token value to be placed here: https://myfatoorah.readme.io/docs/test-token

//Live
//$apiURL = 'https://api.myfatoorah.com';
//$apiKey = ''; //Live token value to be placed here: https://myfatoorah.readme.io/docs/live-token


/* ------------------------ Call InitiatePayment Endpoint ------------------- */
//Fill POST fields array
$ipPostFields = ['InvoiceAmount' => 100, 'CurrencyIso' => 'KWD'];

//Call endpoint
$paymentMethods = initiatePayment($apiURL, $apiKey, $ipPostFields);

//You can save $paymentMethods information in database to be used later
foreach ($paymentMethods as $pm) {
    if ($pm->PaymentMethodEn == 'Visa/Master Direct 3DS Flow' && $pm->IsDirectPayment) {
        $paymentMethodId = $pm->PaymentMethodId;
        break;
    }
}

/* ------------------------ Call ExecutePayment Endpoint -------------------- */
//Fill customer address array
/* $customerAddress = array(
  'Block'               => 'Blk #', //optional
  'Street'              => 'Str', //optional
  'HouseBuildingNo'     => 'Bldng #', //optional
  'Address'             => 'Addr', //optional
  'AddressInstructions' => 'More Address Instructions', //optional
  ); */

//Fill invoice item array
$invoiceItems[] = [
    'ItemName'  => 'Item Name', //ISBAN, or SKU
    'Quantity'  => '2', //Item's quantity
    'UnitPrice' => '25', //Price per item
    'weight'    => 0.250, //Weight must be in kg.
    'Width'     => 11.4, //It must be in cm.
    'Height'    => 2.6, //It must be in cm.
    'Depth'     => 3.2, //It must be in cm.
];

//Shipping Consignee
$shippingConsignee = array(
    //Fill required data
    'PersonName'  => 'fname lname',
    'Mobile'      => '1234567890',
    'LineAddress' => 'Address',
    'CityName'    => 'DUBAI',
    'PostalCode'  => '12345',
    'CountryCode' => 'AE'
        //Fill optional data
        //'EmailAddress' => '[email protected]',
);

//For DHL Shiping
$shipingMethod = 1;

//For Aramex Shiping
/* $shipingMethod = 2; */

//Fill POST fields array
$postFields = [
    //Fill required data
    'paymentMethodId'   => $paymentMethodId,
    'InvoiceValue'      => '50',
    'CallBackUrl'       => 'https://example.com/callback.php',
    'ErrorUrl'          => 'https://example.com/callback.php', //or 'https://example.com/error.php'    
    'InvoiceItems'      => $invoiceItems,
    'ShippingConsignee' => $shippingConsignee,
    'ShippingMethod'    => $shipingMethod,
        //Fill optional data
        //'CustomerName'       => 'fname lname',
        //'DisplayCurrencyIso' => 'KWD',
        //'MobileCountryCode'  => '+965',
        //'CustomerMobile'     => '1234567890',
        //'CustomerEmail'      => '[email protected]',
        //'Language'           => 'en', //or 'ar'
        //'CustomerReference'  => 'orderId',
        //'CustomerCivilId'    => 'CivilId',
        //'UserDefinedField'   => 'This could be string, number, or array',
        //'ExpiryDate'         => '', //The Invoice expires after 3 days by default. Use 'Y-m-d\TH:i:s' format in the 'Asia/Kuwait' time zone.
        //'SourceInfo'         => 'Pure PHP', //For example: (Laravel/Yii API Ver2.0 integration)
        //'CustomerAddress'    => $customerAddress,
];

//Call endpoint
$data = executePayment($apiURL, $apiKey, $postFields);

//You can save payment data in database as per your needs
$invoiceId  = $data->InvoiceId;
$paymentURL = $data->PaymentURL;


/* ------------------------ Call DirectPayment Endpoint --------------------- */
//Fill POST fields array
$cardInfo = [
    'PaymentType' => 'card',
    'Bypass3DS'   => false,
    'Card'        => [
        'Number'         => '5123450000000008',
        'ExpiryMonth'    => '05',
        'ExpiryYear'     => '21',
        'SecurityCode'   => '100',
        'CardHolderName' => 'fname lname'
    ]
];

//Call endpoint
$directData = directPayment($paymentURL, $apiKey, $cardInfo);

//You can save payment data in database as per your needs
$paymentId   = $directData->PaymentId;
$paymentLink = $directData->PaymentURL;

//Redirect your customer to the OTP page to complete the payment process
//Display the payment link to your customer
echo "Click on <a href='$paymentLink' target='_blank'>$paymentLink</a> to pay with payment ID: $paymentId, and invoice ID: $invoiceId.";
die;


/* ------------------------ Functions --------------------------------------- */
/*
 * Initiate Payment Endpoint Function 
 */

function initiatePayment($apiURL, $apiKey, $postFields) {

    $json = callAPI("$apiURL/v2/InitiatePayment", $apiKey, $postFields);
    return $json->Data->PaymentMethods;
}

//------------------------------------------------------------------------------
/*
 * Execute Payment Endpoint Function 
 */

function executePayment($apiURL, $apiKey, $postFields) {

    $json = callAPI("$apiURL/v2/ExecutePayment", $apiKey, $postFields);
    return $json->Data;
}

//------------------------------------------------------------------------------
/*
 * Direct Payment Endpoint Function 
 */

function directPayment($paymentURL, $apiKey, $postFields) {

    $json = callAPI($paymentURL, $apiKey, $postFields);
    return $json->Data;
}

//------------------------------------------------------------------------------
/*
 * Call API Endpoint Function
 */

function callAPI($endpointURL, $apiKey, $postFields = [], $requestType = 'POST') {

    $curl = curl_init($endpointURL);
    curl_setopt_array($curl, array(
        CURLOPT_CUSTOMREQUEST  => $requestType,
        CURLOPT_POSTFIELDS     => json_encode($postFields),
        CURLOPT_HTTPHEADER     => array("Authorization: Bearer $apiKey", 'Content-Type: application/json'),
        CURLOPT_RETURNTRANSFER => true,
    ));

    $response = curl_exec($curl);
    $curlErr  = curl_error($curl);

    curl_close($curl);

    if ($curlErr) {
        //Curl is not working in your server
        die("Curl Error: $curlErr");
    }

    $error = handleError($response);
    if ($error) {
        die("Error: $error");
    }

    return json_decode($response);
}

//------------------------------------------------------------------------------
/*
 * Handle Endpoint Errors Function 
 */

function handleError($response) {

    $json = json_decode($response);
    if (isset($json->IsSuccess) && $json->IsSuccess == true) {
        return null;
    }

    //Check for the errors
    if (isset($json->ValidationErrors) || isset($json->FieldsErrors)) {
        $errorsObj = isset($json->ValidationErrors) ? $json->ValidationErrors : $json->FieldsErrors;
        $blogDatas = array_column($errorsObj, 'Error', 'Name');

        $error = implode(', ', array_map(function ($k, $v) {
                    return "$k: $v";
                }, array_keys($blogDatas), array_values($blogDatas)));
    } else if (isset($json->Data->ErrorMessage)) {
        $error = $json->Data->ErrorMessage;
    }

    if (empty($error)) {
        $error = (isset($json->Message)) ? $json->Message : (!empty($response) ? $response : 'API key or API URL is not correct');
    }

    return $error;
}

/* -------------------------------------------------------------------------- */
# Direct Payment End Point

# Import required libraries (make sure it is installed!)
import requests
import json
import sys

# -----------------------------Define Functions

def check_data(key, response_data):
    if key in response_data.keys() and response_data[key] is not None:
        return True
    else:
        return False


# Error Handle Function
def handle_response(response):
    if response.text == "":  # In case of empty response
        raise Exception("API key is not correct")

    response_data = response.json()
    response_keys = response_data.keys()

    if "IsSuccess" in response_keys and response_data["IsSuccess"] is True:
        return  # Successful
    elif check_data("ValidationErrors", response_data):
        error = []
        for i in range(len(response.json()["ValidationErrors"])):
            v_error = [response_data["ValidationErrors"][i].get(key) for key in ["Name", "Error"]]
            error.append(v_error)
    elif check_data("ErrorMessage", response_data):
        error = response_data["ErrorMessage"]
    elif check_data("Message", response_data):
        error = response_data["Message"]
    elif check_data("ErrorMessage", response_data["Data"]):
        error = response_data["Data"]["ErrorMessage"]
    else:
        error = "An Error has occurred. API response: " + response.text
    raise Exception(error)


# Call API Function
def call_api(api_url, api_key, request_data, request_type="POST"):
    request_data = json.dumps(request_data)
    headers = {"Content-Type": "application/json", "Authorization": "Bearer " + api_key}
    response = requests.request(request_type, api_url, data=request_data, headers=headers)
    handle_response(response)
    return response


# Initiate Payment endpoint Function
def initiate_payment(initiatepay_request):
    api_url = base_url + "/v2/InitiatePayment"
    initiatepay_response = call_api(api_url, api_key, initiatepay_request).json()
    payment_methods = initiatepay_response["Data"]["PaymentMethods"]
    # Initiate Payment output if successful
    #print("Payment Methods: ", payment_methods)
    return payment_methods


# Execute Payment endpoint Function
def execute_payment(executepay_request):
    api_url = base_url + "/v2/ExecutePayment"
    executepay_response = call_api(api_url, api_key, executepay_request).json()
    invoice_id = executepay_response["Data"]["InvoiceId"]
    invoice_url = executepay_response["Data"]["PaymentURL"]
    # Execute Payment output if successful
    #print("InvoiceId: ", invoice_id,
    #      "\nInvoiceURL: ", invoice_url)
    return invoice_id, invoice_url


# Direct Payment endpoint Function
# The payment link from execute payment is used as the API for direct payment
def direct_payment(directpay_request, invoice_url):
    directpay_response = call_api(invoice_url, api_key, directpay_request).json()
    directpay_status = directpay_response["Data"]
    # Direct Payment output if successful
    print("Direct Payment Status: ", directpay_status)
    return directpay_status


# Test Environment
base_url = "https://apitest.myfatoorah.com"
api_key = "MyTokenValue"  # Test token value to be placed here: https:#myfatoorah.readme.io/docs/test-token

# Live Environment
# base_url = "https:#api.myfatoorah.com"
# api_key = "mytokenvalue" #Live token value to be placed here: https:#myfatoorah.readme.io/docs/live-token


# Initaite Payment request data
initiatepay_request = {
                      "InvoiceAmount": 100,
                      "CurrencyIso": "KWD"
                    }

invoice_items = [
                {
                    "ItemName": "string",
                    "Quantity": 20,
                    "UnitPrice": 5,
                    "Description": "string",
                    "Weight": 0.5,
                    "Width": 10,
                    "Height": 15,
                    "Depth": 19
                }
            ]

shipping_consignee = {
                     "PersonName": "fname lname",
                     "Mobile": "1234567890",
                     "LineAddress": "Address",
                     "CityName": "DUBAI",
                     "PostalCode": "12345",
                     "CountryCode": "AE"}


shipping_method = 1 # 1 for DHL, 2 for Aramex


try:
    # Getting the value of payment Method Id
    payment_method = initiate_payment(initiatepay_request)

    # Creating a simplified list for payment methods
    payment_method_list = []
    for item in range(len(payment_method)):
        if payment_method[item]["IsDirectPayment"] == True:
            y = [payment_method[item].get(key) for key in ["PaymentMethodEn", "PaymentMethodId"]]
            payment_method_list.append(y)
    print(payment_method_list)


    # Get the payment method key.
    while True:
        payment_method_id = input("Kindly enter the number equivalent to the required payment method: ")
        try:
            if int(payment_method_id) in [el[1] for el in payment_method_list]:
                break
            else:
                print("Kindly enter a correct payment method id")
        except:
            print("The input must be a number")

    # Based on the initiate payment response, we select the value of reference number to choose payment method

    # Execute Payment Request
    executepay_request = {
                         "paymentMethodId" : payment_method_id,
                         "InvoiceValue"    : 100,
                         "CallBackUrl"     : "https://example.com/callback.php",
                         "ErrorUrl"        : "https://example.com/callback.php",
                         "InvoiceItems": invoice_items,
                         "ShippingConsignee": shipping_consignee,
                         "ShippingMethod": shipping_method,
                    # Fill optional data
                         # "CustomerName"       : "fname lname",
                         # "DisplayCurrencyIso" : "KWD",
                         # "MobileCountryCode"  : "+965",
                         # "CustomerMobile"     : "1234567890",
                         # "CustomerEmail"      : "[email protected]",
                         # "Language"           : "en", #or "ar"
                         # "CustomerReference"  : "orderId",
                         # "CustomerCivilId"    : "CivilId",
                         # "UserDefinedField"   : "This could be string, number, or array",
                         # "ExpiryDate"         : "", # The Invoice expires after 3 days by default. Use "Y-m-d\TH:i:s" format in the "Asia/Kuwait" time zone.
                         # "SourceInfo"         : "Pure PHP", #For example: (Laravel/Yii API Ver2.0 integration)
                         # "CustomerAddress"    : $customerAddress,
                         # "InvoiceItems"       : $invoiceItems,
                         }
# Execute payment t get Invoice Id and Invoice URL
    invoice_id, invoice_url = execute_payment(executepay_request)

    # Required Data for direct Payment
    directpay_request = {
                            "PaymentType": "card",
                            "Bypass3DS": False,
                            "SaveToken": "false",
                            "Token": "string",
                            "Card": {
                                "Number": "5123450000000008",
                                "ExpiryMonth": "05",
                                "ExpiryYear": "21",
                                "SecurityCode": "100",
                                "CardHolderName": "fname lname"
                            }
                         }

    direct_payment(directpay_request, invoice_url)
except:
    ex_type, ex_value, ex_traceback = sys.exc_info()
    print("Exception type : %s " % ex_type.__name__)
    print("Exception message : %s" % ex_value)



# Test Card Data for Visa/Master
# {
# "PaymentType": "card",
# "Bypass3DS": False,
# "SaveToken": False,
# "Card": {
#       "Number": "5453010000095539",
#       "ExpiryMonth": "12",
#       "ExpiryYear": "25",
#       "SecurityCode": "300",
#      }
#      }