ما ستفعله في هذه الصفحة
ستمر بست خطوات، وكلها في بيئة التجربة (sandbox). لا مال حقيقي ولا عملاء حقيقيون.
- التسجيل والحصول على مفاتيح التجربة.
- تجهيز التوقيع.
- ربط تاجر تجريبي.
- نشر قائمة.
- استقبال طلب تجريبي وقبوله وإنهاؤه.
- الانتقال إلى التشغيل.
1. سجل واحصل على مفاتيح التجربة
- افتح لوحة المطورين على
developers.aurages.comقريبا وادخل حساب الشريك. عند الإطلاق ننشئ الحسابات بأنفسنا، والتسجيل الذاتي قريبا. - من «المفاتيح» أنشئ مفتاح تجربة. ستحصل على معرف المفتاح
pk_test_xxxوالسرsk_test_xxx. - السر يظهر مرة واحدة. احفظه في خادمك فقط، ولا تضعه في تطبيق أو متصفح.
- من «Webhooks» أضف عنوان استقبال على خادمك، مثل
https://pos.example.com/aurmap/webhooks، واحفظ سر التوقيعwhsec_xxx.
حسابك يأتي ومعه تاجر تجريبي جاهز: «مطعم تجريبي» بفرعين.
export AURMAP_HOST="https://sandbox.partners.aurmap.com"
export AURMAP_KEY_ID="pk_test_xxx"
export AURMAP_KEY_SECRET="sk_test_xxx"عنوان التجربة وعنوان التشغيل يعملان قريبا.
2. جهز التوقيع
كل طلب يحمل أربع ترويسات: معرف المفتاح، والوقت، ورقما عشوائيا (nonce)، وتوقيع HMAC. التفاصيل في المفاتيح والتوقيع. هذه دالة جاهزة لـ bash تستعملها في أمثلة الصفحات كلها:
aurmap() { # aurmap METHOD PATH [BODY]
local method="$1" path="$2" body="${3:-}"
local ts nonce bh sig
ts=$(date +%s)
nonce=$(openssl rand -hex 16)
bh=$(printf '%s' "$body" | openssl dgst -sha256 -hex | sed 's/^.* //')
sig=$(printf '%s\n%s\n%s\n%s\n%s' "$method" "$path" "$ts" "$nonce" "$bh" \
| openssl dgst -sha256 -hmac "$AURMAP_KEY_SECRET" -hex | sed 's/^.* //')
curl -sS -X "$method" "$AURMAP_HOST$path" \
-H "Content-Type: application/json" \
-H "X-AurMap-Key-Id: $AURMAP_KEY_ID" \
-H "X-AurMap-Timestamp: $ts" \
-H "X-AurMap-Nonce: $nonce" \
-H "X-AurMap-Signature: $sig" \
-H "Idempotency-Key: ${IDEMPOTENCY_KEY:-$(openssl rand -hex 12)}" \
${body:+--data-raw "$body"}
}والدالة نفسها في Node:
import crypto from 'node:crypto';
const { AURMAP_HOST, AURMAP_KEY_ID, AURMAP_KEY_SECRET } = process.env;
export function sign(method, path, ts, nonce, body) {
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const canonical = [method.toUpperCase(), path, ts, nonce, bodyHash].join('\n');
return crypto.createHmac('sha256', AURMAP_KEY_SECRET).update(canonical).digest('hex');
}
export async function aurmap(method, path, payload, idempotencyKey) {
const body = payload === undefined ? '' : JSON.stringify(payload);
const ts = String(Math.floor(Date.now() / 1000));
const nonce = crypto.randomBytes(16).toString('hex');
const headers = {
'Content-Type': 'application/json',
'X-AurMap-Key-Id': AURMAP_KEY_ID,
'X-AurMap-Timestamp': ts,
'X-AurMap-Nonce': nonce,
'X-AurMap-Signature': sign(method, path, ts, nonce, body),
};
if (method !== 'GET') headers['Idempotency-Key'] = idempotencyKey ?? crypto.randomUUID();
const res = await fetch(AURMAP_HOST + path, { method, headers, body: body || undefined });
const json = await res.json();
if (!res.ok) throw Object.assign(new Error(json.error?.code ?? 'HTTP_' + res.status), { status: res.status, error: json.error });
return json;
}وفي PHP:
<?php
function aurmap_sign(string $secret, string $method, string $path, string $ts, string $nonce, string $body): string {
$canonical = implode("\n", [strtoupper($method), $path, $ts, $nonce, hash('sha256', $body)]);
return hash_hmac('sha256', $canonical, $secret);
}
function aurmap(string $method, string $path, ?array $payload = null, ?string $idempotencyKey = null): array {
$body = $payload === null ? '' : json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$ts = (string) time();
$nonce = bin2hex(random_bytes(16));
$headers = [
'Content-Type: application/json',
'X-AurMap-Key-Id: ' . getenv('AURMAP_KEY_ID'),
'X-AurMap-Timestamp: ' . $ts,
'X-AurMap-Nonce: ' . $nonce,
'X-AurMap-Signature: ' . aurmap_sign(getenv('AURMAP_KEY_SECRET'), $method, $path, $ts, $nonce, $body),
];
if ($method !== 'GET') {
$headers[] = 'Idempotency-Key: ' . ($idempotencyKey ?? bin2hex(random_bytes(16)));
}
$ch = curl_init(getenv('AURMAP_HOST') . $path);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($body !== '') {
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
$json = json_decode((string) $raw, true) ?? [];
if ($status >= 400) {
throw new RuntimeException($json['error']['code'] ?? ('HTTP_' . $status), $status);
}
return $json;
}3. اربط التاجر التجريبي
اطلب رمز ربط للفرع في نظامك:
aurmap POST /v1/link-codes '{"level":"place","external_location_id":"pos-branch-17","external_location_name":"Test branch","scopes":["catalog:write","inventory:write","orders:read","orders:write"]}'{
"code": "7KQ2M9XA",
"display_code": "7KQ2-M9XA",
"qr_url": "https://aurmap.com/link/7KQ2M9XA",
"status": "pending",
"expires_at": "2026-10-14T12:15:00Z"
}في التشغيل يمسح التاجر الرمز ويوافق بنفسه. في بيئة التجربة تستطيع الموافقة نيابة عنه، إما بزر في لوحة المطورين، أو بهذا الطلب:
aurmap POST /v1/sandbox/link-codes/7KQ2M9XA/approve '{"place_id":"plc_test_olaya"}'يصلك حدث link.created. احفظ منه link_id وplace_id.
{
"event_id": "evt_01JA9W2C4D",
"type": "link.created",
"seq": 1,
"data": {
"link": {
"link_id": "lnk_test_2h6j4n",
"place": { "place_id": "plc_test_olaya", "name": "مطعم تجريبي - العليا" },
"external_location_id": "pos-branch-17",
"scopes": ["catalog:write", "inventory:write", "orders:read", "orders:write"]
}
}
}4. انشر قائمة
احفظ قائمة صغيرة في ملف menu.json:
{
"schema": "aurmap.menu/1",
"currency": "SAR",
"default_language": "ar",
"languages": ["ar", "en"],
"tax": { "prices_include_vat": true, "vat_percent": 15, "service_charge_percent": 0 },
"aurmap_ordering": { "enabled": true, "pickup": true, "delivery": false, "cash": true },
"sections": [
{ "id": "burgers", "parent_id": null, "name": { "ar": "البرجر", "en": "Burgers" }, "sort": 0 }
],
"items": [
{
"id": "chicken-burger",
"type": "menu_item",
"section_id": "burgers",
"sort": 0,
"name": { "ar": "برجر دجاج", "en": "Chicken burger" },
"price_minor": 2300,
"sizes": [
{ "id": "m", "name": { "ar": "وسط", "en": "Medium" }, "price_minor": 2300 },
{ "id": "l", "name": { "ar": "كبير", "en": "Large" }, "price_minor": 2990 }
],
"group_ids": ["sauce"],
"order_types": { "pickup": true, "delivery": true, "dine_in": true }
}
],
"groups": [
{
"id": "sauce", "name": { "ar": "الصوص", "en": "Sauce" }, "required": true, "min": 1, "max": 1,
"options": [
{ "id": "hot", "name": { "ar": "صوص حار", "en": "Hot sauce" }, "price_minor": 230, "image": null },
{ "id": "none", "name": { "ar": "بدون صوص", "en": "No sauce" }, "price_minor": 0, "image": null }
]
}
],
"state": { "paused": false, "sold_out": { "items": [], "sizes": [], "options": [] }, "prices": { "items": [], "sizes": [], "options": [] } }
}ثم انشرها:
aurmap PUT /v1/places/plc_test_olaya/menu "$(cat menu.json)"{ "place_id": "plc_test_olaya", "version": 1, "prev_version": 0, "kind": "full", "status": "processing", "hash": "9f2c4be1d07a65e3c1f8a2b4d6e8f0a1b3c5d7e9f1a3b5c7d9e1f3a5b7c9d1e3", "warnings": [] }بعد ثوان يصلك menu.changed بالنسخة والبصمة نفسيهما. الصيغة كاملة في الكتالوج. القائمة الآن ظاهرة في تطبيق AurMap التجريبي. المبالغ كلها بالهللة: 2300 تعني 23.00 ريال.
5. استقبل طلبا تجريبيا
اطلب من بيئة التجربة أن تضع طلبا كأن عميلا طلبه من التطبيق:
aurmap POST /v1/sandbox/orders '{"place_id":"plc_test_olaya","items":[{"item_id":"chicken-burger","size_id":"l","qty":1,"options":[{"group_id":"sauce","option_id":"hot"}]}],"payment":{"method":"card"}}'يصل إلى عنوان webhook عندك حدث order.created:
{
"delivery_id": "dlv_test_01JA9Y3K",
"mode": "test",
"events": [
{
"event_id": "evt_test_01JA9Y3J8Q",
"type": "order.created",
"seq": 3,
"data": {
"order": {
"order_id": "ord_test_7m1x9c",
"number": "M-1001",
"status": "received",
"accept_by": "2026-10-14T12:35:05Z",
"items": [ { "line_id": "1", "item_id": "chicken-burger", "size_id": "l", "qty": 1, "line_total_minor": 3220 } ],
"totals": { "currency": "SAR", "total_minor": 3220 },
"payment": { "method": "card", "status": "paid", "amount_minor": 3220 }
}
}
}
]
}تحقق من التوقيع أولا (انظر الأحداث)، ثم رد بـ 200 خلال 10 ثوان. الرد لا يعني القبول. اقبل الطلب قبل accept_by:
aurmap POST /v1/orders/ord_test_7m1x9c/accept '{"prep_minutes":15,"external_order_id":"POS-88231"}'
aurmap POST /v1/orders/ord_test_7m1x9c/status '{"status":"ready"}'
aurmap POST /v1/orders/ord_test_7m1x9c/status '{"status":"completed"}'{ "order_id": "ord_test_7m1x9c", "status": "completed", "version": 4 }هذا أول طلب ناجح. جرب أيضا الإلغاء من العميل وانتهاء مهلة القبول من بيئة التجربة.
6. انتقل إلى التشغيل
- أكمل قائمة الاعتماد في لوحة المطورين. التفاصيل في الانتقال إلى التشغيل.
- بعد الاعتماد تحصل على مفاتيح التشغيل
pk_live_xxxوsk_live_xxx. - غير
AURMAP_HOSTإلى عنوان التشغيل، وأضف عنوان webhook للتشغيل. - اعرض زر «الربط مع AurMap» لتجارك. كل تاجر يربط فروعه بنفسه.