# @xpayeg/sdk (/ar/sdk/sdk-js)

الـ JavaScript SDK بتاع المتصفّح. مرجع لكل تصدير عام، وتوقيع دالة، ونوع خيار.

الـ JavaScript SDK بتاع XPay مكتبة صغيّرة بتتحمّل من الـ CDN، وبتديك `XPayInstance` مكتوب بالأنواع من مفتاحك القابل للنشر. ومنها تقدر تركّب واجهة دفع كـ Elements، أو تفتح drop-in checkout، أو تشغّل `initCheckout` باستدعاء واحد وتأكّد دفعة.

```sh
pnpm add @xpayeg/sdk
# or: npm install @xpayeg/sdk / yarn add @xpayeg/sdk
```

الـ package بيوفّر بناءات ESM وCJS، زائد أنواع TypeScript كاملة. وقت التشغيل نفسه بيتحمّل عند الطلب من `https://checkout.xpay.app/v1/sdk.js`.

فيه طريقتين لتحميل الـ SDK، وكل واحدة بتعرض الـ factory باسم مختلف. ده أكتر غلط شائع في التكامل، فخلّيك مظبّطه من البداية:

<Tabs items="[&#x22;مع bundler (npm)&#x22;, &#x22;HTML عادي (بدون build)&#x22;]">
  <Tab value="مع bundler (npm)">
    ```ts
    // استورد loadXPay واعمله await. ده المسار اللي باقي الصفحة بتوثّقه.
    import { loadXPay } from "@xpayeg/sdk";

    const xpay = await loadXPay("pk_test_...");
    ```
  </Tab>

  <Tab value="HTML عادي (بدون build)">
    ```html
    <!-- حطّ الـ CDN script tag، وبعدين استدعي الـ factory العام XPay() اللي الـ runtime
         بيحطّه على window. من غير import، ولا await، ولا build step. -->
    <script src="https://checkout.xpay.app/v1/sdk.js"></script>
    <script>
      const xpay = XPay("pk_test_...");
    </script>
    ```
  </Tab>
</Tabs>

`loadXPay` موجود بس في الـ package بتاع npm؛ والـ CDN runtime بيعرض بس الـ global `XPay`. مش قابلين للتبديل: استدعاء `loadXPay(...)` بعد الـ script tag بيرمي `ReferenceError: loadXPay is not defined`، والـ global `XPay` مش قابل للاستيراد. اختار الصف اللي يناسب الإعداد بتاعك؛ أي حاجة بعد ما تحصل على نسخة `xpay` هي نفسها بالظبط. الصفحة دي بتوثّق مدخل npm (`loadXPay`). على مسار الـ HTML العادي، بدّل `await loadXPay(k)` بـ `XPay(k)` في أي مثال تحت.

<Card icon="<SquareCode />" title="شوفه شغّال: مثال HTML عادي" href="https://github.com/xpayeg/xpay-examples/tree/main/vanilla-html">
  كل نمط في الصفحة دي كملفات HTML عادية جاهزة للتشغيل: CDN script tag + الـ factory العام `XPay()`،
  وسيرفر Express صغيّر، من غير build step. اعمل clone، وحطّ مفاتيح الاختبار، وافتح في المتصفّح.
</Card>

الصفحة دي مرجع لكل تصدير عام. للشروحات، شوف [Drop-in](/integrate/integration-patterns/drop-in) و[Elements](/integrate/integration-patterns/elements) تحت Integrate.

## استخدم الـ package ده لما [#استخدم-الـ-package-ده-لما]

`@xpayeg/sdk` هو الـ SDK الـ **vanilla** وهو الاختيار الصح كل ما تكون مش على React. ده بيغطي:

* HTML العادي والمواقع الثابتة (الـ CDN script tag + الـ factory العام `XPay()`؛ شوف مساري التحميل فوق).
* **Vue، وSvelte، وSolid، وAngular، وLit، وQwik، وAstro،** وأي إطار تاني. استدعي الـ SDK من جوّه دورة حياة مكوّن الإطار ده (mount، وonMount، وما يعادل useEffect، إلخ).
* React Native عن طريق WebView لحد ما ينزل package أصلي.
* سكربتات من ناحية السيرفر محتاجة تكتب حمولات الـ `clientSecret` بالأنواع (أنواع TypeScript بتاعة الـ package مستقلة عن الإطار).

