Geidea HPP Checkout

Overview

Our Checkout offering is a pre-built payment UI that offers the quickest way to integrate and start securely accepting payments. It allows you to accept popular payment methods through a single web front-end implementation.

Geidea Checkout supports both one-time payments and subscriptions for your customers - through a quick, easy and low-code integration into your website's checkout flow. It is very user-friendly and customizable.

Additional payment methods can be enabled without any extra development work - Geidea Checkout seamlessly handles all payment method flow complexity, including 3D Secure 2.0 authentication.

How it works

Step 1: Create a checkout session

The checkout session streamlines the payment process by allowing you to pre-configure the payment details and options for the session, and then simply load the Geidea checkout payment page to complete the transaction.

You can configure this resource with multiple options such as amount and currency, payment method selection priority, appearance, order details (items, summary, etc.), and customer details.

Create Session Request

The create session endpoint requires basic authentication credentials where the merchant public key is used as the username and the API password as the password. Kindly check this section to find your access credentials.

❗️

Please initiate the Create Session API Request as a server-to-server API call from the back end.

🚧

Warning

Your API password is a secret key! It is important to never expose your API password in any part of your application. Instead, store your API password securely on the server-side, and use a backend proxy to make API requests on behalf of your frontend application. This approach ensures that your API password is never exposed to the client side, reducing the risk of unauthorized access and data breaches.

You will need the following fields to initiate a Create Session API call.

ParameterDescriptionMandatory
amountThe total amount value of the payment. This parameter is required, and the format is a double - a number with 2 digits after the decimal point. For example 19.99Yes
currencyThe currency of the payment. This is a 3-digit alphabetic code, following the ISO 4217 currency code standard. For example: SAR

List of available currencies:
SAR Saudi Riyal
EGP Egyptian Pound
AED UAE Dirham
QAR Qatari Rial
OMR Omani Rial
BHD Bahraini Dinar
KWD Kuwaiti Dinar
USD US Dollar
GBP UK Pound Sterling
EUR Euro

To enable multicurrency for your account - contact our support team.
Yes
timestampThe timestamp of the moment at which the create session request has been initiated.Yes
merchantReferenceIdThe unique identifier for the given session added by the merchant.Yes
tokenIdUnique ID of the token created for the card. This is a UUID that is created when you initiate a transaction with cardOnFile parameter as true.
Mandatory for tokenized payments.
No
signatureA parameter to ensure the security and authenticity of API communications. It involves generating a signature using the contents of the API request and secret keys, which is then sent along with the request.Yes
callbackUrlThe URL where the payment gateway should send the callback after the transaction is completed. It must have a valid SSL certificate and start with 'https://'Yes
cardOnFileIndicates whether to store the payment method for future use. If you pass 'true' in this field, Geidea will save the card and will return a tokenId in the callback after the order. This tokenId can be used later to process a payment for the same customer using the saved payment method.No
languageThe language to be used on the checkout page. The values used for this parameter is either "en" or "ar". If this parameter is not used then the default value is "en".
Mandatory for Tamara payment method
No
paymentOperationThe type of payment operation to be performed. This is an optional parameter - if not submitted, the Geidea gateway will process a 'Pay' operation by default.No
returnUrlA URL that can be used to redirect to a different page after the transaction has been completed
Mandatory for Tabby payment method
No
cofAgreementAgreement object to specify the details of the agreement between the merchant & a customer for a specific transactionNo
cofAgreement.idAn id that can be used to make an agreement merchant & a customer for a specific transactionNo
cofAgreement.typeThe type of agreement of a specific transaction. The values that can be used are "Unscheduled", "Recurring"No
customerCustomer object that specifies all details of the customerNo
customer.emailThe email of the customer that can be collected in the transaction details
Mandatory for Tamara payment method
No
customer.phoneNumberThe phone number of the customer that can be collected in the transaction details
Mandatory for Tabby & Tamara payment method
No
customer.firstNameFirst name of customer
Mandatory for Tamara payment method
No
customer.lastNameLast name of customer
Mandatory for Tamara payment method
No
customer.addressThe address of the customer including the shipping & billing addresses
Mandatory for Tamara payment method
No
customer.address.billingThe billing address of the customer to be collected in the transaction details
Mandatory for Tamara payment method
No
customer.address.billing.countryThe country code for the billing address of the customer. For example, "SAU" for Saudi Arabia
Mandatory for Tamara payment method
No
customer.address.billing.cityThe city name for the billing address of the customer.
Mandatory for Tamara payment method
No
customer.address.billing.streetThe street name for the billing address of the customer.
Mandatory for Tamara payment method
No
customer.address.billing.postalCodeThe postal code for the billing address of the customer.No
customer.address.shippingThe shipping address of the customer to be collected in the transaction details
Mandatory for Tamara payment method
No
customer.address.shipping.countryThe country code for the shipping address of the customer. For example, "SAU" for Saudi Arabia
Mandatory for Tamara payment method
No
customer.address.shipping.cityThe city name for the shipping address of the customer.
Mandatory for Tamara payment method
No
customer.address.shipping.streetThe street name for the shipping address of the customer.
Mandatory for Tamara payment method
No
customer.address.shipping.postalCodeThe postal code for the shipping address of the customer.No
orderThe object indicating details of the order
Mandatory for Tamara payment method
No
order.itemsList of item objects
Mandatory for Tabby & Tamara payment method
No
order.items.merchantItemIdId of the merchant's item
Mandatory for Tamara payment method
No
order.items.nameThe name of the item
Mandatory for Tabby & Tamara payment method
No
order.items.descriptionDescription of the item
Mandatory for Tamara payment method
No
order.items.categoriesCategories that the item belongs to
Mandatory for Tabby & Tamara payment method
No
order.items.countQuantity of the item
Mandatory for Tabby & Tamara payment method
No
order.items.pricePrice per one quantity of the item
Mandatory for Tabby & Tamara payment method
No
order.items.skuThe SKU of the item
Mandatory for Tamara payment method
No

