التكاملات

مدفوعات العملات الرقمية للخوادم الخلفية المخصصة

شرح مستقل عن التقنية لدمج Qvard في خادمك الخاص: نموذج الطلب، وإنشاء الدفعة، والـ webhook، والمطابقة، وقائمة تحقق قبل الإطلاق، مع أمثلة بلغة Python.

إن كان متجرك أو خدمتك أو منصتك يعمل على خادم خلفي خاص بك فلا تحتاج إلى إضافة: يحتاج Qvard إلى استدعاء واحد ينشئ دفعة ونقطة نهاية واحدة تستقبل النتيجة. يمر هذا الدليل بالتكامل بطريقة تناسب أي لغة وإطار عمل، مع أمثلة بـ Python، ويغطي ما يجعله موثوقًا: نموذج الطلب، وخاصية idempotent، والمطابقة، وقائمة تحقق قصيرة قبل الإطلاق.

ما الذي تحتاجه

  • حساب Qvard فيه مشروع ومفتاح API وcallback URL للـ webhook محفوظ في المشروع.
  • نقطة نهاية HTTPS عامة على خادمك للـ webhook.
  • جدول طلبات (أو ما يماثله) يمكن فيه مطابقة الدفعة مع الطلب بمعرّفك الخاص.

لا يوجد بعد SDK ولا sandbox: التكامل HTTP بسيط، ويتم الاختبار بمبالغ حقيقية صغيرة. مرجع صيغ الطلبات في واجهة API لمدفوعات العملات الرقمية للمطورين؛ ويبيّن هذا الدليل كيف تتكامل.

نموذج طلب بسيط

بياناتك أنت تحدد مدى نظافة التكامل. مجموعة دنيا من حقول الطلب:

  • id: رقم طلبك أو فاتورتك. هو الـ id الذي ترسله إلى Qvard والمفتاح الذي يعود في الـ webhook.
  • amount_usd: المبلغ بالدولار الأمريكي، الوحدة التي تُنشأ بها الدفعة.
  • state: مثل awaiting_payment وpaid وcancelled. ضع علامة «مدفوع» من الـ webhook فقط.
  • paid_at وإن شئت id دفعة Qvard من الاستجابة للدعم.

تجنّب وضع منطق الدفع كله في فئة الطلب. وحدة صغيرة تنشئ الدفعة ونقطة نهاية تطبّق الـ webhook تبقيان الشيفرة قابلة للاختبار.

إنشاء الدفعة

عندما يختار العميل الدفع، أنشئ الدفعة من الخادم الخلفي بطلب POST واحد إلى https://api.qvard.com/api/v1/payment. أرسل المفتاح في الترويسة Authorization: Bearer وجسم JSON فيه رقم طلبك كـ id (نص) والمبلغ كـ price بالدولار الأمريكي، واختياريًا paymentSystemId لفتح صفحة الدفع بأصل وشبكة محددين.

الاستجابة 201 مع redirectUrl، عنوان صفحة الدفع المستضافة. وجّه العميل إليه أو ضع الرابط في بريد إلكتروني. قواعد تستحق ترميزها في العميل:

  • المهلة وإعادة المحاولة. استخدم مهلة وأعد المحاولة عند انتهائها أو عند 5xx. إرسال الـ id نفسه لطريقة الدفع نفسها يعيد الدفعة الموجودة، فلا تستطيع إعادة المحاولة إنشاء دفعة ثانية.
  • لا تُعد محاولة 400 («Error validation»، مع رسالة لكل حقل) ولا 401 (مفتاح خاطئ) دون تغيير شيء.
  • المبالغ بالدولار. إن كان متجرك يسعّر بعملة أخرى فحوّل قبل الاستدعاء.
Pythonqvard_client.py
import os
import requests

QVARD_URL = "https://api.qvard.com/api/v1/payment"

def create_payment(order_id: str, amount_usd: float) -> str:
    """Create a Qvard payment for an order and return the hosted payment page URL."""
    response = requests.post(
        QVARD_URL,
        headers={"Authorization": "Bearer " + os.environ["QVARD_API_KEY"]},
        json={"id": order_id, "price": amount_usd},   # id as a string, price in US dollars
        timeout=15,
    )
    if response.status_code == 201:
        return response.json()["redirectUrl"]
    # 400 = "Error validation" with a per-field message, 401 = wrong API key
    raise RuntimeError(f"Qvard {response.status_code}: {response.text}")

استقبال الـ webhook