لـ React، [`@xpayeg/react`](/sdk/sdk-react) غلاف راحة رفيع فوق الـ package ده. مبني على `loadXPay`، و`xpay.initCheckout`، و`xpay.elements`، فأي حاجة بتقراها هنا بتنطبق تحت الكواليس هناك كمان.

## البداية السريعة [#البداية-السريعة]

المسار المنصوح بيه هو `loadXPay` على مستوى الموديول، وبعدين `xpay.initCheckout()` بمجرد ما يبقى عندك `clientSecret` من السيرفر بتاعك.

```ts
import { loadXPay } from "@xpayeg/sdk";

// Module-level: call once, share across the app.
const xpayPromise = loadXPay("pk_test_...");

async function startCheckout() {
  const xpay = await xpayPromise;
  if (!xpay) return; // SSR returns null on the server

  // initCheckout accepts a Promise<string> too, so you can pass the fetch directly.
  const checkout = await xpay.initCheckout({
    clientSecret: fetch("/api/create-checkout", { method: "POST" })
      .then((r) => r.json())
      .then((d) => d.clientSecret as string),
  });

  // Mount the payment element.
  const elements = checkout.getElements();
  const paymentElement = elements.create("payment");
  paymentElement.mount("#payment-element");

  // Listen for state changes (promo codes, quantity updates, fee recalcs).
  checkout.on("change", (session) => {
    document.getElementById("total")!.textContent =
      `${session.currency} ${(session.amountTotal / 100).toFixed(2)}`;
  });

  // Confirm when the customer submits.
  document.getElementById("pay")!.addEventListener("click", async () => {
    const result = await checkout.confirm({
      customerDetails: { email: "customer@example.com", name: "Aya Hassan" },
    });
    if (result.type === "error") {
      console.error(result.error.message);
      return;
    }
    window.location.href = "/thank-you";
  });
}
```

## التصديرات بنظرة سريعة [#التصديرات-بنظرة-سريعة]

| التصدير                      | النوع     | يعني إيه                                                                               |
| ---------------------------- | --------- | -------------------------------------------------------------------------------------- |
| `loadXPay(publishableKey)`   | function  | بيحمّل الـ SDK من الـ CDN ويرجّع `XPayInstance` (أو `null` على السيرفر أثناء الـ SSR). |
| `XPayInstance`               | interface | الـ factory بتاع `Elements`، وdrop-in `Checkout`، و`confirmPayment`، و`initCheckout`.  |
| `Elements`                   | interface | بيدير الـ payment elements (`PaymentElement`) ودورة حياة الجلسة.                       |
| `PaymentElement`             | interface | مختار وسيلة دفع قابل للتركيب مع فورم البطاقة، وBNPL، وكشك، ووسائل المحفظة.             |
| `ConfirmPaymentOptions`      | interface | الشكل المُمرَّر لـ `xpay.confirmPayment()` و`checkout.confirm()`.                      |
| `CheckoutOptions`            | interface | إعداد `xpay.checkout()`. drop-in modal أو inline embed.                                |
| `CheckoutInstance`           | interface | مقبض الـ drop-in checkout: `open()`، و`close()`، و`destroy()`، زائد الأحداث.           |
| `CheckoutCompleteResult`     | interface | الحمولة لـ `onComplete` callback بتاع الـ drop-in.                                     |
| `InitCheckoutOptions`        | interface | خيارات `xpay.initCheckout()`. الـ API العصري باستدعاء واحد.                            |
| `InitCheckoutResult`         | type      | بيانات الجلسة مدموجة مع دوال الإجراءات (`confirm`، وأكواد الخصم، إلخ).                 |
| `CheckoutActions`            | interface | دوال الإجراءات اللي بتركب على كائن الـ checkout.                                       |
| `CheckoutSession`            | type      | شكل بيانات الجلسة: المبلغ، والعملة، والحالة، ووسائل الدفع، والبنود.                    |
| `ActionResult`               | type      | tagged union: `{ type: "success", session }` أو `{ type: "error", error }`.            |
| `XPayError`                  | interface | نوع الخطأ الموحَّد عبر كل إجراء في الـ SDK.                                            |
| `Appearance`                 | type      | تجاوزات العلامة التجارية للواجهة المضمّنة (وضع اللون، ونمط الحدّ، والألوان، والخط).    |
| `PaymentElementChangeEvent`  | interface | الحمولة لأحداث الـ change بتاعة `PaymentElement`.                                      |
| `ElementsReadyEvent`         | interface | الحمولة لحدث `"ready"` بتاع `Elements`.                                                |
| `ElementsLoadErrorEvent`     | interface | الحمولة لحدث `"loaderror"` بتاع `Elements`.                                            |
| `CustomerDetails`, `Address` | interface | الأشكال لحقول العميل اللي فورمك بيجمّعها وبتتمرّر وقت التأكيد.                         |
| `PaymentMethodInfo`          | type      | معلومات عن وسيلة دفع متاحة على الجلسة.                                                 |
| `SessionStatus`              | type      | tagged union: `open`، أو `expired`، أو `complete`.                                     |