Signature

We have asignature parameter in the Create Session API to have an additional layer of security during payment processing. To generate the signature, follow the steps below:

  1. Concatenate the string of { MerchantPublicKey, OrderAmount, OrderCurrency, MerchantReferenceId, timeStamp }. For more details about the parameters please refer : Create Session API here
  2. Amount must be formatted with 2 decimals or the signature function will convert it automatically to 2 decimals.
  3. Hash (SHA-256) the above Concatenated string by {MerchantAPIPassword}.
  4. Convert Hashed Value to Base64Str

Sample Code for generating signature

function generateSignature($merchantPublicKey, $orderAmount, $orderCurrency, $orderMerchantReferenceId, $apiPassword, $timestamp)
{
    $amountStr = number_format($orderAmount, 2, '.', '');
    $data = "{$merchantPublicKey}{$amountStr}{$orderCurrency}{$orderMerchantReferenceId}{$timestamp}";
    $hash = hash_hmac('sha256', $data, $apiPassword, true);
    return base64_encode($hash);
}


static string GenerateSignature(Guid merchantPublicKey, decimal orderAmount, string orderCurrency, string? orderMerchantReferenceId, string apiPassword,string timeStamp)
{
    var amountStr = orderAmount.ToString("F2", CultureInfo.InvariantCulture);
    var data = $"{merchantPublicKey}{amountStr}{orderCurrency}{orderMerchantReferenceId}{timeStamp}";
		using var hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(apiPassword));
    var hash = hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(data));
    return Convert.ToBase64String(hash);
 
}

Sample Code

To initiate an Initiate authentication API call, you will need to provide the following required fields to first create a session and then use the session ID in the Initiate authentication API call.

You can find a full list of parameters which can be used with the Create Session API here.

📘

Usage of the API environment endpoints

Please make sure you use the correct endpoint based on your environment

Below is an example of executing a Create Session API call for payment of 1850.00 EGP with the mandatory parameters.

    {
        "amount": "0.5",
        "currency": "SAR",
        "timestamp": "{{timestamp}}",
        "merchantReferenceId": "21036410062-3704648-12-2",
        "signature": "{{signature}}",
        "paymentOperation": "Pay",
        "language": "en",
        "callbackUrl": "https://webhook.site/c32729f0-39f0-4cf8-a8c2-e932a146b685",
        "returnUrl": "https://www.geidea.net",
        "customer": {
        "email": "[email protected]",
        "phoneNumber": "+966500617554",
        "phonecountrycode": "+966",
        "firstName": "khalil",
        "lastName": "Maasi",
        "address": {
            "billing": {
                "country": "SAU",
                "city": "test",
                "street": "test",
                "postalCode": "test"
            },
            "shipping": {
                "country": "SAU",
                "city": "test",
                "street": "test",
                "postalCode": "test"
            }
        }
    },
    "order": {
        "items": [
            {
                "merchantItemId": "SM",
                "name": "Smartwatch",
                "description": "tracking",
                "categories": "electronic",
                "count": 1,
                "price": 5270,
                "sku": "SM09"
            }
        ]
    }
}

