Bien démarrer

Vos clés d’API

Clés de test et de production, secrètes et publiables, et votre première requête authentifiée.

Ouvrir en Markdown
Sur cette page
  1. Les quatre sortes de clés
  2. Envoyer votre première requête
  3. Quand une clé est refusée
  4. Garder les clés secrètes secrètes

Chaque requête à l’API AdProMaxPay porte une clé. La clé indique à l’API quelle organisation vous êtes et dans quel mode vous travaillez, test ou production.

Les quatre sortes de clés

PréfixeSorteMode
apx_sk_test_…SecrèteTest
apx_pk_test_…PubliableTest
apx_sk_live_…SecrèteProduction
apx_pk_live_…PubliableProduction
  • Une clé secrète agit pour toute votre organisation. Sa place est sur votre serveur, jamais dans une page web ou une application.
  • Une clé publiable est faite pour figurer dans une page web ou une application. Aujourd’hui, chaque route de l’API demande une clé secrète.
  • Les clés de test fonctionnent dès l’inscription. Les clés de production fonctionnent une fois votre compte activé.

La clé secrète de test de votre bac à sable s’affiche une seule fois, à l’inscription. Les clés suivantes se créent sur la page Clés d’API du tableau de bord, et une clé secrète ne s’affiche qu’une fois, à sa création : conservez-la à ce moment-là.

Envoyer votre première requête

Placez votre clé secrète de test dans une variable d’environnement, puis demandez à l’API qui vous êtes. Envoyez la clé comme jeton bearer, ou comme nom d’utilisateur de l’authentification HTTP Basic avec un mot de passe vide.

La réponse est votre compte : son identifiant, son statut d’activation (sandbox jusqu’à l’activation) et la version de l’API qu’il utilise.

  • curl
  • Node.js
  • TypeScript
  • Python
  • PHP
  • Ruby
  • Go
  • Java
  • C#
  • Rust
account.mjsaccount.tsaccount.pyaccount.phpaccount.rbaccount.goAccount.javaAccount.csmain.rs
curl https://pay-api.adpromax.com/v1/account \
  -u "$APX_SECRET_KEY:"
const response = await fetch('https://pay-api.adpromax.com/v1/account', {
  headers: { Authorization: `Bearer ${process.env.APX_SECRET_KEY}` },
})
const account = await response.json()
if (!response.ok)
  throw new Error(account.error.message)
console.log(account.id, account.activation_status)
interface Account {
  id: string
  object: 'account'
  business_name: string
  activation_status: string
  api_version: string
}

interface ApiError {
  error: { type: string, code: string, message: string, request_id: string }
}

const response = await fetch('https://pay-api.adpromax.com/v1/account', {
  headers: { Authorization: `Bearer ${process.env.APX_SECRET_KEY}` },
})
if (!response.ok) {
  const { error } = (await response.json()) as ApiError
  throw new Error(`${error.code}: ${error.message}`)
}
const account = (await response.json()) as Account
console.log(account.id, account.activation_status)
import os

import requests

response = requests.get(
    "https://pay-api.adpromax.com/v1/account",
    auth=(os.environ["APX_SECRET_KEY"], ""),
)
account = response.json()
if not response.ok:
    raise RuntimeError(account["error"]["message"])
print(account["id"], account["activation_status"])
<?php
$ch = curl_init('https://pay-api.adpromax.com/v1/account');
curl_setopt_array($ch, [
    CURLOPT_USERPWD => getenv('APX_SECRET_KEY') . ':',
    CURLOPT_RETURNTRANSFER => true,
]);
$account = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
    throw new RuntimeException($account['error']['message']);
}
echo $account['id'], ' ', $account['activation_status'], PHP_EOL;
require 'json'
require 'net/http'

uri = URI('https://pay-api.adpromax.com/v1/account')
request = Net::HTTP::Get.new(uri)
request.basic_auth(ENV.fetch('APX_SECRET_KEY'), '')

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(request)
end
account = JSON.parse(response.body)
raise account.dig('error', 'message') unless response.is_a?(Net::HTTPSuccess)

puts "#{account['id']} #{account['activation_status']}"
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
)

type Account struct {
	ID               string `json:"id"`
	BusinessName     string `json:"business_name"`
	ActivationStatus string `json:"activation_status"`
	APIVersion       string `json:"api_version"`
}

