Relancer une facture impayée sur WhatsApp

Oui, même si le client ne vous a pas écrit : template UTILITY avec montant et échéance en variables, et un bouton « Payer » dont le lien est propre à chaque facture.

Relancer une facture impayée sur WhatsApp

Astuce
Oui, même si le client ne vous a pas écrit : template UTILITY avec montant et échéance en variables, et un bouton « Payer » dont le lien est propre à chaque facture.

Scénario

Une facture n'est pas réglée trois jours après l'échéance. Votre logiciel envoie un rappel WhatsApp avec le montant, la date, et un bouton qui ouvre la page de paiement de cette facture.

Conversation

Vous    : Bonjour Paul, la facture F-2026-118 de 45 000 FCFA était due le 27/10.
          Vous pouvez la régler en ligne en un clic.
          [ Payer la facture ]   → https://pay.exemple.com/f/F-2026-118
Client  : (touche le bouton, paie sur votre page)

Code

Créez le template une fois. Le lien du bouton se termine par {{1}}, avec un exemple complet :

curl

curl -X POST "https://wa-api.geskap.com/v1/templates" \
  -H "Authorization: Bearer $GESKAP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "relance_facture",
  "language": "fr",
  "category": "UTILITY",
  "body_text": "Bonjour {{1}}, la facture {{2}} de {{3}} était due le {{4}}. Vous pouvez la régler en ligne avec le bouton ci-dessous.",
  "example_values": ["Paul", "F-2026-118", "45 000 FCFA", "27/10/2026"],
  "buttons": [
    {
      "kind": "url",
      "text": "Payer la facture",
      "url": "https://pay.exemple.com/f/{{1}}",
      "url_example": "https://pay.exemple.com/f/F-2026-118"
    }
  ]
}'

Node.js

const res = await fetch("https://wa-api.geskap.com/v1/templates", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.GESKAP_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "relance_facture",
    "language": "fr",
    "category": "UTILITY",
    "body_text": "Bonjour {{1}}, la facture {{2}} de {{3}} était due le {{4}}. Vous pouvez la régler en ligne avec le bouton ci-dessous.",
    "example_values": ["Paul", "F-2026-118", "45 000 FCFA", "27/10/2026"],
    "buttons": [
      {
        "kind": "url",
        "text": "Payer la facture",
        "url": "https://pay.exemple.com/f/{{1}}",
        "url_example": "https://pay.exemple.com/f/F-2026-118"
      }
    ]
  }),
});
console.log(res.status, await res.json());

PHP

$ch = curl_init("https://wa-api.geskap.com/v1/templates");
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("GESKAP_API_KEY"),
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => json_encode([
    "name" => "relance_facture",
    "language" => "fr",
    "category" => "UTILITY",
    "body_text" => "Bonjour {{1}}, la facture {{2}} de {{3}} était due le {{4}}. Vous pouvez la régler en ligne avec le bouton ci-dessous.",
    "example_values" => ["Paul", "F-2026-118", "45 000 FCFA", "27/10/2026"],
    "buttons" => [
      [
        "kind" => "url",
        "text" => "Payer la facture",
        "url" => "https://pay.exemple.com/f/{{1}}",
        "url_example" => "https://pay.exemple.com/f/F-2026-118",
      ],
    ],
  ]),
]);
$res = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $res;

Python

import os, requests

res = requests.request(
    "POST",
    "https://wa-api.geskap.com/v1/templates",
    headers={"Authorization": f"Bearer {os.environ['GESKAP_API_KEY']}"},
    json={
        "name": "relance_facture",
        "language": "fr",
        "category": "UTILITY",
        "body_text": "Bonjour {{1}}, la facture {{2}} de {{3}} était due le {{4}}. Vous pouvez la régler en ligne avec le bouton ci-dessous.",
        "example_values": ["Paul", "F-2026-118", "45 000 FCFA", "27/10/2026"],
        "buttons": [
            {
                "kind": "url",
                "text": "Payer la facture",
                "url": "https://pay.exemple.com/f/{{1}}",
                "url_example": "https://pay.exemple.com/f/F-2026-118",
            },
        ],
    },
    timeout=15,
)
print(res.status_code, res.json())

Une fois le template APPROVED, envoyez-le pour chaque facture. button_url_param porte la fin du lien :

curl

curl -X POST "https://wa-api.geskap.com/v1/messages" \
  -H "Authorization: Bearer $GESKAP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+237690000001",
  "template": {
    "name": "relance_facture",
    "language": "fr",
    "variables": ["Paul", "F-2026-118", "45 000 FCFA", "27/10/2026"],
    "button_url_param": "F-2026-118"
  },
  "idempotency_key": "relance-F-2026-118-1"
}'

Node.js

const res = await fetch("https://wa-api.geskap.com/v1/messages", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.GESKAP_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "to": "+237690000001",
    "template": {
      "name": "relance_facture",
      "language": "fr",
      "variables": ["Paul", "F-2026-118", "45 000 FCFA", "27/10/2026"],
      "button_url_param": "F-2026-118"
    },
    "idempotency_key": "relance-F-2026-118-1"
  }),
});
console.log(res.status, await res.json());

PHP

$ch = curl_init("https://wa-api.geskap.com/v1/messages");
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("GESKAP_API_KEY"),
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => json_encode([
    "to" => "+237690000001",
    "template" => [
      "name" => "relance_facture",
      "language" => "fr",
      "variables" => ["Paul", "F-2026-118", "45 000 FCFA", "27/10/2026"],
      "button_url_param" => "F-2026-118",
    ],
    "idempotency_key" => "relance-F-2026-118-1",
  ]),
]);
$res = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $res;

Python

import os, requests

res = requests.request(
    "POST",
    "https://wa-api.geskap.com/v1/messages",
    headers={"Authorization": f"Bearer {os.environ['GESKAP_API_KEY']}"},
    json={
        "to": "+237690000001",
        "template": {
            "name": "relance_facture",
            "language": "fr",
            "variables": ["Paul", "F-2026-118", "45 000 FCFA", "27/10/2026"],
            "button_url_param": "F-2026-118",
        },
        "idempotency_key": "relance-F-2026-118-1",
    },
    timeout=15,
)
print(res.status_code, res.json())
Attention
Piège : catégorie UTILITY, ton factuel : une relance qui ressemble à une promotion est reclassée MARKETING par Meta, et l'envoi marketing est bloqué par défaut sur votre compte. Pas de menace ni de majuscules.
Attention
Piège : button_url_param est la fin du lien (F-2026-118), jamais l'adresse complète : un domaine différent est refusé. Voir Un lien unique dans un bouton.

Pour joindre la facture elle-même, utilisez un template à en-tête document : Envoyer un PDF. Pour qu'un relancé n'en reçoive pas deux, passez un idempotency_key par facture et par relance : Idempotence.

Preuve — vérifié dans le code de l'API : api_schemas.py, api_send.py.