Create Session Response

After sending the create session request in the example above - if your request is valid, then you will receive a response which includes a session object, with a session.id parameter inside. You will need to use this session.id later in order to start Geidea checkout.

Below is an example of a successful response you can expect to receive for the create session request above.

{
    "session": {
        "id": "0b02b503-fbf8-49dd-cdec-08dcdb056790",
        "amount": 0.5,
        "currency": "SAR",
        "callbackUrl": "https://webhook.site/c32729f0-39f0-4cf8-a8c2-e932a146b685",
        "returnUrl": "https://www.geidea.net",
        "expiryDate": "2024-09-24T15:31:34.3256851Z",
        "status": "Initiated",
        "merchantId": "e80ece7e-fb2a-4c0b-de94-08d8a29a107b",
        "merchantPublicKey": "22dc6fc6-78ee-4767-9b7e-ed99ba23fa60",
        "language": "en",
        "merchantReferenceId": "21036410062-3704648-12-2",
        "paymentIntentId": null,
        "paymentOperation": "Pay",
        "cardOnFile": false,
        "cofAgreement": {
            "id": null,
            "type": null
        },
        "initiatedBy": null,
        "tokenId": null,
        "customer": {
            "id": null,
            "referenceId": null,
            "create": false,
            "setDefaultMethod": false,
            "email": "[email protected]",
            "phoneNumber": "+966500617554",
            "firstName": "khalil",
            "lastName": "Maasi",
            "address": {
                "billing": {
                    "country": "SAU",
                    "city": "test",
                    "street": "test",
                    "postalCode": "test"
                },
                "shipping": {
                    "country": "SAU",
                    "city": "test",
                    "street": "test",
                    "postalCode": "test"
                }
            }
        },
        "platform": {
            "name": null,
            "version": null,
            "pluginVersion": null,
            "partnerId": null
        },
        "paymentOptions": null,
        "recurrence": null,
        "order": {
            "integrationType": null,
            "description": null,
            "summary": {
                "subTotal": null,
                "shipping": null,
                "vat": null
            },
            "statementDescriptor": {
                "name": null,
                "phone": null
            },
            "items": [
                {
                    "merchantItemId": "SM",
                    "name": "Smartwatch",
                    "description": "tracking",
                    "categories": "electronic",
                    "count": 1,
                    "price": 5270,
                    "sku": "SM09"
                }
            ]
        },
        "items": [
            {
                "merchantItemId": "SM",
                "name": "Smartwatch",
                "description": "tracking",
                "categories": "electronic",
                "count": 1,
                "price": 5270,
                "sku": "SM09"
            }
        ],
        "appearance": null,
        "metadata": {
            "custom": null
        },
        "paymentMethod": {
            "cardNumber": null,
            "cardholderName": null,
            "cvv": null,
            "expiryDate": {
                "month": null,
                "year": null
            }
        },
        "subscription": null,
        "acceptTabbyPaymentMethod": true
    },
    "responseMessage": "Success",
    "detailedResponseMessage": "The operation was successful",
    "language": "EN",
    "responseCode": "000",
    "detailedResponseCode": "000",
    "signature": "QMPKpuXfPjSB0mPNR7M966sV7p6Bq2Hjn01Y9xP/ctA="
}

The response includes your session expiryDate - each session by default expires after 15 minutes. This is the timeframe in which you will need to start the Geidea Checkout flow. You can also see the already mentioned id of the session - which you must save and use in the "Start the Payment" section of this flow.

Step 2: Set up Geidea Checkout

Next, embed our Geidea Checkout JavaScript library into your web checkout page HTML. In the example below, we've embedded the script into the section of our example checkout.html file.

📘

Usage of the script tag environment

Please make sure you use the correct source script value based on your environment

<head>
  <!-- GeideaCheckout web script load section -->
  <script src="https://www.merchant.geidea.net/hpp/geideaCheckout.min.js"></script>
</head>

After you have embedded the Geidea Checkout JS library, you should initialize an instance of the GeideaCheckout payment object.

// initialize the payment object
const payment = new GeideaCheckout(onSuccess, onError, onCancel);

To initialize the payment object, you need to:

