FlowAlp

Authentification Merchant API

July 30, 2026

Authentifiez vos requêtes Merchant API FlowAlp Pay avec l'en-tête x-api-key ou la signature ApiSignature HMAC-SHA256, avec des exemples.

Chaque requête Merchant API doit prouver qu'elle provient de votre backend. Il vous faut votre nom d'instance, son API Secret et l'une des deux méthodes d'authentification :

  • En-tête `x-api-key` (recommandé) : vous envoyez l'API Secret avec chaque requête.
  • Paramètre `ApiSignature` : vous envoyez une signature HMAC-SHA256 calculée à partir des paramètres de la requête — le secret lui-même n'est jamais transmis.

Si vous développez en PHP, le SDK PHP applique l'authentification pour vous ; cette page concerne surtout les intégrations HTTP directes.

Prérequis

Option 1 : en-tête x-api-key (recommandée)

Envoyez l'API Secret dans l'en-tête HTTP x-api-key. Les noms d'en-têtes sont insensibles à la casse : X-API-KEY est équivalent :

En-têteHTTP
x-api-key: <api-secret>
Tester l'en-tête avec SignatureCheckbash
curl --request GET \
  --url "https://api.pay.flowalp.com/v1.16/SignatureCheck/?instance=<instance>" \
  --header "x-api-key: <api-secret>"
PHP brut (cURL) avec x-api-keyPHP
<?php
$instance  = getenv('FLOWALP_PAY_INSTANCE');
$apiSecret = getenv('FLOWALP_PAY_API_SECRET');

$ch = curl_init(
    'https://api.pay.flowalp.com/v1.16/SignatureCheck/?instance=' . urlencode($instance)
);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['x-api-key: ' . $apiSecret]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$status   = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

if ($status !== 200) {
    throw new RuntimeException('FlowAlp Pay auth check failed: ' . $status);
}
Node.js avec x-api-keyJavaScript
const instanceName = process.env.FLOWALP_PAY_INSTANCE;
const apiSecret = process.env.FLOWALP_PAY_API_SECRET;

const response = await fetch(
  `https://api.pay.flowalp.com/v1.16/SignatureCheck/?instance=${encodeURIComponent(instanceName)}`,
  { headers: { "x-api-key": apiSecret } }
);

if (!response.ok) {
  throw new Error(`FlowAlp Pay auth check failed: ${response.status}`);
}

Option 2 : ApiSignature (HMAC-SHA256)

En mode signature, vous ne transmettez pas le secret. Vous signez les paramètres de la requête et envoyez le résultat dans le paramètre ApiSignature. La signature est un HMAC (RFC 2104), construit ainsi :

  1. Rassemblez tous les paramètres de la requête sauf instance.
  2. Construisez la query string URL-encodée de ces paramètres, par exemple amount=2500&currency=CHF.
  3. Calculez le HMAC-SHA256 binaire de cette chaîne, avec l'API Secret comme clé.
  4. Encodez le résultat en Base64.
  5. Envoyez la valeur dans le paramètre ApiSignature, avec les autres paramètres.
Algorithme canonique (one-liner PHP)PHP
$apiSignature = base64_encode(
    hash_hmac('sha256', http_build_query($params, '', '&'), $apiSecret, true)
);
Exemple PHP complet : requête Gateway signéePHP
<?php
$instance  = getenv('FLOWALP_PAY_INSTANCE');
$apiSecret = getenv('FLOWALP_PAY_API_SECRET');

$params = [
    'amount'      => 8925, // CHF 89.25 in minor units
    'currency'    => 'CHF',
    'referenceId' => 'ORDER-975382',
];

// Sign exactly the query string you send as the body.
$body = http_build_query($params, '', '&');
$params['ApiSignature'] = base64_encode(
    hash_hmac('sha256', $body, $apiSecret, true)
);

$ch = curl_init(
    'https://api.pay.flowalp.com/v1.16/Gateway/?instance=' . urlencode($instance)
);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params, '', '&'));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);
Bash (openssl)bash
API_SECRET="<api-secret>"
QUERY_STRING="amount=2500&currency=CHF"

SIGNATURE=$(printf '%s' "$QUERY_STRING" \
  | openssl dgst -sha256 -hmac "$API_SECRET" -binary \
  | openssl enc -base64)

curl --request POST \
  --url "https://api.pay.flowalp.com/v1.16/Gateway/?instance=<instance>" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data "$QUERY_STRING" \
  --data-urlencode "ApiSignature=$SIGNATURE"

Encodage de la query string

La chaîne à signer doit être form-encodée selon la RFC 1738 : les espaces deviennent +. La sortie de http_build_query() de PHP est l'implémentation de référence. Les autres langages doivent la reproduire exactement ; attention aux caractères comme !'()*~, que certaines bibliothèques encodent différemment (voir le helper JavaScript ci-dessous). Le corps form-urlencoded de la requête utilise quant à lui le percent-encoding, avec les espaces en %20.

Ne concevez pas votre propre variante de l'algorithme. Si votre bibliothèque produit un encodage différent, la signature ne correspondra pas. Validez votre implémentation avec l'endpoint SignatureCheck avant la mise en production.

Helper de signature JavaScript (crypto-js)JavaScript
const qs = require("qs");
const Base64 = require("crypto-js/enc-base64");
const hmacSHA256 = require("crypto-js/hmac-sha256");

function buildSignature(data, secret) {
  let queryStr = "";
  if (data) {
    queryStr = qs.stringify(data, { format: "RFC1738" });
    queryStr = queryStr.replace(
      /[!'()*~]/g,
      (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
    );
  }
  return Base64.stringify(hmacSHA256(queryStr, secret));
}

const params = { amount: 2500, currency: "CHF" };
const signed = {
  ...params,
  ApiSignature: buildSignature(params, process.env.FLOWALP_PAY_API_SECRET),
};

Quelle méthode choisir ?

Critèrex-api-keyApiSignature
Effort d'implémentationMinimal — un seul en-têteExige un encodage exact de la query string
Secret en transitEnvoyé avec chaque requête (toujours via HTTPS)Jamais transmis ; seul le HMAC circule
Usage typiqueIntégrations serveur à serveurEnvironnements avec des règles strictes de gestion des secrets

Vérifier votre configuration

Appelez SignatureCheck après avoir configuré l'une des deux méthodes ; l'endpoint valide l'instance, le secret et — en mode signature — votre encodage. Détails : SignatureCheck : vérifier les identifiants API.

Réponse type en cas de succèsJSON
{
  "status": "success",
  "data": [
    {
      "id": 1
    }
  ]
}

Recommandations de sécurité

  • Gardez l'API Secret côté backend ; ne l'intégrez jamais dans un navigateur, une app mobile ou tout autre code client.
  • Stockez les secrets dans des variables d'environnement ou un gestionnaire de secrets, pas dans le dépôt.
  • Ne journalisez jamais l'en-tête x-api-key ni les valeurs ApiSignature.
  • Effectuez une rotation immédiate du secret en cas de fuite suspectée.
  • Appelez toujours l'API via HTTPS.

Authentification prête ? Poursuivez avec le format des requêtes et envoyez votre première requête API.