المطورون/التكامل

المنتجات والطلبات

يشرح هذا الدليل عملية الشراء كاملة: تتحقق من رصيدك، وتختار المنتج، وتعرف سعره، ثم تطلبه وتستلم الأكواد.

ذات صلة: المصادقة · القواعد العامة · Webhook

#الحساب والرصيد

#الحساب

يعرض GET/api/v1/account بيانات شركتك، ويبيّن ما إذا كان الوصول إلى API مفعّلًا.

JSON
{
  "merchant_id": "M00000001",
  "name": "Acme Shop",
  "legal_name": "Acme Shop Ltd",
  "billing_email": "[email protected]",
  "status": "active",
  "kyb_status": "approved",
  "api_access_enabled": true,
  "default_currency": "USD",
  "purchase_limits": {
    "currency": "USD",
    "verified": true,
    "max_order_amount": "1000.00",
    "daily_order_amount_limit": "10000.00",
    "daily_order_count_limit": 1000,
    "used_today_amount": "120.50",
    "used_today_count": 3,
    "day_resets_at": "2026-10-01T00:00:00+00:00"
  }
}
  • default_currency هي عملة محفظتك، وكل الأسعار التي تدفعها بهذه العملة.
  • تتحول قيمة api_access_enabled إلى true بعد موافقة CardV على شركتك.

#الرصيد

يعرض GET/api/v1/balance المبلغ المتاح لك للشراء.

JSON
{
  "currency": "USD",
  "balance": "1520.40",
  "reserved_amount": "0.00",
  "available_balance": "1520.40",
  "low_balance_threshold": "200.00",
  "low_balance_notified_at": null,
  "is_active": true
}
  • available_balance هو ما يمكنك إنفاقه الآن، ويساوي balance ناقص reserved_amount.
  • يُرفض أي طلب تتجاوز قيمته available_balance، ولا يُخصم أي مبلغ.
  • low_balance_threshold هو الحد الذي يُرسل عنده بريد تنبيه انخفاض الرصيد، وتضبطه من البوابة.
  • لشحن المحفظة، استخدم البوابة.

#سعر الصرف

يعيد GET/api/v1/fx-rates?quote=EUR سعر الصرف من USD إلى عملة أخرى.

استخدمه إذا كان متجرك يبيع بعملة غير USD. تخصم CardV من محفظتك دائمًا بالـ USD، وهذا السعر يساعدك فقط في تحديد أسعارك.

JSON
{
  "base": "USD",
  "quote": "EUR",
  "rate": "0.9234",
  "as_of": "2026-10-11T07:05:00Z"
}
  • quote رمز عملة وفق ISO 4217، مثل EUR أو GBP أو JPY.
  • base اختياري، ولا يُدعم سوى USD.
  • rate هو عدد وحدات quote التي تحصل عليها مقابل 1 USD. وهو نص عشري، فلا تقرأه كرقم float.
  • as_of هو وقت آخر تحديث لهذا السعر من CardV. تُحدَّث الأسعار كل ساعة.
  • يعيد quote=USD القيمة "rate": "1".
  • احفظ السعر لديك، ويكفي الاستعلام عنه بضع مرات في اليوم.
الحالةالمعنىماذا تفعل
400quote غير موجود أو ليس رمزًا من 3 أحرف، أو base ليس USDصحّح الطلب
404No exchange rate for this currency.حدّد الأسعار بهذه العملة بنفسك
503Exchange rate temporarily unavailable.واصل استخدام آخر سعر حفظته وأعد المحاولة لاحقًا

وقّع هذا الطلب مثل أي طلب آخر. يتضمن المسار الموقَّع سلسلة الاستعلام، مثل /api/v1/fx-rates?quote=EUR.

#المنتجات (SKU)

الـ SKU منتج واحد يمكنك شراؤه، مثل "Steam Wallet 10 USD". ورقمه يشبه S000456، وتستخدم هذا الرقم لمعرفة السعر ولإرسال الطلب.

#نماذج المنتجات

كل وحدة SKU تتبع أحد هذه النماذج. اقرأ denomination_type وproduct_type لتمييزها.

