CinetPay SDK Android

Etape 1

Pré-requis

Vous devez avoir un compte et un service valide sur CinetPay
Sinon, Veuillez Créer votre compte et votre premier service marchand.
Une fois cela fait, vous devez récupérer votre APIKEY et votre SITE ID dans votre interface une fois connecté avant de continuer votre intégration.

Vous êtes prêts ? c'est parti !

Etape 2

Si votre service ne neccessite pas un traitement des notifications de paiement de CinetPay, vous pouvez passer directement à l'etape 3, par exemple les services de don.
Page de notification

A chaque paiement, CinetPay vous notifie via un lien de notification, nous vous conseillons de toujours le traiter côté serveur. Nous allons utiliser PHP dans ce cas de figure : Script index.php dans http://mondomaine.com/notify/ (le script doit se trouver dans le repertoire de votre url notify_url) ;


    <?php
    if (isset($_POST['cpm_trans_id'])) {
        // SDK PHP de CinetPay
        require_once __DIR__ . '/cinetPay.php';
        require_once __DIR__ . '/commande.php';

        //La classe commande correspond à votre colonne qui gère les transactions dans votre base de données
        $commande = new Commande();
        try {
            // Initialisation de CinetPay et Identification du paiement
            $id_transaction = $_POST['cpm_trans_id'];
            $apiKey = _VOTRE_APIKEY_;
            $site_id = _VOTRE_SITEID_;
            $plateform = "TEST"; // Valorisé à PROD si vous êtes en production
            $CinetPay = new CinetPay($site_id, $apiKey, $plateform);
            // Reprise exacte des bonnes données chez CinetPay
            $CinetPay->setTransId($id_transaction)->getPayStatus();
            $cpm_site_id = $CinetPay->_cpm_site_id;
            $signature = $CinetPay->_signature;
            $cpm_amount = $CinetPay->_cpm_amount;
            $cpm_trans_id = $CinetPay->_cpm_trans_id;
            $cpm_custom = $CinetPay->_cpm_custom;
            $cpm_currency = $CinetPay->_cpm_currency;
            $cpm_payid = $CinetPay->_cpm_payid;
            $cpm_payment_date = $CinetPay->_cpm_payment_date;
            $cpm_payment_time = $CinetPay->_cpm_payment_time;
            $cpm_error_message = $CinetPay->_cpm_error_message;
            $payment_method = $CinetPay->_payment_method;
            $cpm_phone_prefixe = $CinetPay->_cpm_phone_prefixe;
            $cel_phone_num = $CinetPay->_cel_phone_num;
            $cpm_ipn_ack = $CinetPay->_cpm_ipn_ack;
            $created_at = $CinetPay->_created_at;
            $updated_at = $CinetPay->_updated_at;
            $cpm_result = $CinetPay->_cpm_result;
            $cpm_trans_status = $CinetPay->_cpm_trans_status;
            $cpm_designation = $CinetPay->_cpm_designation;
            $buyer_name = $CinetPay->_buyer_name;

            // Recuperation de la ligne de la transaction dans votre base de données
            $commande->setTransId($id_transaction);
            $commande->getCommandeByTransId();
            // Verification de l'etat du traitement de la commande
            if ($commande->getStatut() == '00') {
                // La commande a été déjà traité
                // Arret du script
                die();
            }
            // Dans le cas contrait, on remplit notre ligne des nouvelles données acquise en cas de tentative de paiement sur CinetPay
            $commande->setMethode($payment_method);
            $commande->setPayId($cpm_payid);
            $commande->setBuyerName($buyer_name);
            $commande->setSignature($signature);
            $commande->setPhone($cel_phone_num);
            $commande->setDatePaiement($cpm_payment_date . ' ' . $cpm_payment_time);

            // On verifie que le montant payé chez CinetPay correspond à notre montant en base de données pour cette transaction
            if ($commande->getMontant() == $cpm_amount) {
                // C'est OK : On continue le remplissage des nouvelles données
                $commande->setErrorMessage($cpm_error_message);
                $commande->setStatut($cpm_result);
                $commande->setTransStatus($cpm_trans_status);
                if($cpm_result == '00'){
                    //Le paiement est bon
                    // Traitez et delivrez le service au client
                }else{
                    //Le paiement a échoué
                }
            } else {
                //Fraude : montant payé ' . $cpm_amount . ' ne correspond pas au montant de la commande
                $commande->setStatut('-1');
                $commande->setTransStatus('REFUSED');
            }
            // On met à jour notre ligne
            $commande->update();
        } catch (Exception $e) {
            echo "Erreur :" . $e->getMessage();
            // Une erreur s'est produite
        }
    } else {
        // Tentative d'accès direct au lien IPN
    }
    ?>

Etape 3

Intégration de la librairie

Ajoutez la librairie comme dépendance dans votre fichier build.gradle


    dependencies {
        implementation 'com.cinetpay:sdkjs:2.0.0'
    }

