Developers

Developers2020-03-23T21:25:32+01:00

Developer’s Hub

We make it easy for developers to integrate with our API. We remove unnecessary complexity and irrelevant details so you can get up and running with QoS in just minutes!

Create Account
Documentation
MoMo USSD Flow

Code Examples

Download Link

Description

QOS Payment Gateway allows businesses to safely receive payments by Mobile Money.

ACCEPT MOBILE MONEY YOUR STORE

The QOS Payment Gateway plugin extends WooCommerce allowing you to make payments directly on your store.

QOS Payment Gateway is available in:

  • Benin

QOS Payment Gateway is developer friendly solution that allows you to accept mobile money payments in your application or website. Before using this plugin, make sure you have a right Account on QOS, otherwise go and create your account.

WHY CHOOSE QOS PAYMENT GATEWAY?

QOS WooCommerce Payment Gateway is an easy tool that allows you to accept payments on your WooCommerce store using Mobile Money.


Installation

AUTOMATIC INSTALLATION

Automatic installation is the easiest option as WordPress handles the file transfers itself and you don’t need to leave your web browser.
To do an automatic installation, log in to your WordPress dashboard, navigate to the Plugins menu and click Add New.

In the search field type “QOS WooCommerce Payment Gateway” and click Search Plugin. Once you’ve found our plugin you can view details about it such as the point release, rating and description. Most importantly of course, you can install it by simply clicking “Install Now”.

MANUAL INSTALLATION

The manual installation method involves downloading our plugin and uploading it to your web server via your favorite FTP application. The WordPress codex contains instructions on how to do it here.

UPDATING

Automatic updates should work like a charm; as always though, ensure you backup your website just in case.

This document is intended to help implement Qos checkout in a web project. Click here to Download Code.

Implementation:

1. Include the file momo.bundle.js in your project

2. Create a div tag at the location where you want to use the API (with a unique id ex: id= “momo”)

3. To display the form on page, create the new instance for MomoControler class, see example

Ex: `var instance = new MomoControler(idDiv,clientId,username,passeword,montant,option)`

4. The following describes the important element required to be sent for display form.

Data

Element(DE)

type, M/O Example/Description
1 idDiv string

(MANDATORY)

new MomoControler(“momo”…
2 clientId string

(MANDATORY)

…(“momo”,”UBN8”…
3 username string

(MANDATORY)

…”UBN8”,myuser”…
4 password string

(MANDATORY)

…”myuser”,”password”…
5 montant décimale

(MANDATORY)

…”password”,amount”

6 option objet(OPTIONAL) …”amount”,{}”)
7 option.baseDirectory String(MANDATORY) ‘./momo’
8 option.pathImage Business string (OPTIONAL) path for business logo to display
9 option.textIntro string(optional) custom the header text

Process

  1. Recover momo.rar and dezipped

2.1 Open the page on which you want to integrate momo

2.2 Import the file momo.bundle.js into this page

2.3. Create a div at the location where the form will appear

2.4. Create a function and a button that calls your function as follows:

2.5. As soon as your function is called, start your momo Qos as follows:

NB:

  • Copy to the same folder or import the api file momo.bundle.js these two files

  • at this parameter, enter the path of the folder in which the momo.rar file is unzip: {‘baseDirectory’: ‘./momo’}

Request Payment

Code is also available on GitHub

  session_start();
 header("Access-Control-Allow-Origin: *");
		$message=array();
		$message['msisdn']=$_POST['msisdn'];
		$message['amount']=$_POST['amount'];
		$message['firstname']=$_POST['firstname'];
		$message['lastname']=$_POST['lastname'];
		$message['transref']=time();
		$message['clientid']=$_POST['clientid']; 
      $message['comment']="null";
		$context  = "http://example_url_or_ip";  
		$username = "user";  
		$password = "password";  
 
//////////////////////////////////////////////////////////
		function callAPI($method, $url, $data){
   $curl = curl_init();
   switch ($method){
      case "POST":
         curl_setopt($curl, CURLOPT_POST, 1);
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
         break;
      case "PUT":
         curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);                         
         break;
      default:
         if ($data)
            $url = sprintf("%s?%s", $url, http_build_query($data));
   }
   // OPTIONS:
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_HTTPHEADER, array(
      //'APIKEY: 111111111111111111111',
      'Content-Type: application/json',
      'Authorization: Basic '. base64_encode("$username:$password")
   ));
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
   // EXECUTE:
   $result = curl_exec($curl);
   if(!$result){die("Connection Failure");}
   curl_close($curl);
   return $result;
}
////////////////////////////////////////////////////////////////////////////////
 $make_call = callAPI(
	'POST',
 	"$context/QosicBridge/user/requestpayment",
	json_encode($message)
 	);

 $response = json_decode($make_call, true);
