Encaisser un paiement

L'encaissement permet à vos clients de vous payer par Mobile Money via une page sécurisée Tchin. Le parcours se résume en 4 temps :

  1. Créer le paiement — votre serveur appelle l'API et reçoit une payment_url.
  2. Rediriger le client vers cette page de paiement.
  3. Le client choisit son pays, son opérateur, saisit son numéro et paie.
  4. Confirmation — le client est renvoyé directement sur votre site, et Tchin notifie votre callback_url (webhook = source de vérité).

Endpoint

POST /api/v1/payments

ChampTypeRequisDescription
amountentierouiMontant en FCFA (XOF), min 100.
descriptiontextenonLibellé affiché au client (max 255).
envtextenontest (défaut) ou live.
return_urlURLnonPage du marchand où renvoyer le client. Si absent, retour automatique sur la page d'origine.
cancel_urlURLnonPage de retour en cas d'annulation. Défaut : return_url.
callback_urlURLnonWebhook de notification. Défaut : celui de l'app.

Requête (cURL)

cURL
curl -X POST https://tchin.tech/api/v1/payments \
  -H "TCHIN-PUBLIC-KEY: tchin_pk_xxxxxxxx" \
  -H "TCHIN-PRIVATE-KEY: tchin_sk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "amount": 5000,
        "description": "Commande #1024",
        "env": "test",
        "return_url": "https://monsite.com/merci",
        "callback_url": "https://monsite.com/tchin/webhook"
      }'

Réponse

JSON
{
  "success": true,
  "token": "a1b2c3d4e5f6",
  "payment_url": "https://tchin.tech/pay/a1b2c3d4e5f6",
  "env": "test"
}
ChampDescription
tokenRéférence unique du paiement. Mémorisez-la avec votre commande.
payment_urlPage de paiement vers laquelle rediriger le client.

Exemples par langage

PHP

PHP
<?php
function tchin_post($path, $body) {
    $ch = curl_init('https://tchin.tech/api/v1/'.$path);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_HTTPHEADER     => [
            'TCHIN-PUBLIC-KEY: '.getenv('TCHIN_PUBLIC_KEY'),
            'TCHIN-PRIVATE-KEY: '.getenv('TCHIN_SECRET_KEY'),
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode($body),
    ]);
    $res = json_decode(curl_exec($ch), true);
    curl_close($ch);
    return $res;
}

// 1) Créer le paiement (côté serveur)
$res = tchin_post('payments', [
    'amount'       => 5000,                         // FCFA (XOF), entier
    'description'  => 'Commande #1024',
    'env'          => 'live',                       // ou "test"
    'return_url'   => 'https://monsite.com/merci',
    'callback_url' => 'https://monsite.com/tchin/webhook',
]);

// 2) Mémoriser $res['token'] avec votre commande, puis rediriger le client
header('Location: '.$res['payment_url']);
exit;

Node.js

JavaScript
// Node.js / Express
import express from 'express';
const app = express();

app.post('/payer', async (req, res) => {
  const r = await fetch('https://tchin.tech/api/v1/payments', {
    method: 'POST',
    headers: {
      'TCHIN-PUBLIC-KEY': process.env.TCHIN_PUBLIC_KEY,
      'TCHIN-PRIVATE-KEY': process.env.TCHIN_SECRET_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      amount: 5000,
      description: 'Commande #1024',
      env: 'live',
      return_url: 'https://monsite.com/merci',
      callback_url: 'https://monsite.com/webhook',
    }),
  });
  const data = await r.json();
  res.redirect(data.payment_url);   // on envoie le client payer
});

Python

Python
# Python (requests)
import os, requests

r = requests.post('https://tchin.tech/api/v1/payments',
    headers={
        'TCHIN-PUBLIC-KEY': os.environ['TCHIN_PUBLIC_KEY'],
        'TCHIN-PRIVATE-KEY': os.environ['TCHIN_SECRET_KEY'],
    },
    json={
        'amount': 5000,
        'description': 'Commande #1024',
        'env': 'live',
        'return_url': 'https://monsite.com/merci',
        'callback_url': 'https://monsite.com/webhook',
    })
data = r.json()
payment_url = data['payment_url']   # rediriger le client vers cette URL

Rediriger le client

Après réception de la payment_url, redirigez le navigateur du client dessus (réponse HTTP 302, ou un simple lien/bouton). Le client effectue tout le paiement sur la page Tchin (choix opérateur, OTP, etc.) — vous n'avez rien d'autre à coder côté paiement.

Où définir le retour et le webhook ?

