De l'installation du SDK à la réception de votre premier webhook, étape par étape.
Installez le package officiel tiqopay dans votre projet.
npm install @tiqopay/sdkyarn add @tiqopay/sdkpnpm add @tiqopay/sdkPas de Node.js ?
L'API REST fonctionne avec tout langage capable de faire des requêtes HTTP. Voir les exemples Python et PHP plus bas.
Créez un compte et récupérez vos clés depuis le dashboard développeur. Vous obtiendrez une clé test sk_test_... et une clé live sk_live_....
.env
TIQOPAY_SECRET_KEY=sk_test_aBcDeFgHiJkLmNoPqRsTuVwXyZ...
TIQOPAY_WEBHOOK_SECRET=whsec_aBcDeFgHiJkLmNoPqRsTuV...Commencez en mode test
Les clés sk_test_ simulent des transactions sans mouvement d'argent réel. Passez en live quand vous êtes prêt.
Créez une transaction escrow. L'acheteur recevra un email avec le lien de paiement.
import { Tiqopay } from '@tiqopay/sdk';
const escrow = new Tiqopay({
apiKey: process.env.TIQOPAY_SECRET_KEY,
});
const transaction = await escrow.transactions.create({
amount: 50000, // 500.00 MAD (centimes)
description: 'Logo design - 3 concepts',
buyer_email: 'fatima@email.ma',
buyer_name: 'Fatima Zahra',
deadline: '2026-04-01T00:00:00Z',
});
console.log(transaction.id); // txn_01JQ...
console.log(transaction.status); // "created"import requests
import os
API_KEY = os.environ["TIQOPAY_SECRET_KEY"]
BASE = "https://tiqopay.com/api/v1"
res = requests.post(
f"{BASE}/transactions",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"amount": 50000,
"description": "Logo design - 3 concepts",
"buyer_email": "fatima@email.ma",
"buyer_name": "Fatima Zahra",
"deadline": "2026-04-01T00:00:00Z",
},
)
txn = res.json()
print(txn["id"]) # txn_01JQ...
print(txn["status"]) # "created"<?php
$apiKey = getenv('TIQOPAY_SECRET_KEY');
$base = 'https://tiqopay.com/api/v1';
$ch = curl_init("$base/transactions");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $apiKey",
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => 50000,
'description' => 'Logo design - 3 concepts',
'buyer_email' => 'fatima@email.ma',
'buyer_name' => 'Fatima Zahra',
'deadline' => '2026-04-01T00:00:00Z',
]),
]);
$txn = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $txn['id']; // txn_01JQ...
echo $txn['status']; // "created"Configurez un endpoint pour recevoir les événements en temps réel (paiement reçu, livraison, libération des fonds, litige...).
import express from 'express';
import { verifyWebhook } from '@tiqopay/sdk/webhooks';
const app = express();
// Important: raw body pour la vérification HMAC
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
try {
const event = verifyWebhook(
req.body.toString(),
req.headers['tiqopay-signature'] as string,
process.env.TIQOPAY_WEBHOOK_SECRET,
);
switch (event.type) {
case 'transaction.funded':
console.log('Paiement reçu !', event.data.id);
// Notifier le vendeur de commencer le travail
break;
case 'transaction.delivered':
console.log('Livraison confirmée', event.data.id);
break;
case 'transaction.released':
console.log('Fonds libérés !', event.data.id);
// Mettre à jour le statut commande
break;
case 'transaction.disputed':
console.log('Litige ouvert', event.data.id);
// Alerter le support
break;
}
res.json({ received: true });
} catch (err) {
console.error('Webhook invalide:', err.message);
res.status(400).json({ error: err.message });
}
});
app.listen(3000);import hmac, hashlib, time, json, os
from flask import Flask, request, jsonify
app = Flask(__name__)
SECRET = os.environ["TIQOPAY_WEBHOOK_SECRET"]
def verify_webhook(payload, signature, secret, tolerance=300):
parts = dict(p.split("=", 1) for p in signature.split(","))
ts = int(parts["t"])
if time.time() - ts > tolerance:
raise ValueError("Timestamp too old")
expected = hmac.new(
secret.encode(),
f"{ts}.{payload}".encode(),
hashlib.sha256,
).hexdigest()
if not hmac.compare_digest(expected, parts["v1"]):
raise ValueError("Invalid signature")
return json.loads(payload)
@app.post("/webhooks")
def handle_webhook():
try:
event = verify_webhook(
request.get_data(as_text=True),
request.headers["tiqopay-Signature"],
SECRET,
)
except ValueError as e:
return jsonify(error=str(e)), 400
if event["type"] == "transaction.funded":
print("Paiement reçu !", event["data"]["id"])
return jsonify(received=True)<?php
$secret = getenv('TIQOPAY_WEBHOOK_SECRET');
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_TIQOPAY_SIGNATURE'] ?? '';
// Extraire timestamp et signature
$parts = [];
foreach (explode(',', $signature) as $p) {
[$k, $v] = explode('=', $p, 2);
$parts[$k] = $v;
}
$ts = (int) $parts['t'];
// Vérifier la fraîcheur (5 min)
if (time() - $ts > 300) {
http_response_code(400);
die(json_encode(['error' => 'Timestamp too old']));
}
// Vérifier la signature HMAC-SHA256
$expected = hash_hmac('sha256', "$ts.$payload", $secret);
if (!hash_equals($expected, $parts['v1'])) {
http_response_code(400);
die(json_encode(['error' => 'Invalid signature']));
}
$event = json_decode($payload, true);
switch ($event['type']) {
case 'transaction.funded':
// Paiement reçu
break;
case 'transaction.released':
// Fonds libérés
break;
}
echo json_encode(['received' => true]);Quand tout fonctionne en mode test, basculez en live en 3 étapes :
sk_test_ par votre clé sk_live_// C'est tout — le code ne change pas
const escrow = new Tiqopay({
apiKey: process.env.TIQOPAY_SECRET_KEY, // sk_live_...
});Créez un compte gratuit et obtenez vos clés API en quelques secondes.