Configuration de l’interface de paiement

Avant de pouvoir faire fonctionner les paiements, vous devez spécifier les paramètres de votre compte marchand (clé API, site ID, URL de notification) et définir une interface entre votre application et CinetPay. Cette interface permet de communiquer à CinetPay les informations de chaque paiement (montant, devise, ID de la transaction...) qu’un utilisateur s’apprête à effectuer.

Pour ce faire, créez une classe qui hérite de la classe CinetPayWebAppInterface.
Un exemple ci-dessous:


    public class MyCinetPayWebAppInterface extends CinetPayWebAppInterface {

        public MyCinetPayWebAppInterface(Context c, String api_key, int site_id, String notify_url, String trans_id, int amount, String currency, String designation, String custom, boolean should_check_payment) {
            super(c, api_key, site_id, notify_url, trans_id, amount, currency, designation, custom, boolean should_check_payment);
        }

        @Override
        @JavascriptInterface
        public void onPaymentCompleted(String payment_info) {
        }

        @Override
        @JavascriptInterface
        public void onError(String code, String message) {
        }

        @Override
        @JavascriptInterface
        public void terminatePending(String apikey, int cpm_site_id, String cpm_trans_id) {
        }

        @Override
        @JavascriptInterface
        public void terminateSuccess(String payment_info) {
        }

        @Override
        @JavascriptInterface
        public void terminateFailed(String apikey, int cpm_site_id, String cpm_trans_id) {
        }

        @Override
        @JavascriptInterface
        public void checkPayment(String apikey, int cpm_site_id, String cpm_trans_id) {
        }
    }

Cette classe contient des méthodes qui sont déclenchées en fonction de certains événements:
onPaymentCompleted: S'exécute lorsque le paiement est terminé. Elle prend en paramètre une chaîne de caractères au format JSON qui contient toutes les informations concernant le paiement effectué.

La structure de la chaîne se présente ainsi:


    {
        "cpm_site_id": "",
        "signature": "",
        "cpm_amount": "",
        "cpm_trans_date": "",
        "cpm_trans_id": "",
        "cpm_custom": "",
        "cpm_currency": "",
        "cpm_payid": "",
        "cpm_payment_date": "",
        "cpm_payment_time": "",
        "cpm_error_message": "",
        "payment_method": "",
        "cpm_phone_prefixe": "",
        "cel_phone_num": "",
        "cpm_ipn_ack": "",
        "created_at": "",
        "updated_at": "",
        "cpm_result": "",
        "cpm_trans_status": "",
        "cpm_designation": "",
        "buyer_name": ""
    }


onError: S'exécute lorsqu'une erreur survient. Elle prend en paramètres le code et le message de l’erreur.

terminatePending: S'exécute lorsque l'utilisateur appuie sur le bouton Annuler après avoir initié un paiement sans valider (la validation dont on parle ici est le fait de saisir son code secret sur ton téléphone lors de la dernière étape du paiement, dans le cas de MTN et Moov). Le bouton Annuler s'affiche lorsque l'utilisateur clique sur Fermer dans la fenêtre de paiement CinetPay. La méthode prend en paramètres: apikey (votre clé API), cpm_site_id (votre site ID), cpm_trans_id (l'ID de transaction que vous avez généré pour le paiement en question). Ces paramètres vous sont transmis pour vous permettre de vérifier le statut final du paiement car l'utilisateur peut confirmer le paiement après avoir quitté la fenêtre de paiement de CinetPay. Pour vérifier le statut final du paiement, vous devez envoyer par POST les paramètres suivants: apikey, cpm_site_id et cpm_trans_id à cette URL: https://api.cinetpay.com/v1/?method=checkPayStatus.

terminateSuccess: S'exécute lorsque l'utilisateur appuie sur le bouton Terminer. Le bouton Terminer s'affiche lorsque l'utilisateur clique sur Fermer dans la fenêtre de paiement CinetPay après avoir effectué son paiement. La méthode prend en paramètre une chaîne de caractères au format JSON qui contient toutes les informations concernant le paiement effectué, la même que celle dans onPaymentCompleted.

terminateFailed: S'exécute lorsque l'utilisateur appuie sur le bouton Terminer après une erreur survenue. Le bouton Terminer s'affiche lorsque l'utilisateur clique sur Fermer dans la fenêtre de paiement CinetPay. La méthode prend en paramètres: apikey (votre clé API), cpm_site_id (votre site ID), cpm_trans_id (l'ID de transaction que vous avez généré pour le paiement en question). Ces paramètres vous sont transmis pour vous permettre de vérifier le statut final du paiement. Pour vérifier le statut final du paiement, vous devez envoyer par POST les paramètres suivants: apikey, cpm_site_id et cpm_trans_id à cette URL: https://api.cinetpay.com/v1/?method=checkPayStatus.

checkPayment: S'exécute lorsque l'utilisateur clique sur le bouton Vérifier le paiement. Le bouton Vérifier le paiement s'affiche (si vous avez mis le paramètre should_check_payment à true à l'instanciation de votre classe qui hérite de CinetPayWebAppInterface) lorsque l'utilisateur clique sur Fermer dans la fenêtre de paiement CinetPay après avoir initié un paiement sans valider (la validation dont on parle ici est le fait de saisir son code secret sur ton téléphone lors de la dernière étape du paiement, dans le cas de MTN et Moov). La méthode prend en paramètres: apikey (votre clé API), cpm_site_id (votre site ID), cpm_trans_id (l'ID de transaction que vous avez généré pour le paiement en question). Pour vérifier le statut final du paiement, vous devez envoyer par POST les paramètres suivants: apikey, cpm_site_id et cpm_trans_id à cette URL: https://api.cinetpay.com/v1/?method=checkPayStatus.


    try {
        JSONObject paymentInfo = new JSONObject(payment_info);

        String cpm_result = paymentInfo.getString("cpm_result");
        String cpm_trans_status = paymentInfo.getString("cpm_trans_status");
        String cpm_error_message = paymentInfo.getString("cpm_error_message");
        String cpm_custom = paymentInfo.getString("cpm_custom");

    } catch (JSONException e) {
        e.printStackTrace();
    }