Deux endroits, selon vos besoins :

  • À la création de l'application (menu API → champ « URL Webhook ») : cette URL est le callback_url par défaut de tous les paiements de l'app.
  • À chaque paiement (POST /api/v1/payments) : vous fournissez return_url et, si besoin, callback_url pour CE paiement (il remplace alors celui de l'app). Les deux sont optionnels.

Le retour du client

Une fois le paiement terminé (réussi ou annulé), Tchin n'affiche aucune page de remerciement : le client est renvoyé directement sur votre site, là où il se trouvait avant d'être redirigé — comme toute passerelle de paiement.

  • Si vous avez fourni return_url (et au besoin cancel_url), le client y est renvoyé.
  • Sinon, Tchin le ramène automatiquement sur la page d'origine. Vous n'avez donc, le plus souvent, rien à définir.

Tchin ajoute deux paramètres à l'URL de retour :

ParamètreValeur
statussuccess (payé) ou cancel (annulé par le client).
tokenLa référence du paiement (identique à celle reçue à la création).

Exemple : https://votre-site.com/panier?status=success&token=ab12cd34ef

PHP — votre page de retour (optionnel)
<?php
// Votre page return_url, appelée quand le client revient du paiement
$status = $_GET['status'] ?? null;

if ($status === 'success') {
    // Afficher un écran "Merci".
    // NB : validez/livrez la commande UNIQUEMENT via le webhook (source de vérité).
} elseif ($status === 'cancel') {
    // Le client a annulé : afficher "Paiement annulé".
}

⚠️ Le retour client sert uniquement à l'affichage : le client peut fermer son navigateur avant d'y revenir. Pour valider et livrer une commande, fiez-vous toujours au webhook.

La notification serveur (callback_url / webhook)

Dès que le paiement est confirmé, Tchin envoie une requête POST à votre callback_url (ou au webhook de l'app). C'est la source de vérité : c'est là que vous marquez la commande payée. Détails et exemples sur la page Webhooks.

Applications mobiles (Android, iOS, Flutter…)

Le principe est identique aux sites web. Ne mettez jamais la clé secrète dans l'application : créez le paiement depuis votre backend, renvoyez la payment_url à l'app, puis ouvrez-la :

  • Android — Chrome Custom Tabs (recommandé) ou une WebView.
  • iOSSFSafariViewController / ASWebAuthenticationSession ou une WKWebView.
  • Flutterflutter_web_auth_2, url_launcher ou webview_flutter.

Pour récupérer le client dans l'app, utilisez un deep link / lien universel comme return_url (ex. monapp://retour). L'app détecte ce retour et affiche l'écran adéquat ; la commande, elle, est confirmée par le webhook reçu sur votre serveur.

Kotlin — Android (Custom Tabs)
// 1) Votre BACKEND crée le paiement et renvoie payment_url à l'app.
// 2) L'app ouvre la page de paiement (Chrome Custom Tabs) :
val intent = CustomTabsIntent.Builder().build()
intent.launchUrl(context, Uri.parse(paymentUrl))

// 3) Le client revient via votre deep link (return_url, ex: monapp://retour).
// La commande est confirmée par le WEBHOOK reçu sur votre serveur.
Swift — iOS
import SafariServices

// payment_url provient de VOTRE backend (jamais la clé secrète dans l'app)
let vc = SFSafariViewController(url: URL(string: paymentUrl)!)
present(vc, animated: true)

// Récupérez le retour via un Universal Link (return_url).
// La commande est validée par le WEBHOOK côté serveur.

Vérifier le statut d'un paiement

À tout moment, interrogez l'état d'un paiement avec son token (utile en complément du webhook, par exemple depuis votre page de retour).

GET /api/v1/payments/{token}/status

cURL
curl -H "TCHIN-PUBLIC-KEY: votre_cle_publique" \
     -H "TCHIN-PRIVATE-KEY: votre_cle_privee" \
  https://tchin.tech/api/v1/payments/ab12cd34ef/status

Le champ status vaut pending, completed, failed ou cancelled.

Mode test

Avec "env": "test", utilisez le compte de test de votre tableau de bord (menu API → « Compte test ») : email, numéro et mot de passe fictifs. Le paiement est simulé, aucun argent réel n'est déplacé et votre solde n'est pas crédité. Tchin envoie tout de même un webhook de test (mode: test) pour que vous puissiez valider votre intégration avant la production.

Questions fréquentes

Un même lien peut-il être payé plusieurs fois ?

Chaque appel à /payments crée un paiement à usage unique. Pour plusieurs ventes, créez un paiement par commande.

Combien Tchin prélève-t-il ?

Une commission de 5% est retenue à l'encaissement ; le reste (net) est crédité sur votre solde du pays concerné.

Que se passe-t-il si le client abandonne ?

Aucun webhook « completed » n'est envoyé ; ne validez pas la commande. Le client peut réessayer.

Base API : https://tchin.tech/api/v1 · Tchin Documentation

Connexion / Inscription

Entrez votre email, on vous envoie un code à 6 chiffres.

En vous inscrivant, vous acceptez nos politiques.

Entrez le code

Code envoyé à .