Intégrer MonCash et NatCash en Laravel, Node.js, Python et PHP
L'API Tranzak est du HTTP et du JSON : une requête pour créer le paiement, une vérification de signature pour le webhook. Tranzak ne publie pas de SDK : l'API est du HTTP et du JSON, appelée directement depuis votre langage.
Les deux opérations à implémenter
- Créer le paiement : POST /api/gateway/v1/payments avec l'en-tête X-Api-Key, puis rediriger le client vers payment_url.
- Recevoir le webhook : vérifier l'en-tête X-Tranzak-Signature (HMAC-SHA256 du corps brut avec le secret de votre site), répondre 2xx rapidement et traiter chaque paiement une seule fois.
Avant de coder
Créez un site dans la section Développeur du tableau de bord : vous y renseignez l'adresse du webhook (publique, en HTTPS) et l'adresse de retour, et vous récupérez le secret du webhook. Gardez la clé API et le secret dans des variables d'environnement, jamais dans le code ni côté navigateur.
Exemples de code
use Illuminate\Support\Facades\Http;
$response = Http::withHeaders(['X-Api-Key' => config('services.tranzak.key')])
->post('https://tranzak.co/api/gateway/v1/payments', [
'amount' => 500,
'currency' => 'HTG',
'payment_method' => 'moncash', // ou 'natcash'
'customer_name' => $order->customer_name,
'reference' => (string) $order->id,
])->throw();
return redirect()->away($response->json('payment_url'));
public function webhook(Request $request)
{
$expected = hash_hmac('sha256', $request->getContent(), config('services.tranzak.webhook_secret'));
abort_unless(hash_equals($expected, (string) $request->header('X-Tranzak-Signature')), 401);
// Traitez l'événement une seule fois (clé : transaction_id + événement), puis répondez vite.
return response()->noContent();
}
import crypto from 'node:crypto';
import express from 'express';
const app = express();
async function createPayment(order) {
const res = await fetch('https://tranzak.co/api/gateway/v1/payments', {
method: 'POST',
headers: { 'X-Api-Key': process.env.TRANZAK_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
amount: order.total, currency: 'HTG', payment_method: 'moncash',
customer_name: order.name, reference: String(order.id),
}),
});
return (await res.json()).payment_url; // redirigez le client ici
}
// Le corps brut est nécessaire pour calculer la signature.
app.post('/webhooks/tranzak', express.raw({ type: 'application/json' }), (req, res) => {
const expected = crypto.createHmac('sha256', process.env.TRANZAK_WEBHOOK_SECRET)
.update(req.body).digest('hex');
const received = String(req.get('X-Tranzak-Signature') || '');
const ok = received.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
if (!ok) return res.sendStatus(401);
// Traitez l'événement (JSON.parse(req.body)) une seule fois, puis répondez vite.
res.sendStatus(204);
});
import hashlib, hmac, os
import requests
def create_payment(order):
r = requests.post(
"https://tranzak.co/api/gateway/v1/payments",
headers={"X-Api-Key": os.environ["TRANZAK_API_KEY"]},
json={
"amount": order["total"], "currency": "HTG", "payment_method": "natcash",
"customer_name": order["name"], "reference": str(order["id"]),
},
timeout=15,
)
r.raise_for_status()
return r.json()["payment_url"] # redirigez le client ici
def signature_is_valid(raw_body: bytes, header: str) -> bool:
expected = hmac.new(os.environ["TRANZAK_WEBHOOK_SECRET"].encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header or "")
$ch = curl_init('https://tranzak.co/api/gateway/v1/payments');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-Api-Key: ' . getenv('TRANZAK_API_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'amount' => 500, 'currency' => 'HTG', 'payment_method' => 'moncash',
'customer_name' => 'Jean Baptiste', 'reference' => 'commande-1042',
]),
]);
$payment = json_decode(curl_exec($ch), true);
header('Location: ' . $payment['payment_url']);
// Webhook : hash_equals(hash_hmac('sha256', file_get_contents('php://input'), $secret), $_SERVER['HTTP_X_TRANZAK_SIGNATURE'] ?? '')
Questions fréquentes
Existe-t-il un SDK Tranzak pour Laravel, Node.js ou Python ?
Non. L'API est du HTTP et du JSON : les exemples de cette page suffisent, avec Http de Laravel, fetch, requests ou cURL.
Comment vérifier qu'un webhook vient bien de Tranzak ?
En comparant l'en-tête X-Tranzak-Signature avec le HMAC-SHA256 du corps brut de la requête, calculé avec le secret de votre site, par une comparaison à temps constant.
Où trouver la clé API et le secret du webhook ?
Dans la section Développeur de votre tableau de bord Tranzak, où vous créez aussi vos clés de test et de production.
Y a-t-il une spécification de l'API ?
Oui : un contrat OpenAPI 3.1 et une collection Postman sont publics.
À lire aussi
Commencez avec une clé de test gratuite
Créez votre compte et testez votre première intégration sans argent réel.
Créer un compte