CinetPay SDK-SEAMLESS integration


Context

Today, CinetPay provides its merchants with a payment gateway that works by API call. However, in order to expand its merchant integration pole, it gives the possibility of a special integration in relation to each programming language. In fact, the SDK Seamless is one of its tools specific to Javascript, facilitating the integration of the counter.

The merchant will be able to use it in Javascript code, allowing him to call the CinetPay counter.
The rest of the document, will show the different steps to use the Seamless SDK in a project.

STEPS

The integration of seamless is done in 5 steps:

seamless

1) IMPORTING THE SEAMLESS SDK

Before starting, you need to link the seamless SDK to your page. This is done in the head tag of your web page:

<head>

    <script src="https://cdn.cinetpay.com/seamless/main.js" type="text/javascript"></script>

</head>

2) CREATION OF THE FORM

The CinetPay payment form consists of the elements available in the sectionPAYMENT API. Click here

3) SETUP OF PARAMETERS

In order to invoke the counter, some elements are required to recognize the merchant:

  • apikey: The identifier of the merchant
  • site_id: The service identifier
  • close_after_response: Closes the counter automatically (Optional - true or false)
  • type: WEB or MOBILE (Optional - Default is WEB)
  • Notify_url: Valid payment notification URL
 CinetPay.setConfig({
    apikey: 'YOUR_API_KEY',
    site_id: YOUR_SITE_ID,
    mode: 'PRODUCTION',
    notify_url: 'https://mondomaine.com/notify/'
});

4) SENDING DATA

In order for the counter to load and be displayed to the buyer, all you have to do is pass the payment data to the SDK. In fact, on an action of the buyer, you will provide the data of the form :

CinetPay.getCheckout({
    transaction_id: 'YOUR_TRANSACTION_ID',
    amount: 100,
    currency: 'XOF',
    channels: 'ALL',
    description: 'YOUR_PAYMENT_DESCRIPTION'
});

5) CALLBACK

After each payment, the seamless allows you to observe the status of the transaction using the method CinetPay.waitResponse(function(data){})

The data parameter contains the data returned to the merchant in the integration after each payment:

  • amount: Amount paid,
  • currency: Currency,
  • status: Status of the transaction "ACCEPTED" or "REFUSED"
  • payment_method: Payment method
  • description: Description provided at initialization
  • metadata: Metadata provided at initialization,
  • operator_id: Operator identifier,
  • payment_date: Payment date
{
          "amount": "100", 
          "currency": "XOF", 
          "status": "ACCEPTED", 
          "payment_method": "FLOOZ", 
          "description": "Description", 
          "metadata": "ABIDJAN", 
          "operator_id": "8211027064102", 
         "payment_date": "2021-10-27 09:47:09"
}

Use the callback of the seamless to perform your different treatments (redirection, update, etc...):

   CinetPay.waitResponse(function(data) {
         // En cas d'échec
          if (data.status == "REFUSED") {
              if (alert("Votre paiement a échoué")) {
                  window.location.reload();
              }
          }
          // En cas de succès
          else if (data.status == "ACCEPTED") {
              if (alert("Votre paiement a été effectué avec succès")) {
                  // correct, on delivre le service
                  window.location.reload();
              }
          }
   });

6) CLOSE SEAMLESS

By default, the seamless popup contains a close button in the top right-hand corner, as shown in the image.👇

seamless


Please note:If you set the close_after_response parameter to true, the counter will be closed automatically after payment. The user will not be able to perform any other action on the counter ( Download receipt or contact support).

If you opt for automatic closure of the counter, make sure you manage the return after closure using the function: CinetPay.onClose(function(data){})


Example:

    // À l'écoute de la fermeture du guichet
    CinetPay.onClose(function(data) {
        if (data.status === "REFUSED") {
            // Afficher un message de paiement échec à l'utilisateur (Facultatif)
            alert("Votre paiement a échoué");
        } else if (data.status === "ACCEPTED") {
            // Afficher un message de paiement succès à l'utilisateur (Facultatif)
            alert("Votre paiement a été effectué avec succès");
        } else {
            // Afficher un message de fermeture du guichet (Facultatif)
            alert('Fermeture du guichet');
        }

        // Rafraichir la page après fermeture du guichet 
        // (Permet de recharger le Seamless pour un éventuel nouveau paiement)
        window.location.reload();
    });

7) PREPARATION DES PAGES DE NOTIFICATION

Why use a notification url?

Even if you configured the seamless callback correctly, don't forget that the notification URL is the only authorized mechanism for automatically synchronizing payments to your merchant site. CinetPay will call this link after each update to notify you of status changes while a transaction is in progress.

You can configure your notification url, following the model of sdk php


<?php 