النموذجكيف تتعرّف عليهالسعرالطلبما تستلمه
قيمة ثابتةdenomination_type: "fixed"merchant_price هو سعر الوحدة الواحدة.أرسل quantity.أكواد في deliveries.
قيمة مرنةdenomination_type: "range"من merchant_price_min إلى merchant_price_max. السعر الفعلي يعتمد على المبلغ: اطلب عرض سعر.أرسل quantity وamount.أكواد في deliveries.
شحن مباشرproduct_type: "direct_charge"مثل القيمة الثابتة.أرسل أيضًا inputs (راجع الشحن المباشر).عادةً بلا أكواد. succeeded تعني أن الحساب شُحن.
شحن رصيد الهاتف المحمولليس في هذا الكتالوجعرض سعر خاص بهواجهة API خاصة بهراجع شحن رصيد الهاتف المحمول.
  • vertical هو خط المنتجات وليس النموذج. قد يكون للشحن المباشر أيضًا vertical: "gift_card".
  • أي وحدة بقيمة ثابتة أو مرنة يمكن تسليمها على شكل رابط استرداد من CardV بدلًا من الكود. عندها يكون للوحدة delivery_mode: "voucher". تستلم رابطًا (delivery_type: "link"، والرابط في redeem_url). يفتحه عميلك ليحصل على الكود. أرسله إلى عميلك كما ترسل الكود.

يعرض GET/api/v1/skus قائمة المنتجات المتاحة لك. مثال:

HTTP
GET /api/v1/skus?search=steam&region=US&limit=50&offset=0

عوامل التصفية (كلها اختيارية):

عامل التصفيةمثالما يطابقه
searchsteamرقم المنتج أو اسمه أو علامته التجارية
brandSteamاسم العلامة التجارية (لا فرق بين الأحرف الكبيرة والصغيرة)
regionUSرمز الدولة أو اسمها. GLC = عالمي، EU = أوروبا
categoryTravelالفئة التجارية، مثل Travel وDigital Wallets & Payment وGame Credits
verticalgift_cardفئة المنتج
product_typepin_codeطريقة التسليم

الصفحات: أرسل limit (الافتراضي 100، والحد الأقصى 500) وoffset. كرّر الطلب مع زيادة offset حتى تصل قيمته إلى count.

JSON
{
  "count": 7,
  "limit": 2,
  "results": [
    {
      "sku_id": "S000456",
      "product_id": "P000123",
      "name": "Steam Wallet 10 USD",
      "product_name": "Steam Wallet US",
      "brand": "Steam",
      "region": "US",
      "vertical": "gift_card",
      "product_type": "pin_code",
      "denomination_type": "fixed",
      "denomination_value": "10",
      "face_currency": "USD",
      "merchant_price": "9.25",
      "merchant_price_min": "9.25",
      "merchant_price_max": "9.25",
      "settlement_currency": "USD",
      "availability": "available",
      "min_quantity": 1,
      "max_quantity": 100,
      "required_input_schema": [],
      "...": "more fields"
    },
    {
      "sku_id": "S006126",
      "product_id": "P002210",
      "name": "Apple ES",
      "product_name": "Apple ES",
      "brand": "Apple",
      "region": "ES",
      "vertical": "gift_card",
      "product_type": "pin_code",
      "denomination_type": "range",
      "denomination_value": "0",
      "min_face_value": "2",
      "max_face_value": "250",
      "amount_step": null,
      "face_currency": "EUR",
      "merchant_price": "2.28",
      "merchant_price_min": "2.28",
      "merchant_price_max": "284.15",
      "price_label": "From 2.28 USD",
      "settlement_currency": "USD",
      "availability": "available",
      "...": "more fields"
    }
  ],
  "filter_options": {"brands": [], "regions": [], "categories": [], "verticals": []}
}

يُرجع GET/api/v1/skus/{sku_id} منتجًا واحدًا بالحقول نفسها.

أهم الحقول:

الحقلالمعنى
sku_idالرقم الذي تستخدمه لمعرفة السعر وللطلب.
merchant_priceسعرك للوحدة بعملة settlement_currency. في وحدات range هو سعر min_face_value فقط، أي سعر بداية. لا تستخدمه لمبالغ أخرى: اطلب عرض سعر مع amount.
availabilityavailable أو unavailable. لا تطلب إلا المنتجات available.
denomination_typefixed أو range. راجع القيمة الثابتة والقيمة المرنة.
denomination_valueالقيمة الاسمية لوحدة fixed. تكون "0" في وحدة range.
min_face_value، max_face_valueوحدات range: أقل وأعلى مبلغ يمكن لعميلك اختياره، بعملة face_currency.
merchant_price_min، merchant_price_maxسعر أقل مبلغ وأعلى مبلغ. يساويان merchant_price في وحدات fixed. استخدمهما لعرض نطاق سعري، واطلب دائمًا عرض سعر للمبلغ الدقيق قبل الطلب. تكون قيمة merchant_price_max هي "" عندما يتعذّر تسعيره حاليًا.
price_labelmerchant_price كنص للعرض. في وحدات range يبدأ بـ From، مثل From 2.28 USD.
face_value_labelالقيمة الاسمية كنص للعرض، مثل 10 USD أو 50 - 1000 GBP.
discountالخصم على القيمة الاسمية، مثل 7.50% off face value. فقط لوحدات fixed التي تكون عملة البطاقة فيها هي عملة محفظتك، وإلا فهي "".
amount_stepللمنتجات ذات القيمة المرنة فقط. يجب أن يكون المبلغ من مضاعفات هذه القيمة، فمثلًا "1" تعني أعدادًا صحيحة فقط. وتعني null عدم وجود خطوة.
face_currencyالعملة المطبوعة على البطاقة، وقد تختلف عن عملة محفظتك.
min_quantity، max_quantityعدد الوحدات المسموح به في بند الطلب الواحد.
product_typepin_code (تستلم كودًا) أو direct_charge (نشحن حساب العميل مباشرة).
delivery_typeما يسلّمه المورّد: code أو code_pin أو code_serial أو url أو direct_charge. عندما تكون delivery_mode هي voucher تستلم رابطًا بدلًا من ذلك.
delivery_modecode (تستلم الكود نفسه) أو voucher (تستلم رابط استرداد من CardV).
voucher_instructionsلوحدات voucher: نص يشرح لعميلك كيف يستخدم الرابط. وإلا فهي "".
vertical، categoryخط المنتجات وفئة النشاط، للتصفية والعرض.
region، region_name، region_labelرمز البلد أو المنطقة، واسمه، ونص للعرض.
required_input_schemaالبيانات التي يجب إرسالها في الشحن المباشر.
brand_logo_url، image_urlصور تستضيفها CardV، أو "".
description، redemption_instructions، terms، disclaimerنصوص يمكنك عرضها على عملائك.

نصائح:

  • لا تظهر لك إلا المنتجات النشطة والمتاحة لحسابك. أما غيرها فيُرجع 404.
  • حدّث قائمة المنتجات كل 5 إلى 15 دقيقة، واطلب عرض السعر دائمًا قبل الطلب مباشرة.
  • اعرض على عملائك الأسعار من قائمتك المتزامنة. لا تستدعِ واجهة عرض السعر عند كل مشاهدة للصفحة أو لكل زائر.
  • تتبع أسعار وحدات المبلغ المرن تكلفة المورّد وقد تتغيّر بضع مرات في اليوم. حدّث merchant_price_min وmerchant_price_max مع كل مزامنة للمنتجات.
  • يعرض filter_options العلامات التجارية والمناطق وفئات المنتجات التي يمكنك التصفية بها.

#المزامنة حسب المنتج

إذا كان متجرك يعرض صفحة واحدة لكل منتج مع اختيار القيمة، فزامن المنتجات بدلًا من وحدات SKU. تعرض GET/api/v1/products قائمة المنتجات، ويحمل كل منتج جميع وحدات SKU التي يمكنك شراؤها منه.

HTTP
GET /api/v1/products?brand=Steam&region=GB&limit=50&offset=0