type APIError struct {
	Error struct {
		Code    string `json:"code"`
		Message string `json:"message"`
	} `json:"error"`
}

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://pay-api.adpromax.com/v1/account", nil)
	if err != nil {
		log.Fatal(err)
	}
	req.SetBasicAuth(os.Getenv("APX_SECRET_KEY"), "")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()

	if res.StatusCode >= 400 {
		var apiErr APIError
		json.NewDecoder(res.Body).Decode(&apiErr)
		log.Fatal(apiErr.Error.Message)
	}
	var account Account
	if err := json.NewDecoder(res.Body).Decode(&account); err != nil {
		log.Fatal(err)
	}
	fmt.Println(account.ID, account.ActivationStatus)
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Account {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://pay-api.adpromax.com/v1/account"))
            .header("Authorization", "Bearer " + System.getenv("APX_SECRET_KEY"))
            .GET()
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() >= 400) {
            throw new IllegalStateException(response.body());
        }
        // The account as JSON: read it with your JSON library (Jackson, Gson…).
        System.out.println(response.body());
    }
}
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

var json = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower };
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("APX_SECRET_KEY"));

using var response = await http.GetAsync("https://pay-api.adpromax.com/v1/account");
if (!response.IsSuccessStatusCode)
{
    var failure = await response.Content.ReadFromJsonAsync<ApiError>(json);
    throw new InvalidOperationException(failure?.Error.Message);
}
var account = await response.Content.ReadFromJsonAsync<Account>(json);
Console.WriteLine($"{account!.Id} {account.ActivationStatus}");

record Account(string Id, string BusinessName, string ActivationStatus, string ApiVersion);
record ApiError(ApiErrorBody Error);
record ApiErrorBody(string Code, string Message);
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
//             serde = { version = "1", features = ["derive"] }
use serde::Deserialize;

#[derive(Deserialize)]
struct Account {
    id: String,
    activation_status: String,
}

#[derive(Deserialize)]
struct ApiError {
    error: ErrorBody,
}

#[derive(Deserialize)]
struct ErrorBody {
    message: String,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let response = reqwest::blocking::Client::new()
        .get("https://pay-api.adpromax.com/v1/account")
        .bearer_auth(std::env::var("APX_SECRET_KEY")?)
        .send()?;
    if !response.status().is_success() {
        let failure: ApiError = response.json()?;
        return Err(failure.error.message.into());
    }
    let account: Account = response.json()?;
    println!("{} {}", account.id, account.activation_status);
    Ok(())
}
Réponse200 OK
{
  "id": "org_01k7cz9q3m8v6t2x4b5n7p1r0s",
  "object": "account",
  "business_name": "Atlas Shop",
  "country": "MA",
  "default_currency": "mad",
  "activation_status": "sandbox",
  "capabilities": {
    "card_payments": "inactive",
    "cash_payments": "inactive"
  },
  "api_version": "2026-11-01",
  "created": 1790847000
}

Quand une clé est refusée

L’API répond 401 ou 403 avec un objet d’erreur ; son code dit pourquoi.

StatutcodeCe qui s’est passé
401api_key_missingLa requête ne portait aucune clé.
401api_key_invalidLa clé n’existe pas. Vérifiez qu’il ne manque pas un caractère.
401api_key_revokedLa clé a été révoquée. Utilisez-en une autre.
401api_key_expiredLa clé a été renouvelée et son chevauchement est terminé. Utilisez la nouvelle clé.
403secret_key_requiredUne clé publiable a servi là où il faut une clé secrète.
403account_inactiveLe compte est suspendu ou fermé.
403live_mode_not_activatedUne clé de production a servi avant l’activation du compte.

Le message de l’erreur l’explique dans la langue de votre requête, et son request_id identifie la requête si vous écrivez au support.

Garder les clés secrètes secrètes

  • Lisez la clé depuis une variable d’environnement ou un coffre de secrets ; ne la versionnez jamais dans un dépôt.
  • Ne placez jamais une clé secrète dans une page web, une application mobile ou un ticket de support.
  • Si une clé secrète a pu fuiter, révoquez-la sur le tableau de bord et créez-en une nouvelle.

Renouvellement, révocation et le reste : Sécurité.