/////////////////////////////////////////////////////////////////

  $_SESSION['transref']=$response['transref'];
  $_SESSION['clientid']=$message['clientid'];

Get Later Response

session_start();
 header("Access-Control-Allow-Origin: *");
		$message=array();
		$message['transref']=$_SESSION['transref'];
      $message['clientid']=$_SESSION['clientid'];
      $context  = "http://example_url_or_ip";  
		$username = "user";  
		$password = "password"; 
   
		/////////////////////////////////////////////////////////
		function callAPI($method, $url, $data){
   $curl = curl_init();
   switch ($method){
      case "POST":
         curl_setopt($curl, CURLOPT_POST, 1);
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
         break;
      case "PUT":
         curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);                         
         break;
      default:
         if ($data)
            $url = sprintf("%s?%s", $url, http_build_query($data));
   }
   // OPTIONS:
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_HTTPHEADER, array(
      
      'Content-Type: application/json',
      'Authorization: Basic '. base64_encode("$username:$password")
   ));
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
   // EXECUTE:
   $result = curl_exec($curl);
   if(!$result){die("Connection Failure");}
   curl_close($curl);
   return $result;
}
///////////////////////////////////////////////////////////////////////////////////////////////
$make_call = callAPI(
	'POST',
	  "$context/api/web/QosicBridge/user/gettransactionstatus",
    // "$context/QosicBridge/user/gettransactionstatus",
	json_encode($message)
	);
$response = json_decode($make_call, true);
/////////////////////////////////////////////////////////////////////////////////////////

if($response['responsecode']==01){
		echo "Pending";}
elseif($response['responsecode']==00){
		echo "success";}
else {
		echo "Failed ";
}

Python Django: Initiate Transaction Process

View The complete index.html file on Github

def api(request):
    context = {  
        'status':"info",
        'text':"Not Set",
        'code':"Neutral",
    }
    return render(request, 'index.html',context)