تقبل عوامل التصفية والتقسيم إلى صفحات نفسها التي تقبلها GET/api/v1/skus. يعدّ count المنتجات، ويعدّ sku_count وحدات SKU التابعة لها.

JSON
{
  "count": 1,
  "sku_count": 4,
  "limit": 50,
  "results": [
    {
      "product_id": "P000123",
      "product_name": "Steam Wallet UK",
      "brand": "Steam",
      "category": "Gaming",
      "region": "GB",
      "product_type": "pin_code",
      "image_url": "https://b2b.cardv.net/api/v1/catalog-assets/steam.png",
      "required_input_schema": [],
      "skus": [
        {
          "sku_id": "S000456",
          "name": "Steam Wallet 5 GBP",
          "label": "5 GBP",
          "denomination_type": "fixed",
          "denomination_value": "5",
          "face_currency": "GBP",
          "merchant_price": "7.61",
          "settlement_currency": "USD",
          "availability": "available",
          "min_quantity": 1,
          "max_quantity": 100,
          "...": "more fields"
        }
      ]
    }
  ],
  "filter_options": {"brands": [], "regions": [], "categories": [], "verticals": []}
}

تعيد GET/api/v1/products/{product_id} منتجًا واحدًا مع وحدات SKU التابعة له، إضافة إلى description وredemption_instructions وterms وdisclaimer.

  • لكل وحدة SKU داخل skus الحقول والقيم نفسها الموجودة في GET/api/v1/skus. اطلب السعر واطلب الشراء بـ sku_id كالمعتاد.
  • استخدم label نصًا للخيار، مثل 5 GBP أو Tinder Plus 1 Month. بعض المنتجات باقات وليست قيمًا.
  • للمنتج الواحد عملة قيمة اسمية واحدة ونوع قيمة واحد. وحدة SKU ذات القيمة المرنة منتج مستقل دائمًا.
  • لا تتضمن القائمة النصوص الطويلة. اقرأها مرة واحدة لكل منتج من GET/api/v1/products/{product_id}.

#القيمة الثابتة والقيمة المرنة

لمعظم المنتجات قيمة اسمية ثابتة، مثل 10 USD. ولبعضها قيمة مرنة ضمن نطاق: يختار عميلك المبلغ، مثلًا من 5 إلى 500 USD.

النوععند طلب عرض السعرعند إرسال الطلب
fixedأرسل quantityلا ترسل amount
rangeأرسل quantity وamountأرسل amount

في المنتج ذي القيمة المرنة، يجب أن يقع amount بين min_face_value وmax_face_value، ويكون بعملة face_currency.

سعر وحدة المبلغ المرن. في قوائم الوحدات والمنتجات، merchant_price وprice_label هما سعر min_face_value فقط. ويعطي merchant_price_min وmerchant_price_max سعر أقل مبلغ وأعلى مبلغ. سعر أي مبلغ بينهما ليس مضاعفًا بسيطًا لأيٍّ منهما. قبل تحديد سعر البيع أو الطلب، اطلب عرض سعر بالمبلغ amount الدقيق وأرسل merchant_price من ذلك العرض كقيمة expected_unit_price.

في بعض المنتجات ذات القيمة المرنة يوجد أيضًا amount_step. إذا لم تكن قيمته null، فيجب أن يكون amount من مضاعفاته. مثلًا، مع "amount_step": "1" يمكنك إرسال 25 لكن لا يمكنك إرسال 25.50. عرض السعر أو الطلب بمبلغ لا يتوافق مع الخطوة يُرجع HTTP 400 ولا يُخصم أي مبلغ.

#الشحن المباشر

بعض المنتجات تشحن حساب عميلك مباشرة، مثل حساب في لعبة. وفي هذه الحالة تحتاج CardV إلى بيانات الحساب، ويذكرها المنتج هكذا:

JSON
"required_input_schema": [
  {"key": "player_id", "label": "Player ID", "type": "text", "required": true},
  {"key": "server", "label": "Server", "type": "text", "required": false}
]

أرسل القيم في الحقل inputs داخل بند الطلب، مستخدمًا كل key:

JSON
"inputs": {"player_id": "123456789", "server": "EU"}
  • كل حقل إلزامي ما لم يُذكر فيه "required": false. type تلميح لنوع حقل النموذج لديك، مثل text.
  • إذا نقصت قيمة إلزامية، يُرفض الطلب بخطأ في items.
  • هذه القيم بيانات شخصية لعميلك، فاحمِها (راجع الأمان).

#عرض السعر

يخبرك عرض السعر بالسعر الحالي لكمية معيّنة.

HTTP
GET /api/v1/skus/S000456/quote?quantity=2
GET /api/v1/skus/S000789/quote?quantity=1&amount=25.00
JSON
{
  "sku_id": "S000456",
  "settlement_currency": "USD",
  "merchant_price": "9.25",
  "quantity": 2,
  "total_price": "18.50",
  "min_quantity": 1,
  "max_quantity": 100,
  "availability": "available"
}
  • عرض السعر لا يثبّت السعر، فالأسعار قد تتغيّر في أي وقت.
  • اطلب عرض السعر مرة واحدة فقط عندما يُتمّ عميلك الشراء، مع مهلة قصيرة مثل 5 ثوانٍ. وإذا انتهت المهلة، فاستمر في عرض سعرك المتزامن وأعد المحاولة؛ ولا تعرض صفحة خطأ أبدًا لأن عرض السعر تأخّر.
  • لتحمي نفسك، أرسل قيمة merchant_price في الحقل expected_unit_price عند الطلب. أرسل السعر الوارد في عرض السعر، لا سعرًا حسبته بنفسك: يجب أن يطابق تمامًا حتى آخر سنت. فإذا تغيّر السعر، ترفض CardV الطلب ولا تخصم شيئًا.
  • إذا كانت الكمية أو المبلغ خارج النطاق، أو لم يكن المبلغ من مضاعفات amount_step، تحصل على HTTP 400 مع خطأ في quantity أو amount.

#إرسال طلب

يشتري POST/api/v1/orders منتجًا أو أكثر، ويدفع قيمته من محفظتك. ويجب توقيع هذا الاستدعاء، مثل كل استدعاء.

JSON
{
  "external_order_id": "SHOP-20260929-10001",
  "items": [
    {"sku_id": "S000456", "quantity": 2, "expected_unit_price": "9.25"},
    {"sku_id": "S000789", "amount": "25.00", "expected_unit_price": "23.75"},
    {
      "sku_id": "S000900",
      "expected_unit_price": "4.90",
      "inputs": {"player_id": "123456789"}
    }
  ]
}
الحقلإلزامي؟المعنى
external_order_idنعمرقم طلبك، من 1 إلى 120 حرفًا، ولا يتكرر.
itemsنعمبند واحد أو أكثر.
items[].sku_idنعمالمنتج الذي تشتريه.
items[].quantityلاعدد الوحدات. الافتراضي 1.
items[].amountللمنتجات ذات القيمة المرنةالقيمة الاسمية التي تشتريها. يجب أن تتوافق مع min_face_value وmax_face_value وamount_step.
items[].expected_unit_priceموصى بهقيمة merchant_price من عرض السعر. أرسله دائمًا.
items[].inputsللشحن المباشربيانات الحساب في حالة الشحن المباشر.

عندما تقبل CardV الطلب، تخصم المبلغ الإجمالي كاملًا من محفظتك فورًا. ثم يبدأ التسليم في الخلفية.

يكون الرد HTTP 201:

JSON
{
  "idempotent_replay": false,
  "order": {
    "order_id": "O-00001234",
    "external_order_id": "SHOP-20260929-10001",
    "status": "accepted",
    "total_amount": "46.20",
    "...": "more fields"
  }
}

احفظ order.order_id. هذا الرد لا يحتوي على الأكواد أبدًا، بل تقرؤها لاحقًا (قراءة الطلب).

#الطلبات المرفوضة

الطلب المرفوض يُرجع HTTP 400 ولا يُخصم أي مبلغ. ومفتاح الخطأ يوضح السبب:

المفتاحالسببما الذي تفعله
itemsتغيّر السعر، أو المنتج غير متاح، أو المبلغ غير صحيح، أو نقصت بياناتاطلب عرض سعر جديدًا، وأصلح المشكلة، ثم أعد الإرسال
balanceرصيد محفظتك لا يكفياشحن محفظتك من البوابة
riskتجاوزت الحد الأقصى للطلب الواحد أو الحد اليوميتواصل مع CardV
external_order_idرقم طلبك مستخدم من قبل لطلب مختلفراجع إعادة المحاولة بأمان

مثال على تغيّر السعر:

JSON
{
  "items": "SKU S000456 price changed from 9.25 to 9.41 USD; refresh quote and confirm again."
}

لحسابك حدود للطلب الواحد، وللإنفاق اليومي، ولعدد الطلبات اليومية. يعرضها GET/api/v1/account في purchase_limits، مع ما استخدمته اليوم. القيمة 0 تعني عدم وجود حد. تُصفَّر الحدود اليومية عند 00:00 UTC.

#إعادة المحاولة بأمان

رقم طلبك (external_order_id) يحميك من الشراء مرتين. إذا أرسلت الطلب نفسه مرة أخرى برقم الطلب نفسه، لا تخصم CardV المبلغ مرة ثانية، بل تُرجع الطلب الموجود لديها.

ما ترسلهما تحصل عليه
رقم طلب جديدHTTP 201. طلب جديد، ويُخصم المبلغ من محفظتك.
رقم الطلب نفسه والطلب نفسهHTTP 200 و"idempotent_replay": true. الطلب الموجود، دون أي خصم.
رقم الطلب نفسه لكن بطلب مختلفHTTP 400 على external_order_id. لا يحدث شيء.

"الطلب نفسه" يعني البنود نفسها، بالترتيب نفسه، وبالمنتج والكمية والمبلغ والبيانات نفسها. وإذا أرسلت expected_unit_price، فيجب أن يطابق سعر الطلب الأول.

تتعرّف CardV على الطلب المكرر قبل التحقق من الرصيد والسعر. لذلك تُرجع الطلب الأول دائمًا، حتى لو تغيّر السعر بعده.

#خطوات إعادة المحاولة

إذا لم تحصل على رد واضح، فأرسل الطلب نفسه مرة أخرى ببساطة.

Text
POST /orders برقم الطلب R
 ├─ 201 أو 200 → احفظ order_id. انتهى.
 ├─ 400 items / balance / risk → لم يُنشأ أي طلب.
 │      أصلح السبب وأعد الإرسال. يمكنك استخدام R نفسه.
 ├─ 400 external_order_id → الرقم R يخص طلبًا آخر. توقّف وتحقّق.
 ├─ 403 خطأ في التوقيع → وقّع من جديد وأرسل المحتوى نفسه.
 ├─ 429 → انتظر مدة Retry-After، ثم وقّع من جديد وأرسل المحتوى نفسه.
 └─ انتهاء المهلة أو 5xx أو انقطاع الاتصال
        → أرسل المحتوى نفسه مرة أخرى بالرقم R نفسه.
          ستحصل على 201 (المحاولة الأولى لم تصل) أو 200 (وصلت).

القواعد:

  • لا تنشئ رقم طلب جديدًا لمجرد أن الرد لم يصلك. فإذا كان الطلب الأول قد وصل، سيؤدي الرقم الجديد إلى شراء كل شيء مرتين.
  • كل إعادة إرسال تحتاج إلى طابع زمني وقيمة nonce وتوقيع جديدة، مع بقاء المحتوى كما هو.

#قراءة الطلب

يُرجع GET/api/v1/orders/{order_id} الطلب وحالته وأكواده.