if (isset($_POST['cpm_trans_id'])) {

    try {

        require_once __DIR__ . '/../src/new-guichet.php';
        require_once __DIR__ . '/../commande.php';
        require_once __DIR__ . '/../marchand.php';

        //Creation of a log file to ensure that the elements are executed correctly
        $log = "User: ".$_SERVER['REMOTE_ADDR'].' - '.date("F j, Y, g:i a").PHP_EOL.
        "TransId:".$_POST['cpm_trans_id'].PHP_EOL.
        "SiteId: ".$_POST['cpm_site_id'].PHP_EOL.
        "-------------------------".PHP_EOL;
        //Save string to log, use FILE_APPEND to append.
        file_put_contents('./log_'.date("d.n.Y").'.log', $log, FILE_APPEND);

        //The command class corresponds to your column that manages transactions in your database
        $command = new Commande();
        // CinetPay initialization and payment identification
        $transaction_id = $_POST['cpm_trans_id'];
        // apiKey
        $apikey = $marchand["apikey"];

        // siteId
        $site_id = $_POST['cpm_site_id'];

        $CinetPay = new CinetPay($site_id, $apikey);
        //We retrieve the status of the transaction in the database
        /* $command->set_transactionId($id_transaction);
             //Make sure the transaction exists in our database
         * $order->getOrderByTransId();
         */

        // We check that the order has not yet been processed
        $VerifyStatusCmd = "1"; // status value to retrieve from your database
        if ($VerifyStatusCmd == '00') {
            // The command has already been processed
            // Stop the script
            die();
        }

        // If not, check the status of the transaction in the event of a payment attempt on CinetPay

        $CinetPay->getPayStatus($id_transaction, $site_id);

        $amount = $CinetPay->chk_amount;
        $currency = $CinetPay->chk_currency;
        $message = $CinetPay->chk_message;
        $code = $CinetPay->chk_code;
        $metadata = $CinetPay->chk_metadata;

        //Something to write to txt log
        $log = "User: ".$_SERVER['REMOTE_ADDR'].' - '.date("F j, Y, g:i a").PHP_EOL.
            "Code:".$code.PHP_EOL.
            "Message: ".$message.PHP_EOL.
            "Amount: ".$amount.PHP_EOL.
            "currency: ".$currency.PHP_EOL.
            "-------------------------".PHP_EOL;
        //Save string to log, use FILE_APPEND to append.
        file_put_contents('./log_'.date("d.n.Y").'.log', $log, FILE_APPEND);

        // We check that the amount paid at CinetPay corresponds to our amount in the database for this transaction
        if ($code == '00') {
            // correct, we deliver the service
            echo 'Congratulations, your payment has been successfully completed';
            die();

        } else {
            // transaction is not valid
            echo 'Failed, your payment failed because: ' .$message;
            die();
        }
        // update transactions in the database
        /* $command->update(); */

    } catch(Exception $e) {
        echo "Error:" . $e->getMessage();
    }
} else {
    // direct access IPN
    echo "cpm_trans_id not provided";
}


SEAMLESS OVERVIEW

seamless


EXAMPLE OF INTEGRATION

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.cinetpay.com/seamless/main.js"></script>
    <style>
        .sdk {
            display: block;
            position: absolute;
            background-position: center;
            text-align: center;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }
    </style>
    <script>
        function checkout() {
            CinetPay.setConfig({
                apikey: '',//   YOUR APIKEY
                site_id: '',//YOUR_SITE_ID
                notify_url: 'http://mondomaine.com/notify/',
                mode: 'PRODUCTION'
            });
            CinetPay.getCheckout({
                transaction_id: Math.floor(Math.random() * 100000000).toString(),
                amount: 100,
                currency: 'XOF',
                channels: 'ALL',
                description: 'Test paiement',
                //Provide these variables for credit card payments
                customer_name:"Joe",//Customer name
                customer_surname:"Down",//The customer's first name
                customer_email: "down@test.com",//the customer's email
                customer_phone_number: "088767611",//the customer's email
                customer_address: "BP 0024",//customer address
                customer_city: "Antananarivo",// The customer's city
                customer_country: "CM",// the ISO code of the country
                customer_state: "CM",// the ISO state code
                customer_zip_code: "06510", // postcode
            });
            CinetPay.waitResponse(function(data) {
              if (data.status == "REFUSED") {
                if (alert("Your payment failed")) {
                  window.location.reload();
                }
              } else if (data.status == "ACCEPTED") {
                if (alert("Your payment has been made successfully")) {
                  window.location.reload();
                }
              }
            });
            CinetPay.onError(function(data) {
                console.log(data);
            });
        }
    </script>
</head>
<body>
    </head>
    <body>
        <div class="sdk">
            <h1>SDK SEAMLESS</h1>
            <button onclick="checkout()">Checkout</button>
        </div>
    </body>
</html>  

Error Status

Code Cause Solution
Code: 403 Cloudflare restriction caused by the network or an error in the request please change your network
The payment counter loads indefinitely There is an error in the query In the console, you will find the cause of the error
The "pay" button submission redirects to the CinetPay website The issues encountered are due to Apple's security measures;
an update has been initiated in which the "Prevent cross-site tracking" system on Safari browsers destroys cookies contained in popups.
To fix this, simply uncheck the Prevent cross-site tracking option on the browser.