1. Provide reference to three callback event functions (onSuccess, onError, onCancel). After the payment process is completed, Geidea Checkout will redirect the customer back to the parent URL from where the checkout was started. One of the three methods will be triggered after the payment through the Geidea Checkout form is completed and the customer has returned. You must create a function for each of these events.

  • onSuccess: this callback event function is triggered after a payment has been successful. You can use this function to display a successful message to the customer to confirm that the payment order has been successful. The responseCode parameter in this case will always be '000' and the responseMessage will be 'Success'. You can see a full list of Response codes here.

  • onError: this callback event function is triggered when the parameters in your payment configuration (configurePayment) are invalid; or when there is a payment processing error which does not allow the order to continue.

  • onCancel: this callback function is triggered when your user clicks the 'Cancel' button on the Geidea Checkout form; or when the payment has timed out.

  • Geidea Checkout will call one of the three callback events based on the outcome of the customer payment. When one of the callback events is triggered, a JSON data object including information about the order is also sent to the event. This data object includes 6 parameters which can be used to display the result of the payment to your customer:

{
   "responseCode":"string",
   "responseMessage":"string",
   "detailResponseCode":"string",
   "detailResponseMessage":"string",
   "orderId":"GUID",
   "reference":"GUID"
}

2. Create the onSuccess, onError, and onCancel functions. You can determine how you would like the checkout flow to continue after payment has been completed - for example, you can display a successful or failed message to the customer, or you can redirect to a success or error page - you can create your functions as you like.

In the following example, each of the three functions is only alerting the order information after Geidea Checkout is completed:

// onSuccess function definition
let onSuccess = function(data) {
  alert("Success:" + "\n" +
  data.responseCode + "\n" +
  data.responseMessage + "\n" +
  data.detailResponseCode + "\n" +
  data.detailResponseMessage + "\n" +
  data.orderId + "\n" +
  data.reference);
}

// onError function definition
let onError = function(data) {
  alert("Error:" + "\n" +
  data.responseCode + "\n" +
  data.responseMessage + "\n" +
  data.detailResponseCode + "\n" +
  data.detailResponseMessage + "\n" +
  data.orderId + "\n" +
  data.reference);
}

//onCancel function definition
let onCancel = function(data) {
  alert("Cancel:" + "\n" +
  data.responseCode + "\n" +
  data.responseMessage + "\n" +
  data.detailResponseCode + "\n" +
  data.detailResponseMessage + "\n" +
  data.orderId + "\n" +
  data.reference);
}
  • The orderId parameter returned in the callback event data object is Geidea's unique ID assigned to every order. The format of this parameter is a GUID.

  • The reference parameter returned in the data object serves as an additional reference which can be used to help our support team find all the information about the payment process - in the case where an order was not created and the orderId is missing. The format of this parameter is a GUID.

Once you have completed steps 1 and 2, you are ready to start the Geidea Checkout payment.

Step 3: Start the payment

After you have created your session, received your session.id, and initialized the payment object, you are ready to start the payment with Geidea Checkout.

To start the payment, you will need to use the startPayment method by passing the session.id which you received when you created the session in Step 1:

// initialize the payment object
const payment = new GeideaCheckout(onSuccess, onError, onCancel);

// start the payment
payment.startPayment(sessionId);

The startPayment method must be attached to an action on your web page - you can attach it to a 'Checkout' or a 'Pay' button, or you can use any preferred onClick event on your own web page.

After triggering the startPayment method, Geidea Checkout will appear as a modal/popup iframe on top of your web page by default. This is the recommended flow.

687

Based on your preference - you can start Geidea Checkout anywhere during your customer checkout flow - for example, you can choose to redirect to Geidea Checkout using your sessionId, or you can load the Geidea Checkout iframe in a previously defined empty <div> container.


Sample application

Below is a basic example of a checkout.html page, which loads Geidea Checkout.