def post(request):
    if request.method == "POST":
        #keys
		context = 'http://ip_link'
        headers = {'content-type':'application/json'}
        url = context + '/QosicBridge/user/requestpayment'
		raw_url = url;
        msisdn = request.POST['msisdn']
        amount = request.POST['amount']
        firstname = request.POST['firstname']
        lastname = request.POST['lastname']
        clientid = request.POST['clientid']
        transref = (randint(1000000, 9999999))##integer
        transref_str = str(transref) ##to string
        server_pass = 'server_pass'
        server_user = 'server_user'
        url = context +"/QosicBridge/user/requestpayment?msisdn="+msisdn+"&amount="+amount+"&firstname="+firstname+"&lastname="+lastname+"&transref="+transref_str+"&ClientID="+clientid
        data = json.dumps({
            "msisdn": msisdn,
            "amount": amount,
            "firstname":firstname,
            "lastname":lastname,
            "transref" :transref,
            "clientid": clientid,
            })
            
        # return HttpResponse(str(url)) ###--##TEST##--##
        
        r = requests.post(url, auth=(server_user, server_pass), headers=headers, data=data,timeout=20)
        # //load the json to a string
        resp = json.loads(r.text)
        
        # return HttpResponse(str(resp['transref']))
        if r.status_code == 200:
                data = r.json() ##response from server
                # return HttpResponse(str(url))
                # return HttpResponse(pprint(data))#console
                # return HttpResponse(print(data)) #console
                context = {  
                    'status':"success",
                    'text':'Status is OKAY',
                    'code':r.status_code,
                    'responsecode':resp['responsecode'],
                    'responsemsg':resp['responsemsg'],
                    'transref':resp['transref'],
                    'comment':resp['comment']+', '+clientid,
                    'clientid':clientid,
					
					'server_link':raw_url,
					'server_user':server_user,
					'server_pass':server_pass,
                }
                return render(request, 'index.html',context)
        elif r.status_code == 202:
                context = {  
                    'status':"success",
                    'text':"

Expires in <span id="time">05:00</span>

Check Your Phone; Awaiting Confirmation

<i class="fa fa-spinner fa-spin" style="font-size: 60px;"></i>",
                    'code':r.status_code,
                    'responsecode':resp['responsecode'],
                    'responsemsg':resp['responsemsg'],
                    'transref':resp['transref'],
                    'comment':resp['comment'],
                    'clientid':clientid,
                }
                return render(request, 'index.html',context)
        elif r.status_code == 401:
                context = {  
                    'status':"danger",
                    'text':'Unauthorized',
                    'code':r.status_code,
                    'responsecode':resp['responsecode'],
                    'responsemsg':resp['responsemsg'],
                    'transref':resp['transref'],
                    'comment':resp['comment'],
                }
                return render(request, 'index.html',context)
        else:
                context = {  
                    'status':"danger",
                    'text':'Failed',
                    'code':r.status_code,
                    'responsecode':resp['responsecode'],
                    'responsemsg':resp['responsemsg'],
                    'transref':resp['transref'],
                    'comment':resp['comment'],
                }
                # return JsonResponse({'error': 'Some error'}, status=400)
                return render(request, 'index.html',context)
    else:
                context = {  
                    'status':"warning",
                    'text':'Invalid Method;',
                    'code':"-",
                    'responsecode':'-',
                    'responsemsg':'-',
                    'transref':'-',
                    'comment':'-',
                }
                return render(request, 'index.html',context)

Ajax Call: to Server every 5 seconds until transaction is approved or expires in 5 minutes

//add starting script tag here
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
      var responseText = xhr.responseText;
      console.log(responseText);
      // process the response.
     };


  $('#response').show();
  $('#spinner').show();
  $('#success').hide();
//add closing script tag here

//add starting script tag here
var token = '{{csrf_token}}';
  var c_i = 0;
  function executeQuery() {
    c_i++;
    console.log(c_i+ " Run")

  $.ajax({
    type: 'POST',
    //type: 'GET',
    dataType: 'json',
    crossDomain: true,
    headers:{
      "Authorization": "Basic " + btoa("{{server_user}}" + ":" + "{{server_pass}}"),
      "X-CSRFToken": token,
      "accept": "application/json",
      "Access-Control-Allow-Origin":"*"
    },
    contentType:"application/json; charset=utf-8",
    //beforeSend: function (xhr) {
    //  xhr.setRequestHeader ("Authorization", "Basic " + btoa("{{server_user}}" + ":" + "{{server_pass}}"));
  //},
    data: JSON.stringify({
      transref: "{{transref}}",
      clientid: "{{clientid}}", 
    }),
   url: "{{server_link}}/QosicBridge/user/gettransactionstatus",
    success: function(data,jqXHR, textStatus) {
      if (textStatus.status == 200) {
        var json = data;
        //console.log(json)
        console.log(json.responsemsg +' '+ json.responsecode)
        if (json.responsecode == 00) {
          $('#response').hide();
          $('#spinner').hide();
          $('#success').show();
        }
        //console.log(JSON.parse(this.responseText));
        
      ///////////////////////////////////////////////
        }
      //console.log(textStatus.status)
    },
    error: function(jqXHR, textStatus, errorThrown) {
      console.log(textStatus, errorThrown);
    }
    

  });
  
  if(c_i < 60){ // to run 60 times thats 5 mins
    setTimeout(executeQuery, 5000); // you could choose not to continue on failure...
  }
  
}

