البدء
مفاتيح API الخاصة بك
مفاتيح الاختبار ومفاتيح الوضع المباشر، السرية والقابلة للنشر، وأول طلب مصادَق عليه ترسله.
يحمل كل طلب إلى واجهة API لدى AdProMaxPay مفتاحًا. يخبر المفتاح الواجهة بمؤسستك وبالوضع الذي تعمل فيه: وضع الاختبار أو الوضع المباشر.
أنواع المفاتيح الأربعة
| البادئة | النوع | الوضع |
|---|---|---|
apx_sk_test_… | سري | الاختبار |
apx_pk_test_… | قابل للنشر | الاختبار |
apx_sk_live_… | سري | المباشر |
apx_pk_live_… | قابل للنشر | المباشر |
- المفتاح السري يتصرف باسم مؤسستك كلها. مكانه خادمك، لا صفحة ويب ولا تطبيق أبدًا.
- المفتاح القابل للنشر مصمم ليوضع في صفحة ويب أو تطبيق. وحاليًا يطلب كل مسار في API مفتاحًا سريًا.
- مفاتيح الاختبار تعمل فور إنشائها. ومفاتيح الوضع المباشر تعمل بعد تفعيل حسابك.
لا ينشئ AdProMaxPay أي مفتاح بدلًا منك. تنشئ مفاتيح الاختبار من صفحة مفاتيح API في لوحة التحكم، بعد التحقق من بريدك الإلكتروني، ولا يُعرض المفتاح السري إلا مرة واحدة، عند إنشائه: احفظه حينها.
أرسل طلبك الأول
ضع مفتاحك السري للاختبار في متغير بيئة، ثم اسأل API من أنت. أرسل المفتاح كرمز Bearer، أو كاسم المستخدم في مصادقة HTTP Basic مع كلمة مرور فارغة.
الاستجابة هي حسابك: معرّفه، وحالة تفعيله (sandbox إلى حين التفعيل)، وإصدار API الذي
يستخدمه.
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(())
}{
"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
}عندما يُرفض مفتاح
تجيب واجهة API بـ 401 أو 403 مع كائن خطأ؛ ويوضح حقله code السبب.
| الحالة | code | ما حدث |
|---|---|---|
| 401 | api_key_missing | لم يحمل الطلب أي مفتاح. |
| 401 | api_key_invalid | المفتاح غير موجود. تحقّق من عدم نقصان أي حرف. |
| 401 | api_key_revoked | أُبطل المفتاح. استخدم مفتاحًا آخر. |
| 401 | api_key_expired | جُدِّد المفتاح وانتهت فترة التداخل الخاصة به. استخدم المفتاح الجديد. |
| 403 | secret_key_required | استُخدم مفتاح قابل للنشر حيث يلزم مفتاح سري. |
| 403 | account_inactive | الحساب موقوف أو مغلق. |
| 403 | live_mode_not_activated | استُخدم مفتاح للوضع المباشر قبل تفعيل الحساب. |
يشرح حقل message الخطأ بلغة طلبك، ويحدد request_id الطلب إذا راسلت
الدعم.
حافظ على سرية المفاتيح السرية
- اقرأ المفتاح من متغير بيئة أو من مخزن أسرار؛ ولا تودعه أبدًا في مستودع كود.
- لا تضع مفتاحًا سريًا أبدًا في صفحة ويب أو تطبيق جوال أو تذكرة دعم.
- إذا احتُمل تسرّب مفتاح سري، فأبطِله من لوحة التحكم وأنشئ مفتاحًا جديدًا.
التجديد والإبطال وغيرهما: الأمان.