<!DOCTYPE html>
<html>
<head>
	<title>Geidea Checkout Example</title>
  	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<script src="https://www.merchant.geidea.net/hpp/geideaCheckout.min.js"></script>
	<script>
		function createAndStartPayment() {
			// Create a new XMLHttpRequest object
			var xhr = new XMLHttpRequest();

			// Set up the request
			xhr.open('POST', 'create_session.php');
			xhr.setRequestHeader('Content-Type', 'application/json');

			// Set up a function to handle the response
			xhr.onload = function() {
				if (xhr.status === 200) {
					// Get the response text
					var response = xhr.responseText.trim();

					// Check if the response is empty or not
					if (response.length > 0) {
						// Start the payment with the session ID
						startPayment(response);
					} else {
						alert('Error: Empty response from server');
					}
				} else {
					alert('Error: ' + xhr.statusText);
				}
			};

			// Set up a function to handle network errors
			xhr.onerror = function() {
				alert('Error: Network Error');
			};

            // Send the request with the JSON string
            var data = {
                amount: 10.00,
                currency: "EGP",
                callbackUrl: "https://www.example.com/callback",
                merchantReferenceId: "ABC-123",
                language: "ar",
            };
            xhr.send(JSON.stringify(data));
		}

		function startPayment(sessionId) {
			// Initialize GeideaCheckout
			var payment = new GeideaCheckout(onSuccess, onError, onCancel);

			// Start the payment
			payment.startPayment(sessionId);
		}

		// Define the onSuccess function
		let onSuccess = function(data) {
			alert('Success:' + '\n' +
			data.responseCode + '\n' +
			data.responseMessage + '\n' +
			data.detailedResponseCode + '\n' +
			data.detailedResponseMessage + '\n' +
			data.orderId + '\n' +
			data.reference);
		};

        // Define the onError function
		let onError = function(data) {
			alert('Error:' + '\n' +
			data.responseCode + '\n' +
			data.responseMessage + '\n' +
			data.detailedResponseCode + '\n' +
			data.detailedResponseMessage + '\n' +
			data.orderId + '\n' +
			data.reference);
		};

		// Define the onCancel function
		let onCancel = function(data) {
			alert('Payment Cancelled:' + '\n' +
			data.responseCode + '\n' +
			data.responseMessage + '\n' +
			data.detailedResponseCode + '\n' +
			data.detailedResponseMessage + '\n' +
			data.orderId + '\n' +
			data.reference);
		};
	</script>
</head>
<body>
	<button onclick="createAndStartPayment()">Geidea Checkout</button>
</body>
</html>

The checkout.html file above uses the following PHP script for creating a session.

<?php
// Replace with your actual merchant public key and API password
$merchantPublicKey = "Merchant Public Key";
$apiPassword = "API Password";

// Set the API endpoint URL
$url = "https://api.merchant.geidea.net/payment-intent/api/v2/direct/session";

// Retrieve the JSON string from the request body
$data = file_get_contents("php://input");

// Decode the JSON string into a PHP associative array
$data = json_decode($data, true);

// Access the values of the array
$orderAmount = $data["amount"];
$orderCurrency = $data["currency"];
$callbackUrl = $data["callbackUrl"];
$orderMerchantReferenceId = $data["merchantReferenceId"];
$language = $data["language"];
$date=new DateTime();
$timestamp = date_format($date,"Y/m/d H:i:s");

$signature = generateSignature($merchantPublicKey, $orderAmount, $orderCurrency, $orderMerchantReferenceId, $apiPassword, $timestamp);



// Set the request data
$data = array(
    'amount' => $orderAmount,
    'currency' => $orderCurrency,
    'merchantReferenceId' => $orderMerchantReferenceId,
    'timestamp' => $timestamp,
	'signature' => $signature
);

// Set the cURL options
$options = array(
    CURLOPT_URL => $url,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($data),
    CURLOPT_HTTPHEADER => array(
        "Content-Type: application/json",
        "Authorization: Basic " . base64_encode("$merchantPublicKey:$apiPassword")
    ),
    CURLOPT_RETURNTRANSFER => true
);

// Initialize cURL
$ch = curl_init();

// Set cURL options
curl_setopt_array($ch, $options);

// Execute the cURL request
$response = curl_exec($ch);

// Check for errors
if (curl_errno($ch)) {
    $error_msg = curl_error($ch);
    curl_close($ch);
    die("cURL Error: $error_msg");
}

// Close the cURL session
curl_close($ch);

// Decode the JSON response
$response_data = json_decode($response, true);

// Check for errors in the response
if ($response_data["responseCode"] !== "000" || $response_data["detailedResponseCode"] !== "000") {
    die("Error: " . $response_data["detailedResponseMessage"]);
}

// Get the session ID from the response
$session_id = $response_data["session"]["id"];

// Output the session ID
echo $session_id;

function generateSignature($merchantPublicKey, $orderAmount, $orderCurrency, $orderMerchantReferenceId, $apiPassword, $timestamp)
{
    $amountStr = number_format($orderAmount, 2, '.', '');
    $data = "{$merchantPublicKey}{$amountStr}{$orderCurrency}{$orderMerchantReferenceId}{$timestamp}";
    $hash = hash_hmac('sha256', $data, $apiPassword, true);
    return base64_encode($hash);
}

?>

Callback Validation

After the payment is complete, the Geidea platform sends a callback informing the final status of the transaction. For the checkout, the callback is automatically validated and the page is redirected the page defined for the Success, Cancelled, Error conditions. For further details of handling callbacks, please check here.