## `loadXPay(publishableKey)` [#loadxpaypublishablekey]

بيحمّل وقت تشغيل الـ SDK من الـ CDN ويرجّع `XPayInstance`. استدعيه مرة واحدة على مستوى الموديول، مش جوّه مكوّن.

```ts
import { loadXPay } from "@xpayeg/sdk";

const xpayPromise = loadXPay("pk_test_...");
// later, when you have a clientSecret:
const xpay = await xpayPromise;
const elements = xpay.elements({ clientSecret: "cs_test_..." });
```

| البارامتر        | النوع  | الوصف                                                              |
| ---------------- | ------ | ------------------------------------------------------------------ |
| `publishableKey` | string | مفتاح الـ API القابل للنشر بتاعك (`pk_test_...` أو `pk_live_...`). |

بيرجّع `Promise<XPayInstance | null>`. الـ `null` بيرجع أثناء العرض من ناحية السيرفر (مفيش `window`). الـ `XPayProvider` من `@xpayeg/react` بيتعامل مع الـ `null` بسلاسة بإعادة المحاولة على العميل.

وقت التشغيل بيتجاب مرة واحدة؛ واستدعاءات `loadXPay` اللي بعدها بتعيد استخدام نفس الـ script tag. لو فيه سكربت بـ `sdk.js` موجود أصلًا على الصفحة، ما بيتحقنش تاني.

## `XPayInstance` [#xpayinstance]

الـ factory اللي بيرجعلك من `loadXPay`. أربع دوال.

```ts
interface XPayInstance {
  elements(options: ElementsOptions): Elements;
  checkout(options: CheckoutOptions): CheckoutInstance;
  confirmPayment(options: ConfirmPaymentOptions): Promise<ActionResult>;
  initCheckout(options: InitCheckoutOptions): Promise<InitCheckoutResult>;
}
```

### `elements(options)` [#elementsoptions]

بينشئ نسخة Elements لواجهة دفع مخصّصة. مرّر له الـ `clientSecret` من جلسة دفع.

```ts
const elements = xpay.elements({
  clientSecret: "cs_test_...",
  appearance: { colorMode: "dark", borderStyle: "rounded" },
  locale: "en",
});
```

`ElementsOptions`:

| الحقل          | النوع                       | الوصف                                                                          |
| -------------- | --------------------------- | ------------------------------------------------------------------------------ |
| `clientSecret` | `string \| Promise<string>` | مطلوب. الـ client secret بتاع جلسة الدفع. ممكن يكون Promise.                   |
| `appearance`   | `Appearance`                | اختياري. تجاوزات الواجهة المدموجة مع العلامة التجارية من ناحية السيرفر للجلسة. |
| `locale`       | `"en" \| "ar"`              | اختياري. الافتراضي `"en"`.                                                     |