عند اكتمال الدفعة يرسل Qvard طلب POST إلى callback URL الخاص بك مع الـ id والـ status، موقّعًا في الترويسة X-Qvard-Signature. يجب أن تقوم نقطة نهايتك بما يلي:

  1. التحقق من التوقيع: HMAC-SHA256 بمفتاحك السري على الطابع الزمني والجسم الخام، بمقارنة بزمن ثابت، والرد بـ 400 إن لم يتطابق.
  2. التصرف عند الحالة completed فقط.
  3. تحديث الطلب بشرط، «مدفوع إن كان ما زال بانتظار الدفع»، فلا تفعل التكرارات شيئًا.
  4. وضع العمل البطيء في الطابور والرد بـ HTTP 200 بالضبط.

يعيد Qvard محاولة أي رد آخر أو انتهاء مهلة أو إعادة توجيه، خمس محاولات في نحو ست دقائق، لذا فعمليات التسليم المكررة أمر طبيعي. تفاصيل إعادة المحاولة في استراتيجية إعادة محاولة الـ webhook في أنظمة الدفع، وقواعد الأمان في كيف تؤمّن webhook مدفوعات العملات الرقمية.

Pythonwebhook.py
import os
from fastapi import FastAPI, Request, Response
from qvard import Qvard

app = FastAPI()
qvard = Qvard(os.environ["QVARD_API_KEY"])

@app.post("/webhooks/qvard")
async def qvard_webhook(request: Request):
    try:
        body = qvard.webhooks.construct_event(await request.body(), request.headers.get("X-Qvard-Signature"), os.environ["QVARD_API_KEY"])
    except ValueError:
        return Response(status_code=401)

    if body.get("status") == "completed":
        # Only changes an order that is not paid yet, so repeated deliveries are harmless.
        changed = await db.execute(
            "UPDATE orders SET state = 'paid', paid_at = now() WHERE id = :id AND state = 'awaiting_payment'",
            {"id": body.get("id")},
        )
        if changed:
            await queue.enqueue("fulfil_order", body["id"])

    return Response(status_code=200)

المدفوعات الجزئية والأعطال وما يراه العميل

قرّر ما تعنيه كل حالة دفعة للطلب:

  • wait: بانتظار الدفع.
  • partial: وصل أقل من المبلغ كاملًا؛ لا يُرسل webhook الاكتمال. أبقِ الطلب مفتوحًا، وأخبر العميل بمقدار ما ينقص، أو ألغِ وأعد المال.
  • completed: وصل المبلغ كاملًا؛ ضع علامة «مدفوع» على الطلب.
  • rejected: اعرض طريقة دفع أخرى.

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

المطابقة وقائمة التحقق قبل الإطلاق

أضف فحصًا يوميًا يقارن الطلبات التي تعدّها مدفوعة أو غير مدفوعة بالمدفوعات والرصيد في لوحة Qvard؛ فالدفعة التي تظهر مكتملة بينما طلبك غير مدفوع إشعار فائت، يمكنك إعادة إرساله من اللوحة.

قبل الإطلاق:

  • مفتاح API في متغير بيئة أو مدير أسرار، وليس في المستودع أبدًا؛
  • callback URL محفوظ وعام وبـ HTTPS ويمكن الوصول إليه من خارج شبكتك؛
  • نقطة النهاية تردّ بـ 200 بالضبط وبسرعة وهي آمنة إذا نُفّذت مرتين؛
  • دفعت مبلغًا حقيقيًا صغيرًا ورأيت الطلب يصبح مدفوعًا؛
  • جعلت نقطة النهاية تفشل مرة ورأيت Qvard يعيد المحاولة دون تنفيذ مزدوج؛
  • سحبت مبلغًا صغيرًا إلى محفظتك. السحب لا يكلّف إلا رسوم الشبكة؛ والسحب إلى حساب مصرفي بالعملة الورقية غير متاح.

الشروط التجارية في صفحة الأسعار، وفاتورة تجريبية تُظهر ما يراه عميلك.

FAQ

هل يوجد SDK للغتي؟

لا. التكامل HTTP بسيط: طلب POST واحد لإنشاء دفعة وwebhook واحد لاستقبال النتيجة. تُظهر الأمثلة في هذا الدليل النمط بـ Python، وينتقل إلى أي لغة.

كيف أطابق دفعة مع طلب؟

أرسل رقم طلبك الخاص كـ id عند إنشاء الدفعة. يعود الـ id نفسه في الـ webhook.

هل يوجد sandbox للاختبار؟

ليس بعد. استخدم مبالغ حقيقية صغيرة وفاتورة تجريبية لرؤية صفحة الدفع.

ماذا لو كان خادمي متوقفًا عند اكتمال دفعة؟

يعيد Qvard المحاولة خمس مرات خلال نحو ست دقائق. بعد ذلك أعد إرسال إشعار الدفعة من اللوحة؛ والمعالج idempotent يجعل ذلك آمنًا.

مقالات ذات صلة

مقالات ذات صلة