Encaissez cartes et espèces au Maroc, avec une seule API

Construisez dans le bac à sable avec des clés de test, suivez un paiement de sa création à sa réussite, puis passez en production avec le même code.

Votre serveur

POST /v1/checkout/sessions

{ "amount": 25000, "currency": "mad" }

pi_01k7d2h6w0f3r8t5y2TEST

250,00 MAD

  1. requires_payment_method
  2. requires_action
  3. processing
  4. succeeded

Votre point de terminaison webhook

payment_intent.succeeded200 OK

Un paiement de test, de la requête de votre serveur jusqu’au webhook

Par où commencer

Démarrages rapides

Chacun se déroule entièrement en mode test, en une dizaine de minutes.

Votre langage, partout

Chaque exemple appelle l’API HTTP avec le client standard de votre langage. Choisissez-en un : tous les blocs de code du site suivent, et votre navigateur s’en souvient.

  • 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(())
}

Données de test

Utilisez n’importe quelle date d’expiration future et trois chiffres quelconques. Les numéros de test ne fonctionnent qu’avec des clés de test.

Numéro de carteExpirationtoute date futureCVC3 chiffres quelconquesScénarioRésultat
4242 4242 4242 4242Expiration12/34CVC123Succès
Réussit tout de suite.
4000 0000 0000 3220Expiration12/34CVC1233-D Secure
Une page 3-D Secure simulée s’ouvre.
4000 0000 0000 0002Expiration12/34CVC123Refusée
La banque refuse le paiement.
4000 0000 0000 0077Expiration12/34CVC123Confirmation lente
Réussit après 60 secondes.
Toutes les cartes et tous les scénarios espèces de test