Autenticazione della Merchant API
July 30, 2026
Autentica le richieste alla Merchant API di FlowAlp Pay con l'header x-api-key o con la firma ApiSignature HMAC-SHA256, con esempi di codice.
Ogni richiesta alla Merchant API deve dimostrare di provenire dal tuo backend. Ti servono l'instance name, il relativo API Secret e uno dei due metodi di autenticazione:
- Header `x-api-key` (consigliato): invii l'API Secret con ogni richiesta.
- Parametro `ApiSignature`: invii una firma HMAC-SHA256 calcolata sui parametri della request — il secret non viene mai trasmesso.
Se sviluppi in PHP, lo SDK PHP applica l'autenticazione al posto tuo; questa pagina è rilevante soprattutto per le integrazioni HTTP dirette.
Prerequisiti
- Il tuo instance name
- Le tue credenziali API
- L'API Secret conservato fuori dal codice, ad esempio nella variabile d'ambiente
FLOWALP_PAY_API_SECRET
Opzione 1: header x-api-key (consigliata)
Invia l'API Secret nell'header HTTP x-api-key. I nomi degli header non distinguono maiuscole e minuscole, quindi X-API-KEY è equivalente:
x-api-key: <api-secret>curl --request GET \
--url "https://api.pay.flowalp.com/v1.16/SignatureCheck/?instance=<instance>" \
--header "x-api-key: <api-secret>"<?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);
}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}`);
}Opzione 2: ApiSignature (HMAC-SHA256)
In modalità firma non trasmetti il secret: firmi i parametri della request e invii il risultato nel parametro ApiSignature. La firma è un HMAC (RFC 2104) e si costruisce così:
- Raccogli tutti i parametri della request eccetto
instance. - Costruisci la query string URL-encoded di questi parametri, ad esempio
amount=2500¤cy=CHF. - Calcola l'HMAC-SHA256 binario di quella stringa usando l'API Secret come chiave.
- Codifica il risultato in Base64.
- Invia il valore nel parametro
ApiSignatureinsieme agli altri parametri.
$apiSignature = base64_encode(
hash_hmac('sha256', http_build_query($params, '', '&'), $apiSecret, true)
);<?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);API_SECRET="<api-secret>"
QUERY_STRING="amount=2500¤cy=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"Encoding della query string
La stringa da firmare deve essere form-encoded secondo RFC 1738: gli spazi diventano +. L'output di http_build_query() di PHP è l'implementazione di riferimento. Gli altri linguaggi devono riprodurla esattamente; fai attenzione a caratteri come !'()*~, che alcune librerie codificano in modo diverso (vedi l'helper JavaScript qui sotto). Il body form-urlencoded della request usa invece il percent-encoding, con gli spazi come %20.
Non creare varianti dell'algoritmo. Se la tua libreria produce un encoding diverso, la firma non corrisponderà. Convalida l'implementazione con l'endpoint SignatureCheck prima di andare in produzione.
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),
};Quale metodo scegliere?
| Criterio | x-api-key | ApiSignature |
|---|---|---|
| Impegno di implementazione | Minimo — un solo header | Richiede un encoding esatto della query string |
| Secret in transito | Inviato con ogni richiesta (sempre su HTTPS) | Mai trasmesso; viaggia solo l'HMAC |
| Uso tipico | Integrazioni server-to-server | Ambienti con policy rigide sulla gestione dei secret |
Verifica la configurazione
Dopo aver configurato uno dei due metodi chiama SignatureCheck: convalida instance, secret e — in modalità firma — anche il tuo encoding. Dettagli: SignatureCheck: verifica le credenziali API.
{
"status": "success",
"data": [
{
"id": 1
}
]
}Raccomandazioni di sicurezza
- Tieni l'API Secret sul backend; non inserirlo mai in browser, app mobile o altro codice client-side.
- Conserva i secret in variabili d'ambiente o in un secret manager, non nel repository.
- Non loggare mai l'header
x-api-keyné i valori diApiSignature. - Ruota subito il secret se sospetti una compromissione.
- Chiama l'API sempre tramite HTTPS.
Autenticazione pronta? Prosegui con il formato delle request e invia la tua prima richiesta API.