> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Flutter

> افتح صفحة الدفع المستضافة من Dodo Payments من Flutter في علامة تبويب متصفح النظام، واحصل على نتيجة مكتوبة النوع في استدعاء واحد.

<Info>
  هذه هي حزمة Flutter الرسمية من Dodo Payments (`dodopayments_checkout`
  على pub.dev). توجد أيضًا حزمة منفصلة طوّرها المجتمع، راجع
  [مشاريع المجتمع](/community/projects).
</Info>

<CardGroup cols={2}>
  <Card title="Checkout Sessions API" icon="cart-shopping" href="/developer-resources/checkout-session">
    أنشئ checkout\_url الذي تفتحه هذه الحزمة، من الخادم الخلفي لديك.
  </Card>

  <Card title="Mobile Integration Guide" icon="mobile" href="/developer-resources/mobile-integration">
    تعرّف على كيفية اندماج ذلك في تدفق الدفع الكامل على الأجهزة المحمولة.
  </Card>
</CardGroup>

تفتح `dodopayments_checkout` صفحة الدفع المستضافة من Dodo في
`SFSafariViewController` على iOS وعلامة تبويب Chrome مخصصة على Android — وهي نفس
النوى الأصلية المستخدمة في حزم [iOS](/developer-resources/sdks/ios) و
[Android](/developer-resources/sdks/android) المستقلة. توجد كل منطق الدفع في
تلك النوى الأصلية؛ وتمرر طبقة Dart الاستدعاء عبر قناة مكتوبة النوع هي
[Pigeon](https://pub.dev/packages/pigeon). ولا تحتوي على مفتاح API، كما أنها
لا تستدعي API الخاص بـ Dodo Payments مطلقًا.

يتطلب Flutter 3.44+ / Dart 3.12+، وiOS 16+، وAndroid `minSdk` 23.

## التثبيت

<Steps>
  <Step title="Add the Dependency">
    ```yaml pubspec.yaml theme={null}
    dependencies:
      dodopayments_checkout: ^1.0.0
    ```
  </Step>

  <Step title="Register a Callback URL Scheme">
    <Tabs>
      <Tab title="iOS">
        أضف نوع URL لمخططك في `ios/Runner/Info.plist`:

        ```xml ios/Runner/Info.plist theme={null}
        <key>CFBundleURLTypes</key>
        <array>
          <dict>
            <key>CFBundleURLName</key>
            <string>myapp</string>
            <key>CFBundleURLSchemes</key>
            <array>
              <string>myapp</string>
            </array>
          </dict>
        </array>
        ```

        بعد ذلك مرّر عناوين URL الواردة (مثلًا عبر
        [`app_links`](https://pub.dev/packages/app_links)) إلى الحزمة، لأن
        `SFSafariViewController` لا يمكنه التقاط عنوان URL الخاص بالعودة:

        ```dart theme={null}
        import 'package:dodopayments_checkout/dodopayments_checkout.dart';

        DodoCheckout.instance.handleOpenURL(url);
        ```

        <Note>
          من الآمن تمرير كل عنوان URL هنا. لا يتصرف `handleOpenURL` إلا مع عناوين URL
          التي تطابق `returnUrl` المسجّل لديك، ويحلّ `false` لأي شيء
          آخر.
        </Note>
      </Tab>

      <Tab title="Android">
        عيّن مخطط استدعاءك كعنصر نائب في بيان Gradle:

        ```kotlin android/app/build.gradle theme={null}
        android {
            defaultConfig {
                manifestPlaceholders["dodoCallbackScheme"] = "myapp"
            }
        }
        ```

        <Warning>
          إذا كان `MainActivity` يعيّن `android:taskAffinity=""` (الإعداد الافتراضي في `flutter
                    create`)، فأزله أو امنح أنشطة الحزمة نفس
          الانتماء. وإلا فقد تفقد بعض إصدارات Android من الشركات المصنّعة
          مسار الدفع الجاري وتعيد `PLATFORM_ERROR`.
        </Warning>
      </Tab>
    </Tabs>
  </Step>
</Steps>

## الاستخدام

```dart theme={null}
import 'package:dodopayments_checkout/dodopayments_checkout.dart';

final result = await DodoCheckout.instance.start(
  CheckoutParams(
    checkoutUrl: Uri.parse(checkoutUrl), // from your backend's checkout session
    returnUrl: Uri.parse('myapp://checkout/return'), // scheme must be registered (see Setup)
    onEvent: (event) => print(event.type), // logging only
  ),
);

switch (result.status) {
  case CheckoutStatus.succeeded: showSuccess(result.paymentId);
  case CheckoutStatus.failed:    showFailure();
  case CheckoutStatus.cancelled: dismiss();
  case CheckoutStatus.pending:   showPending();
  case CheckoutStatus.expired:   showExpired();
}
```

## معنى النتيجة

<Warning>
  `result.status` هو تلميح لواجهة المستخدم، وليس دليلًا على الدفع. أكّد كل عملية دفع
  من الخادم الخلفي لديك، عبر `payment.succeeded` / `subscription.active`
  webhook.
</Warning>

<ParamField body="status" type="CheckoutStatus" required>
  واحد من `succeeded`، `failed`، `cancelled`، `pending`، `expired`.
</ParamField>

<ParamField body="paymentId" type="String?">
  يُعيَّن عند تضمين أحدها في عنوان URL للعودة. اعرضه في واجهة المستخدم، ولا تستخدمه لمنح صلاحية الوصول. راجع قسم التحقق من الدفع أدناه.
</ParamField>

<ParamField body="subscriptionId" type="String?">
  يُعيَّن لعمليات دفع الاشتراكات.
</ParamField>

<ParamField body="licenseKeys" type="List<String>?">
  يُعيَّن عند تضمين منتجات مفاتيح الترخيص في عملية الدفع.
</ParamField>

<ParamField body="customerEmail" type="String?">
  يُعيَّن عند جمع عنوان بريد إلكتروني في عملية الدفع.
</ParamField>

<ParamField body="raw" type="Map<String, String>">
  كل مَعلمات الاستعلام الواردة من عنوان URL للعودة، حرفيًا.
</ParamField>

## التحقق من الدفع

<CardGroup cols={2}>
  <Card title="Webhooks" icon="webhook" href="/developer-resources/webhooks">
    يستدعي Dodo Payments خادمك الخلفي عند نجاح عملية دفع أو تفعيل اشتراك.
  </Card>

  <Card title="Get Payment Detail" icon="magnifying-glass" href="/api-reference/payments/get-payments-1">
    ابحث عن `paymentId` باستخدام مفتاحك السري للتحقق من حالته مباشرة.
  </Card>
</CardGroup>

امنح صلاحية الوصول بعد أن يؤكد أحد هذه العناصر الدفع، ولا تمنحها مطلقًا استنادًا إلى
`result.status` وحده.

## الأخطاء

يُطلق `start` الاستثناء `CheckoutException` فقط عند إساءة الاستخدام أو حدوث عطل في المنصة.
أما عملية الدفع الملغاة أو المرفوضة فهي دائمًا نتيجة وليست استثناءً.

* `invalidCheckoutUrl` (`INVALID_CHECKOUT_URL`): ليس عنوان URL لجلسة `checkout.dodopayments.com`.
* `invalidReturnUrl` (`INVALID_RETURN_URL`): ليس عنوان URL مطلقًا صالحًا.
* `alreadyInProgress` (`ALREADY_IN_PROGRESS`): توجد عملية دفع قيد التشغيل بالفعل.
* `platformError` (`PLATFORM_ERROR`): عطل غير متوقع في المنصة.

## الجلسات المتروكة

<Info>
  إذا أُغلِق التطبيق أثناء عملية الدفع، فاستعد الجلسة عند التشغيل التالي
  وطابِقها مع خادمك الخلفي.
</Info>

```dart theme={null}
import 'package:dodopayments_checkout/dodopayments_checkout.dart';

final abandoned = await DodoCheckout.instance.getAbandonedSession();
if (abandoned != null) {
  // reconcile abandoned.sessionId with your backend, then:
  await DodoCheckout.instance.clearAbandonedSession();
}
```

## ذات صلة

<CardGroup cols={2}>
  <Card title="Mobile Integration Guide" icon="mobile" href="/developer-resources/mobile-integration">
    نفس العقد الخاص بـ Android وiOS وReact Native.
  </Card>

  <Card title="Community Projects" icon="users" href="/community/projects">
    توجد أيضًا حزمة Flutter منفصلة طوّرها المجتمع.
  </Card>
</CardGroup>