JSON
{
  "order_id": "O-00001234",
  "external_order_id": "SHOP-20260929-10001",
  "status": "succeeded",
  "currency": "USD",
  "total_amount": "18.50",
  "created_at": "2026-09-29T08:15:30.123456Z",
  "updated_at": "2026-09-29T08:15:41.004211Z",
  "items": [
    {
      "sku_id": "S000456",
      "product_name": "Steam Wallet US",
      "quantity": 2,
      "unit_price": "9.25",
      "total_price": "18.50",
      "delivery_count": 2,
      "deliveries": [{"...": "see Codes below"}]
    }
  ],
  "...": "more fields"
}
  • total_amount هو المبلغ الذي خُصم منك عند قبول الطلب.
  • items[].unit_price هو السعر المثبّت لهذا الطلب.
  • يحتوي items[].deliveries على الأكواد كاملة، فتعامل مع الرد كمعلومة سرية.
  • invoice_url وdelivery_file_url مساران للفاتورة ولملف الأكواد بصيغة CSV. وكلاهما خاص بالبوابة، ومع مفتاح API يُرجعان HTTP 403.
  • يُرجع الرد أيضًا id (رقم قديم، لا تستخدمه)، وevents (سجل للعرض فقط)، ومدى تقدّم التسليم في كل بند. يمكنك تجاهل هذه الحقول.
  • رقم طلب غير معروف يُرجع HTTP 404.

#حالة الطلب والأكواد

#الحالة

Text
accepted ──► processing ──► succeeded
                  │
                  ├──► partially_succeeded   (سُلّمت بعض البنود ولم يُسلَّم بعضها)
                  │
                  └──► failed ──► refunded   (أُعيد المبلغ إلى محفظتك)
الحالةهل اكتمل؟ما الذي تفعله
acceptedلاانتظر. خُصم المبلغ من المحفظة، ولم يبدأ التسليم بعد.
processingلاانتظر. لا ترسل الطلب مرة أخرى.
succeededنعماقرأ الأكواد وسلّمها لعميلك.
partially_succeededنعمسلّم ما وصل. يُسترد الباقي لاحقًا.
failedليس بعدانتظر refunded. الفشل لا يعني أن المبلغ أُعيد بعد.
refundedنعمعاد المبلغ إلى محفظتك.

إذا لم تستخدم Webhook، فاستعلم عن الطلب بهذا الترتيب: بعد 5 ثوانٍ، ثم 10 ثوانٍ، ثم 30، ثم 60، ثم كل 5 دقائق. والتزم بحد الطلبات. تكتمل معظم الطلبات خلال ثوانٍ، لكن بعضها يحتاج إلى مراجعة يدوية وقد يستغرق ساعات.

#الأكواد

كل وحدة مُسلَّمة هي عنصر واحد داخل items[].deliveries:

JSON
{
  "status": "stored",
  "delivery_type": "card_pin",
  "card_number": "X1234",
  "pin_code": "9876",
  "redeem_url": "",
  "expiry_date": "2027-09-29",
  "instructions": "Redeem at ..."
}
الحقلما هو
card_numberالكود الرئيسي: رقم البطاقة أو كود القسيمة أو رقم PIN.
pin_codeالكود الثاني، مثل رقم PIN أو رمز الأمان. يكون فارغًا إذا لم يوجد.
redeem_urlرابط الاسترداد. في التسليم من نوع link يكون الرابط نفسه هو الكود.
expiry_dateآخر يوم يمكن فيه استخدام الكود، بالصيغة YYYY-MM-DD. تعني "" أن المورّد لم يحدد تاريخ انتهاء. وهذا لا يعني أن الكود قد انتهت صلاحيته.
  • سلّم عميلك كل حقل غير فارغ: card_number وpin_code وredeem_url وexpiry_date وinstructions.
  • يوضح delivery_type نوع ما استلمته: code أو card_pin أو link أو code_link أو qr.
  • احفظ redeem_url سرًا كما تحفظ الكود.
  • لا تحذف الكود أو تخفيه أو تلغيه أبدًا لأن expiry_date فارغ. اعرض تاريخ الانتهاء لعميلك فقط عندما لا يكون فارغًا.
  • لا تسلّم عميلك أبدًا وحدة حالتها voided.
  • منتجات الشحن المباشر لا تُسلَّم فيها أكواد عادةً، والحالة succeeded تعني أن الحساب شُحن.
  • رسائل Webhook لا تحتوي على الأكواد أبدًا. اقرأ الطلب بعد وصول الرسالة.

هل لديك سؤال حول التكامل؟ راسلنا على [email protected] مع ذكر Merchant ID ومعرّف الطلب أو الاستدعاء.