$(document).ready(function() { 
  setTimeout(executeQuery, 5000);// run the first time;
});




  function startTimer(duration, display) {
      var timer = duration, minutes, seconds;
      var end =setInterval(function () {
          minutes = parseInt(timer / 60, 10)
          seconds = parseInt(timer % 60, 10);

          minutes = minutes < 10 ? "0" + minutes : minutes;
          seconds = seconds < 10 ? "0" + seconds : seconds;

          display.textContent = minutes + ":" + seconds;

          if (--timer < 0) {
              //Do somthing on timeout
              $('#response').hide();
              $('#spinner').hide();
              clearInterval(end);
          }
      }, 1000);
  }

  window.onload = function () {
      var fiveMinutes = 300,
          display = document.querySelector('#time');
      startTimer(fiveMinutes, display);
  };
//add closing script tag here
Install Guzzle first

//web.php
// Route::get('/',[
//     'uses'=>'ApiController@index',
//     'as'=>'index'
// ]);

// Route::get('/get_status',[
//     'uses'=>'ApiController@get_status',
//     'as'=>'get_status'
// ]);
//web.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Goutte\Clients;
class ApiController extends Controller
{
    public function index(Request $request)
    {
       
        //testing 
        $context = 'ip_address';
        $url = $context .'/QosicBridge/user/requestpayment';
        $msisdn = "123456789";
        $amount = "350";
        $firstname = "John";
        $lastname = "Wick";
        $clientid = 'client_id';
        $transref = str_random(20);
        $server_user = 'server_user';
        $server_pass = 'server_pass';
        $data = array(
            "msisdn"=> $msisdn,
            "amount"=> $amount,
            "firstname"=>$firstname,
            "lastname"=>$lastname,
            "transref" =>$transref,
            "clientid"=> $clientid,
        ); 
        
        $client = new \GuzzleHttp\Client(['headers' => ['content-type' => 'application/json']]);
        $response = $client->request('POST', $url, [
            'auth' => [$server_user, $server_pass],
            'json' => $data,
        ]); 
        ///////////DUMPS///////////
        dump("Request Transaction");
        dump($data);
        dump("Status Code: " .$response->getStatusCode());
        $response = $response->getBody()->getContents();
        dump ($response);
        dump (json_decode($response));
        $response = json_decode($response);//json proper
        dump("Response: ".$response->responsecode);
        dump("Responsemsg: ".$response->responsemsg);
        dump("Transref: ".$response->transref);
        dump("Comment: ".$response->comment);
        return dd('-------------------');
    }
    
    public function get_status()
    {
        $context = 'ip_address';
        $url = $context .'/QosicBridge/user/gettransactionstatus';
        $clientid = 'UBHQ';
        $transref = "5P5fU2GYDJnltqH";// transaction ref
        $server_user = 'server_user';
        $server_pass = 'server_pass';
        $data = array(
            "transref" =>$transref,
            "clientid"=> $clientid,
        ); 
        $client = new \GuzzleHttp\Client(['headers' => ['content-type' => 'application/json']]);
        $response = $client->request('POST', $url, [
            'auth' => [$server_user, $server_pass],
            'json' => $data,
        ]); 
        dump("Get Transaction Status");
        dump($data);
        dump("Status Code: " .$response->getStatusCode());
        $response = $response->getBody()->getContents();
        dump ($response);
        dump (json_decode($response));
        $response = json_decode($response);//json proper
        dump("Response: ".$response->responsecode);
        dump("Responsemsg: ".$response->responsemsg);
        dump("Transref: ".$response->transref);
        dump("Comment: ".$response->comment);
        return dd('-------------');
        
    }
}