### `checkout(options)` [#checkoutoptions]

بينشئ نسخة drop-in checkout. شوف [`CheckoutOptions`](#checkoutoptions) تحت.

### `confirmPayment(options)` [#confirmpaymentoptions]

بيقدّم دفعة باستخدام البيانات اللي Elements جمّعها. شوف [`ConfirmPaymentOptions`](#confirmpaymentoptions) تحت.

### `initCheckout(options)` [#initcheckoutoptions]

الـ API العصري باستدعاء واحد: بيرجّع بيانات الجلسة ودوال الإجراءات مع بعض. شوف [`InitCheckoutOptions`](#initcheckoutoptions) تحت.

## `Elements` [#elements]

بيرجعه `xpay.elements()`. بيدير iframe دفع مشترك واحد وبيكشف دوال تعديل الجلسة.

```ts
interface Elements {
  create(type: "payment"): PaymentElement;
  getElement(type: "payment"): PaymentElement | null;
  fetchPaymentMethods(): Promise<PaymentMethodInfo[]>;

  on(event: "ready" | "change" | "loaderror" | "error", handler): void;
  off(event: string, handler): void;

  applyPromotionCode(code: string): Promise<ActionResult>;
  removePromotionCode(): Promise<ActionResult>;
  updateLineItemQuantity(args: { lineItem: string; quantity: number }): Promise<ActionResult>;
  submit(): Promise<{ error?: XPayError; selectedPaymentMethod?: string }>;
  fetchUpdates(): Promise<ActionResult>;
  changeAppearance(appearance: Appearance): void;
  destroy(): void;
}
```

### الأحداث [#الأحداث]

| الحدث         | توقيع الـ handler                        | بيطلق لما                                                                      |
| ------------- | ---------------------------------------- | ------------------------------------------------------------------------------ |
| `"ready"`     | `(data: ElementsReadyEvent) => void`     | الجلسة اتحمّلت والـ elements قابلة للتركيب. بيطلق فورًا لو متحمّلة أصلًا.      |
| `"change"`    | `(session: CheckoutSession) => void`     | بيانات الجلسة بتتغيّر (اختيار وسيلة دفع، وأكواد خصم، وإعادة حساب رسوم).        |
| `"loaderror"` | `(data: ElementsLoadErrorEvent) => void` | الجلسة بتفشل في التحميل (خطأ شبكة، أو client secret غلط، أو خطأ API).          |
| `"error"`     | `(error: XPayError) => void`             | خطأ غير مطلوب مش جاي من إجراء التاجر (مثلًا جلسة انتهت أثناء إعادة حساب رسوم). |

### الدوال [#الدوال]

* `create("payment", options?)`: بيرجّع [`PaymentElement`](#paymentelement) تقدر تركّبه.
* `getElement("payment")`: بيرجّع الـ element الموجود أو `null` لو ما اتعملش واحد.
* `fetchPaymentMethods()`: بيرجّع قائمة الـ `PaymentMethodInfo` اللي الجلسة بتدعمها.
* `applyPromotionCode(code)`: بيطبّق كود خصم، ويرجّع `ActionResult`.
* `removePromotionCode()`: بيشيل الكود المطبَّق، ويرجّع `ActionResult`.
* `updateLineItemQuantity({ lineItem, quantity })`: بيحدّث بند، ويرجّع `ActionResult`.
* `submit()`: بيتحقّق من حقول الـ element. بيرجّع يا إما `error` أو نص نوع الـ `selectedPaymentMethod`.
* `fetchUpdates()`: بيعيد جلب الجلسة من السيرفر.
* `changeAppearance(appearance)`: بيحدّث العلامة التجارية في وقت التشغيل من غير ما يعيد إنشاء الـ elements.
* `destroy()`: بيفكّك النسخة ويحرّر الموارد.

## `PaymentElement` [#paymentelement]

مختار وسيلة الدفع الكامل مع فورم البطاقة، وBNPL، وكشك، ووسائل المحفظة. خُد واحد من `elements.create("payment")`.

```ts
interface PaymentElement {
  mount(container: string | HTMLElement): void;
  unmount(): void;
  destroy(): void;
  focus(): void;
  blur(): void;
  collapse(): void;

  on(event: "ready" | "loaderstart" | "loaderror", handler): void;
  off(event: string, handler): void;
}
```

`PaymentElementChangeEvent` هو الحمولة لحدث `"change"` بتاع الـ `Elements` الأب لما يتطلق من تغيير وسيلة دفع:

| الحقل         | النوع              | الوصف                                           |
| ------------- | ------------------ | ----------------------------------------------- |
| `elementType` | `"payment"`        | دايمًا `"payment"` للـ element ده.              |
| `empty`       | `boolean`          | إذا كانت كل حقول البطاقة فاضية.                 |
| `complete`    | `boolean`          | إذا كان الفورم مكتمل وجاهز للتقديم.             |
| `collapsed`   | `boolean`          | إذا كان مختار الوسيلة مطوي (مفيش وسيلة مختارة). |
| `value`       | `{ type: string }` | نوع وسيلة الدفع المختارة حاليًا.                |
| `session`     | `CheckoutSession`  | آخر لقطة للجلسة.                                |

## `ConfirmPaymentOptions` [#confirmpaymentoptions-1]

الشكل المُمرَّر لـ `xpay.confirmPayment()` و`checkout.confirm()`.

| الحقل               | النوع                                         | الوصف                                                                                                 |
| ------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `elements`          | `Elements`                                    | مطلوب (لـ `xpay.confirmPayment`). نسخة الـ Elements اللي بتدير الفورم. `checkout.confirm` بيحقنها لك. |
| `customerDetails`   | `CustomerDetails`                             | اختياري. حقول العميل اللي فورمك جمّعها.                                                               |
| `customFields`      | `Record<string, string \| number \| boolean>` | اختياري. قيم الحقول المخصّصة للجلسة.                                                                  |
| `deviceFingerprint` | `{ visitorId: string; confidence?: number }`  | اختياري. بصمة الجهاز لكشف الاحتيال.                                                                   |
| `paymentMethod`     | `string`                                      | اختياري. تجاوز نوع وسيلة الدفع المختارة.                                                              |
| `redirect`          | `"if_required" \| "always"`                   | الافتراضي `"if_required"`. بيتحكم في التنقّل بعد الدفع.                                               |

دلالات `redirect`:

* `"if_required"` بيرجّع النتيجة لكودك؛ وبيحوّل بس لما وسيلة الدفع تتطلّب كده (مثلًا 3-D Secure، وBNPL).
* `"always"` بيحوّل دايمًا لـ `afterCompletion.redirect.url` بتاع الجلسة بعد الدفع. الصفحة بتتنقّل بعيد والدالة عمرها ما بترجع عند النجاح.

العنوان هو `afterCompletion.redirect.url` بتاع الجلسة، اللي بيتحدد لما السيرفر بتاعك ينشئ الجلسة. وXPay بتوجّه ليه من غير ما تضيف عليه حاجة.

## `CheckoutOptions` [#checkoutoptions-1]

إعداد الـ drop-in `xpay.checkout()`.

| الحقل          | النوع                                      | الوصف                                                               |
| -------------- | ------------------------------------------ | ------------------------------------------------------------------- |
| `clientSecret` | `string`                                   | مطلوب. الـ client secret بتاع جلسة الدفع.                           |
| `mode`         | `"modal" \| "inline"`                      | `"modal"` (افتراضي) بيعرض تغطية؛ و`"inline"` بيضمّن في `container`. |
| `container`    | `string \| HTMLElement`                    | مطلوب لوضع `inline`. CSS selector أو DOM node علشان يتضمّن فيه.     |
| `appearance`   | `Appearance`                               | تجاوزات الواجهة المدموجة مع العلامة التجارية للجلسة.                |
| `locale`       | `"en" \| "ar"`                             | لغة الواجهة. الافتراضي `"en"`.                                      |
| `onComplete`   | `(result: CheckoutCompleteResult) => void` | بيتنادى لما الدفعة تكتمل بنجاح.                                     |
| `onClose`      | `() => void`                               | بيتنادى لما النافذة المنبثقة تتقفل.                                 |
| `onReady`      | `(session: CheckoutSession) => void`       | بيتنادى لما الجلسة تتحمّل والواجهة تجهز.                            |
| `onConfirmed`  | `() => void`                               | بيتنادى لما العميل يأكّد الدفع، قبل النتيجة النهائية.               |
| `onError`      | `(error: CheckoutError) => void`           | بيتنادى لما يحصل خطأ.                                               |

## `CheckoutInstance` [#checkoutinstance]

بيرجعه `xpay.checkout()`. مقبض أمري.

```ts
interface CheckoutInstance {
  open(): void; // modal mode
  close(): void;
  destroy(): void;
  on(event: "complete" | "close" | "ready" | "confirmed" | "error", handler): void;
  off(event: string, handler): void;
}
```

`CheckoutCompleteResult` (الحمولة لـ `onComplete`):

| الحقل             | النوع         | الوصف                                             |
| ----------------- | ------------- | ------------------------------------------------- |
| `status`          | `"succeeded"` | دايمًا `"succeeded"` للـ callback ده.             |
| `paymentIntentId` | `string`      | معرّف الـ Payment Intent للتحقق من ناحية السيرفر. |
| `chargeId`        | `string`      | اختياري. معرّف الـ Charge، لما يكون متاح.         |
| `redirectUrl`     | `string`      | اختياري. URL التحويل بعد الاكتمال بتاع الجلسة.    |

## `InitCheckoutOptions` [#initcheckoutoptions-1]

الـ API العصري باستدعاء واحد. بيدمج `elements()` مع تحميل الجلسة، وبيكشف بيانات الجلسة زائد دوال الإجراءات على كائن واحد.

```ts
const checkout = await xpay.initCheckout({ clientSecret: "cs_test_..." });
console.log(checkout.amountTotal); // session field
const result = await checkout.confirm({ customerDetails: { email } });
```

| الحقل          | النوع                       | الوصف                                 |
| -------------- | --------------------------- | ------------------------------------- |
| `clientSecret` | `string \| Promise<string>` | مطلوب. الـ client secret بتاع الجلسة. |
| `appearance`   | `Appearance`                | اختياري. تجاوزات الواجهة.             |
| `locale`       | `"en" \| "ar"`              | اختياري. الافتراضي `"en"`.            |

`InitCheckoutResult` هو `CheckoutSession & CheckoutActions`. دوال الإجراءات على `CheckoutActions`:

| الدالة                                           | بتعمل إيه                                                       |
| ------------------------------------------------ | --------------------------------------------------------------- |
| `confirm(options?)`                              | بتأكّد الدفعة. بترجّع `ActionResult`.                           |
| `applyPromotionCode(code)`                       | بتطبّق كود. بترجّع `ActionResult`.                              |
| `removePromotionCode()`                          | بتشيل الكود المطبَّق. بترجّع `ActionResult`.                    |
| `updateLineItemQuantity({ lineItem, quantity })` | بتحدّث كمية بند. بترجّع `ActionResult`.                         |
| `submit()`                                       | بتتحقّق من الحقول. بترجّع `{ error?, selectedPaymentMethod? }`. |
| `fetchUpdates()`                                 | بتعيد جلب الجلسة من السيرفر. بترجّع `ActionResult`.             |
| `changeAppearance(appearance)`                   | بتحدّث العلامة التجارية في وقت التشغيل.                         |
| `on(event, handler)`                             | تستنى `"change"`، أو `"error"`، أو حدث مخصّص.                   |
| `getElements()`                                  | بترجّع الـ `Elements` الأساسي لإنشاء الـ elements.              |

## `CheckoutSession` (نوع بيانات) [#checkoutsession-data-type]

بيانات الجلسة المكشوفة للتاجر. مشتقّة من رد السيرفر، مقصوصة على الحقول الموجّهة للتاجر.

| الحقل            | النوع                  | الوصف                                                           |
| ---------------- | ---------------------- | --------------------------------------------------------------- |
| `id`             | `string`               | معرّف الجلسة `cs_*`.                                            |
| `amountSubtotal` | `number`               | المجموع الفرعي بالوحدات الصغرى (مثلًا `50000` لـ `500.00 EGP`). |
| `amountTotal`    | `number`               | الإجمالي بالوحدات الصغرى بعد الرسوم والضرايب والخصومات.         |
| `currency`       | `string`               | كود العملة ISO (مثلًا `"EGP"`).                                 |
| `merchantName`   | `string`               | الاسم المعروض لنشاطك التجاري.                                   |
| `livemode`       | `boolean`              | `true` للمفاتيح الفعلية؛ و`false` لوضع الاختبار.                |
| `expiresAt`      | `string`               | طابع زمني ISO لوقت انتهاء الجلسة.                               |
| `status`         | `SessionStatus`        | tagged union: `open`، و`expired`، و`complete`.                  |
| `canConfirm`     | `boolean`              | إذا كانت الجلسة ممكن تتأكّد حاليًا.                             |
| `paymentMethods` | `PaymentMethodInfo[]`  | وسائل الدفع المتاحة على الجلسة دي.                              |
| `lineItems`      | `CheckoutLineItem[]`   | البنود.                                                         |
| `totalDetails`   | `CheckoutTotalDetails` | تفصيل المجموع الفرعي، والضريبة، والشحن، والخصم.                 |
| `fees`           | `CheckoutFees`         | تفصيل الرسوم لما يكون `feesPassThrough` مفعّل.                  |
| `discounts`      | `CheckoutDiscount[]`   | أكواد الخصم المطبَّقة.                                          |

`SessionStatus`:

```ts
type SessionStatus =
  | { type: "open" }
  | { type: "expired" }
  | { type: "complete"; paymentStatus: "paid" | "unpaid" | "no_payment_required" };
```

`PaymentMethodInfo`:

| الحقل            | النوع                                     | الوصف                                         |
| ---------------- | ----------------------------------------- | --------------------------------------------- |
| `type`           | `string`                                  | نوع الوسيلة (`"card"`، `"valu"`، `"fawry"`).  |
| `displayName`    | `string`                                  | لافتة مترجمة (`"Card"`، `"ValU"`، `"Fawry"`). |
| `category`       | `"card" \| "bnpl" \| "kiosk" \| "wallet"` | تصنيف لتجميع الواجهة.                         |
| `icon`           | `string`                                  | URL أيقونة اختياري.                           |
| `nextActionText` | `string`                                  | اختياري. وصف الخطوة الجاية اللي بتظهر للعميل. |

## `ActionResult` و`XPayError` [#actionresult-وxpayerror]

كل إجراء بيعدّل الجلسة بيرجّع `ActionResult`. ده tagged union، فضيّق حسب `result.type` قبل ما تقرا الحمولة.

```ts
type ActionResult<E = XPayError> =
  | { type: "success"; session: CheckoutSession }
  | { type: "error"; error: E };
```

`XPayError` هو شكل الخطأ الموحَّد. الحقول الخاصة بالدفع بتبقى `null` للأخطاء اللي مش دفع.

| الحقل               | النوع                             | الوصف                                                                                   |
| ------------------- | --------------------------------- | --------------------------------------------------------------------------------------- |
| `type`              | `string`                          | فئة الخطأ: `"card_error"`، `"invalid_request_error"`، `"api_error"`.                    |
| `code`              | `string \| null`                  | كود قابل للقراءة آليًا (`"card_declined"`، `"promotion_code_not_found"`).               |
| `message`           | `string`                          | رسالة مقروءة للبني آدم.                                                                 |
| `param`             | `string \| null`                  | البارامتر اللي سبّب الخطأ (مثلًا `"promotionCode"`).                                    |
| `docUrl`            | `string \| null`                  | URL التوثيق لكود الخطأ ده.                                                              |
| `declineCode`       | `string \| null`                  | تفصيل الرفض زي `"insufficient_funds"`. Null للأخطاء اللي مش دفع.                        |
| `adviceCode`        | `string \| null`                  | نصيحة إعادة المحاولة: `"try_again_later"`، `"do_not_try_again"`، `"confirm_card_data"`. |
| `chargeId`          | `string \| null`                  | معرّف الـ charge الفاشل.                                                                |
| `paymentMethodId`   | `string \| null`                  | معرّف وسيلة الدفع الفاشلة.                                                              |
| `paymentMethodType` | `string \| null`                  | نوع وسيلة الدفع (`"card"`، `"valu"`).                                                   |
| `paymentMethod`     | `Record<string, unknown> \| null` | لقطة وسيلة الدفع وقت الفشل.                                                             |

لدليل التعامل مع أخطاء الـ API وفضاءات أكواد الخطأ التلاتة، شوف [الأخطاء](/integrate/errors/api-errors)، و[أكواد أخطاء الـ API](/integrate/errors/api-error-codes)، و[أكواد أخطاء الدفع](/integrate/errors/payment-error-codes)، و[أكواد الرفض](/integrate/errors/decline-codes).

## `Appearance` [#appearance]

تجاوزات العلامة التجارية للواجهة المضمّنة. بتعكس مجموعة فرعية من حقول التاجر الافتراضية اللي بتظبطها في [إعدادات العلامة التجارية](/features/checkout-customization/branding).

| الحقل         | القيم                                                                                                                                           |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `colorMode`   | `"system" \| "light" \| "dark"`                                                                                                                 |
| `borderStyle` | `"rounded" \| "sharp" \| "pill"`                                                                                                                |
| `spacing`     | `"condensed" \| "normal" \| "spacious"`                                                                                                         |
| `inputSize`   | `"small" \| "medium" \| "large"`                                                                                                                |
| `inputStyle`  | `"outlined" \| "flat" \| "filled"`                                                                                                              |
| `formLayout`  | `"compact" \| "spacious"`                                                                                                                       |
| `colors`      | كائن بـ اتناشر رمز دلالي (primary، وforeground، وbackground، وmuted، وaccent، وborder، وinput، وring، وdestructive، زائد أزواج الـ foreground). |
| `fontFamily`  | نص CSS لـ font-family.                                                                                                                          |

مرّر `Appearance` لـ `xpay.elements()`، أو `xpay.checkout()`، أو `xpay.initCheckout()`. أو استدعي `elements.changeAppearance()` / `checkout.changeAppearance()` علشان تحدّث في وقت التشغيل.

## `CustomerDetails` و`Address` [#customerdetails-وaddress]

الأشكال لحقول العميل اللي بتجمّعها على فورمك وبتمرّرها وقت التأكيد.

```ts
interface CustomerDetails {
  email?: string;
  name?: string;
  phone?: string;
  billingDetails?: { name?: string; email?: string; phone?: string; address?: Address };
  shipping?: { name?: string; phone?: string; address?: Address };
}

interface Address {
  line1?: string;
  line2?: string;
  city?: string;
  state?: string;
  postalCode?: string;
  country?: string;
}
```

للمرجع المتبادل من ناحية المطوّر عن كل حقل في جلسة الدفع بيتحكم في إيه (مفاتيح التحصيل، والحقول المخصّصة، وأولوية الملء المسبق)، شوف [دورة حياة العميل](/integrate/checkout-session/customer-lifecycle).

## رايح فين بعد كده [#رايح-فين-بعد-كده]

<Cards>
  <Card icon="<FileCode />" title="@xpayeg/react" href="/sdk/sdk-react">
    غلاف React. `XPayProvider`، والـ hooks، والمكوّنات المبنية فوق الـ package ده.
  </Card>

  <Card icon="<Sparkles />" title="نمط Drop-in" href="/integrate/integration-patterns/drop-in">
    شرح الدمج لـ `xpay.checkout()`.
  </Card>

  <Card icon="<Sparkles />" title="نمط Elements" href="/integrate/integration-patterns/elements">
    شرح الدمج لـ `xpay.elements()` ومكوّن `PaymentElement`.
  </Card>
</Cards>