Affichage de la page de paiement de CinetPay

Après avoir défini le processus de paiement, vous pouvez maintenant rediriger l’utilisateur vers la page de paiement de CinetPay. Vous devez d’abord créer une Activity qui hérite de CinetPayActivity:


    public class MyCinetPayActivity extends CinetPayActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    }

Après avoir défini le processus de paiement, vous pouvez maintenant rediriger l’utilisateur vers la page de paiement de CinetPay. Vous devez d’abord créer une Activity qui hérite de CinetPayActivity:AndroidManifest.xml:


    <activity android:name=".MyCinetPayActivity" />

Assurez-vous de l’ajouter dans le fichier

Etape 4

Assurez-vous de l’ajouter dans le fichier

A chaque paiement, CinetPay vous notifie via un lien de notification, nous vous conseillons de toujours le traiter côté serveur. Nous allons utiliser PHP dans ce cas de figure : Script index.php dans http://mondomaine.com/notify/ (le script doit se trouver dans le repertoire de votre url notify_url) ;


    String api_key = "MY_API_KEY"; // A remplacer par votre clé API
    int site_id = 0; // A remplacer par votre Site ID
    String notify_url = "";
    String trans_id = String.valueOf(new Date().getTime());
    int amount = 100 ;
    String currency = "CFA";
    String designation = "Achat test";
    String custom = "";

    Intent intent = new Intent(MainActivity.this,MyCinetPayActivity.class);
    intent.putExtra(CinetPayActivity.KEY_API_KEY, api_key);
    intent.putExtra(CinetPayActivity.KEY_SITE_ID, site_id);
    intent.putExtra(CinetPayActivity.KEY_NOTIFY_URL, notify_url);
    intent.putExtra(CinetPayActivity.KEY_TRANS_ID, trans_id);
    intent.putExtra(CinetPayActivity.KEY_AMOUNT, amount);
    intent.putExtra(CinetPayActivity.KEY_CURRENCY, currency);
    intent.putExtra(CinetPayActivity.KEY_DESIGNATION, designation);
    intent.putExtra(CinetPayActivity.KEY_CUSTOM, custom);
    startActivity(intent);

Enfin, vous devez récupérer ces paramètres dans votre Activity préalablement créée (MyCInetPayActivity ici) et les passer à la classe qui hérite de CinetPayWebAppInterface (MyCinetPayWebAppInterface ici).


    public class MyCinetPayActivity extends CinetPayActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            Intent intent = getIntent();

            String api_key = intent.getStringExtra(KEY_API_KEY);
            int site_id = intent.getIntExtra(KEY_SITE_ID, 0);
            String notify_url = intent.getStringExtra(KEY_NOTIFY_URL);
            String trans_id = intent.getStringExtra(KEY_TRANS_ID);
            int amount = intent.getIntExtra(KEY_AMOUNT, 0);
            String currency = intent.getStringExtra(KEY_CURRENCY);
            String designation = intent.getStringExtra(KEY_DESIGNATION);
            String custom = intent.getStringExtra(KEY_CUSTOM);

            mWebView.addJavascriptInterface(new MyCinetPayWebAppInterface(this, api_key, site_id, notify_url, trans_id, amount, currency, designation, custom, true), "Android");
        }
    }

Le mWebView vient de CinetPayActivity. Vous y avez accès parce que votre Activity hérite de CinetPayActivity. Notez que vous ne devez pas définir de layout pour MyCinetPayActivity.

Exemple