> ## 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.

# iOS

> افتح صفحة الدفع المستضافة من Dodo Payments من تطبيق iOS داخل SFSafariViewController واحصل على نتيجة typed من خلال استدعاء واحد.

<Info>
  هذا هو iOS checkout SDK الرسمي من Dodo Payments والمخصص لـ Swift. يفتح صفحة الدفع المستضافة من Dodo داخل متصفح أصلي ويعيد نتيجة typed.
</Info>

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

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

يفتح iOS SDK صفحة الدفع المستضافة من Dodo داخل `SFSafariViewController`، ولا يحتفظ بأي API key، ولا يستدعي Dodo API مباشرةً. تعمل جميع منطق الدفع في المتصفح؛ بينما يدير SDK ببساطة دورة حياة العرض ويلتقط return URL.

يتطلب iOS 16+ وSwift 6.

## التثبيت

<Steps>
  <Step title="Add the Package">
    في Xcode، انتقل إلى **File → Add Package Dependencies** وأدخل:

    ```
    https://github.com/dodopayments/dodopayments-mobile-sdk-ios
    ```

    حدد الإصدار 1.0.0 أو إصدارًا أحدث.

    بدلًا من ذلك، أضفه إلى `Package.swift`:

    ```swift Package.swift theme={null}
    .package(url: "https://github.com/dodopayments/dodopayments-mobile-sdk-ios", from: "1.0.0")
    ```
  </Step>

  <Step title="Register a Callback URL Scheme">
    يجب أن يسجل تطبيقك URL scheme لاستقبال return URL من صفحة الدفع. أضف ما يلي إلى `Info.plist`:

    ```xml 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>
    ```

    يمكنك أيضًا إضافة ذلك عبر واجهة **Info → URL Types** في Xcode.
  </Step>
</Steps>

## الاستخدام

```swift theme={null}
import DodoCheckout

let result = try await DodoCheckout.start(
    checkoutUrl: checkoutUrl,   // from your backend's checkout session
    returnUrl: URL(string: "myapp://checkout/return")!,
    onEvent: { event in print(event.name) }  // logging only
)

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

## إعادة توجيه Return URL

لا يملك `SFSafariViewController` طريقة داخل العملية لالتقاط return URL الخاص به. يجب أن يعيد تطبيقك توجيه عناوين URL الواردة إلى SDK.

<Tabs>
  <Tab title="SwiftUI">
    ```swift theme={null}
    .onOpenURL { url in
        DodoCheckout.handleOpenURL(url)
    }
    ```
  </Tab>

  <Tab title="SceneDelegate">
    ```swift SceneDelegate.swift theme={null}
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let url = URLContexts.first?.url else { return }
        DodoCheckout.handleOpenURL(url)
    }
    ```
  </Tab>
</Tabs>

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

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

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

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

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

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

<ParamField body="licenseKeys" type="[String]?">
  يُعيَّن عند احتواء عملية الدفع على منتجات تتضمن license key.
</ParamField>

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

<ParamField body="raw" type="[String: String]">
  كل query parameter من return URL، حرفيًا.
</ParamField>

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

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

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

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

## الأخطاء

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

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

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

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

```swift theme={null}
import DodoCheckout

if let abandoned = DodoCheckout.getAbandonedSession() {
    // reconcile abandoned.sessionId with your backend, then:
    DodoCheckout.clearAbandonedSession()
}
```

## ذات صلة

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

  <Card title="React Native SDK" icon="react" href="/developer-resources/sdks/react-native">
    يغلّف نواة Swift نفسها على iOS.
  </Card>
</CardGroup>
