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

# Checkout Sessions

> Create secure, hosted checkout experiences that handle the complete payment flow for both one-time purchases and subscriptions with full customization control.

<CardGroup cols={2}>
  <Card title="Quick Start Guide" icon="rocket" href="#creating-your-first-checkout-session">
    Get your first checkout session running in under 5 minutes
  </Card>

  <Card title="API Reference & Live Testing" icon="code" href="/api-reference/checkout-sessions/create">
    Explore the full API documentation and interactively test Checkout Session requests and responses.
  </Card>

  <Card title="Preview Checkout" icon="eye" href="/api-reference/checkout-sessions/preview">
    Calculate pricing, taxes, and totals before creating a session.
  </Card>
</CardGroup>

<Info>
  **Session Validity**: Checkout sessions are valid for 24 hours by default. If you pass `confirm=true` in your request, the session will only be valid for 15 minutes.
</Info>

## Prerequisites

<Steps>
  <Step title="Dodo Payments Account">
    You'll need an active Dodo Payments merchant account with API access.
  </Step>

  <Step title="API Credentials">
    Generate your API credentials from the Dodo Payments dashboard:
  </Step>

  <Step title="Products Setup">
    Create your products in the Dodo Payments dashboard before implementing checkout sessions.
  </Step>
</Steps>

## Creating Your First Checkout Session

<Tabs>
  <Tab title="Node.js SDK">
    ```javascript expandable theme={null}
    import DodoPayments from 'dodopayments';

    // Initialize the Dodo Payments client
    const client = new DodoPayments({
      bearerToken: process.env.DODO_PAYMENTS_API_KEY,
      environment: 'test_mode', // defaults to 'live_mode'
    });

    async function createCheckoutSession() {
      try {
        const session = await client.checkoutSessions.create({
          // Products to sell - use IDs from your Dodo Payments dashboard
          product_cart: [
            {
              product_id: 'prod_123', // Replace with your actual product ID
              quantity: 1
            }
          ],
          
          // Pre-fill customer information to reduce friction
          customer: {
            email: 'customer@example.com',
            name: 'John Doe',
            phone_number: '+1234567890'
          },
          
          // Billing address for tax calculation and compliance
          billing_address: {
            street: '123 Main St',
            city: 'San Francisco',
            state: 'CA',
            country: 'US', // Required: ISO 3166-1 alpha-2 country code
            zipcode: '94102'
          },
          
          // Where to redirect after successful payment
          return_url: 'https://yoursite.com/checkout/success',
          
          // Custom data for your internal tracking
          metadata: {
            order_id: 'order_123',
            source: 'web_app'
          }
        });

        // Redirect your customer to this URL to complete payment
        console.log('Checkout URL:', session.checkout_url);
        console.log('Session ID:', session.session_id);
        
        return session;
        
      } catch (error) {
        console.error('Failed to create checkout session:', error);
        throw error;
      }
    }

    // Example usage in an Express.js route
    app.post('/create-checkout', async (req, res) => {
      try {
        const session = await createCheckoutSession();
        res.json({ checkout_url: session.checkout_url });
      } catch (error) {
        res.status(500).json({ error: 'Failed to create checkout session' });
      }
    });
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python expandable theme={null}
    import os
    from dodopayments import DodoPayments

    # Initialize the Dodo Payments client
    client = DodoPayments(
        bearer_token=os.environ.get("DODO_PAYMENTS_API_KEY"),  # This is the default and can be omitted
        environment="test_mode",  # defaults to "live_mode"
    )

    def create_checkout_session():
        """
        Create a checkout session for a single product with customer data pre-filled.
        Returns the session object containing checkout_url for customer redirection.
        """
        try:
            session = client.checkout_sessions.create(
                # Products to sell - use IDs from your Dodo Payments dashboard
                product_cart=[
                    {
                        "product_id": "prod_123",  # Replace with your actual product ID
                        "quantity": 1
                    }
                ],
                
                # Pre-fill customer information to reduce checkout friction
                customer={
                    "email": "customer@example.com",
                    "name": "John Doe",
                    "phone_number": "+1234567890"
                },
                
                # Billing address for tax calculation and compliance
                billing_address={
                    "street": "123 Main St",
                    "city": "San Francisco", 
                    "state": "CA",
                    "country": "US",  # Required: ISO 3166-1 alpha-2 country code
                    "zipcode": "94102"
                },
                
                # Where to redirect after successful payment
                return_url="https://yoursite.com/checkout/success",
                
                # Custom data for your internal tracking
                metadata={
                    "order_id": "order_123",
                    "source": "web_app"
                }
            )
            
            # Redirect your customer to this URL to complete payment
            print(f"Checkout URL: {session.checkout_url}")
            print(f"Session ID: {session.session_id}")
            
            return session
            
        except Exception as error:
            print(f"Failed to create checkout session: {error}")
            raise error

    # Example usage in a Flask route
    from flask import Flask, jsonify, request

    app = Flask(__name__)

    @app.route('/create-checkout', methods=['POST'])
    def create_checkout():
        try:
            session = create_checkout_session()
            return jsonify({"checkout_url": session.checkout_url})
        except Exception as error:
            return jsonify({"error": "Failed to create checkout session"}), 500
    ```
  </Tab>

  <Tab title="REST API">
    ```javascript expandable theme={null}
    // Direct API call using fetch - useful for any JavaScript environment
    async function createCheckoutSession() {
      try {
        const response = await fetch('https://test.dodopayments.com/checkouts', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${process.env.DODO_PAYMENTS_API_KEY}`
          },
          body: JSON.stringify({
            // Products to sell - use IDs from your Dodo Payments dashboard
            product_cart: [
              {
                product_id: 'prod_123', // Replace with your actual product ID
                quantity: 1
              }
            ],
            
            // Pre-fill customer information to reduce checkout friction
            customer: {
              email: 'customer@example.com',
              name: 'John Doe',
              phone_number: '+1234567890'
            },
            
            // Billing address for tax calculation and compliance
            billing_address: {
              street: '123 Main St',
              city: 'San Francisco',
              state: 'CA', 
              country: 'US', // Required: ISO 3166-1 alpha-2 country code
              zipcode: '94102'
            },
            
            // Where to redirect after successful payment
            return_url: 'https://yoursite.com/checkout/success',
            
            // Custom data for your internal tracking
            metadata: {
              order_id: 'order_123',
              source: 'web_app'
            }
          })
        });

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }

        const session = await response.json();
        
        // Redirect your customer to this URL to complete payment
        console.log('Checkout URL:', session.checkout_url);
        console.log('Session ID:', session.session_id);
        
        return session;
        
      } catch (error) {
        console.error('Failed to create checkout session:', error);
        throw error;
      }
    }

    // Example: Redirect user to checkout
    createCheckoutSession().then(session => {
      window.location.href = session.checkout_url;
    });
    ```
  </Tab>
</Tabs>

### API Response

All methods above return the same response structure:

```json theme={null}
{
  "session_id": "cks_Gi6KGJ2zFJo9rq9Ukifwa",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks_Gi6KGJ2zFJo9rq9Ukifwa"
}
```

<Steps>
  <Step title="Get the checkout URL">
    Extract the `checkout_url` from the API response.
  </Step>

  <Step title="Redirect your customer">
    Direct your customer to the checkout URL to complete their purchase.

    ```javascript theme={null}
    // Redirect immediately
    window.location.href = session.checkout_url;

    // Or open in new window
    window.open(session.checkout_url, '_blank');
    ```

    <Tip>
      **Alternative Integration Options**: Instead of redirecting, you can embed the checkout directly in your page using [Overlay Checkout](/developer-resources/overlay-checkout) (modal overlay) or [Inline Checkout](/developer-resources/inline-checkout) (fully embedded). Both options use the same checkout session URL.
    </Tip>
  </Step>

  <Step title="Handle the return">
    After payment, customers are redirected to your `return_url` with query parameters including payment/subscription ID, status, customer email, and any license keys. See the [`return_url` parameter docs](#request-body) for the full list.
  </Step>
</Steps>

## Request Body

<CardGroup cols={2}>
  <Card title="Required Fields" icon="asterisk">
    Essential fields needed for every checkout session
  </Card>

  <Card title="Optional Fields" icon="gear">
    Additional configuration to customize your checkout experience
  </Card>
</CardGroup>

### Required Fields

<ParamField body="product_cart" type="array" required>
  Array of products to include in the checkout session. Each product must have a valid `product_id` from your Dodo Payments dashboard.

  <Tip>
    **Mixed Checkout**: You can combine one-time payment products and subscription products in the same checkout session. This enables powerful use cases like setup fees with subscriptions, hardware bundles with SaaS, and more.
  </Tip>

  <Expandable title="Product Cart Item Properties">
    <ParamField body="product_id" type="string" required>
      The unique identifier of the product from your Dodo Payments dashboard.

      **Example:** `"prod_123abc456def"`
    </ParamField>

    <ParamField body="quantity" type="integer" required>
      Quantity of the product.

      **Example:** `1` for single item, `3` for multiple quantities
    </ParamField>

    <ParamField body="addons" type="array">
      Array of addons to attach to the product. Only valid if the product is a subscription.

      <Expandable title="Addon item properties">
        <ParamField body="addon_id" type="string" required />

        <ParamField body="quantity" type="integer" required />
      </Expandable>
    </ParamField>

    <ParamField body="amount" type="integer">
      Amount the customer pays if pay\_what\_you\_want is enabled. If disabled, this field will be ignored.

      **Format**: Represented in the lowest denomination of the currency (e.g., cents for USD). For example, to charge \$1.00, pass `100`.
    </ParamField>

    <ParamField body="credit_entitlements" type="array">
      Per-checkout-session overrides for credit entitlements already attached to this product. Use this to grant a different number of credits for this single session — e.g., a promotional bundle that grants 1,000 API credits instead of the product-default 500 — without creating a separate product.

      <Info>
        Each `credit_entitlement_id` must already be attached to the product. This field overrides only the `credits_amount` granted when this session is fulfilled; product-level credit entitlement settings (expiration, rollover, etc.) still apply.
      </Info>

      <Expandable title="Credit entitlement override properties">
        <ParamField body="credit_entitlement_id" type="string" required>
          ID of the credit entitlement to override. Must already be attached to the product.
        </ParamField>

        <ParamField body="credits_amount" type="string" required>
          Number of credits to grant for this checkout session, overriding the product-level `credits_amount`. Must be greater than zero.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<Tip>
  **Find Your Product IDs**: You can find product IDs in your Dodo Payments dashboard under Products → View Details, or by using the [List Products API](/api-reference/products/get-products).
</Tip>

### Optional Fields

Configure these fields to customize the checkout experience and add business logic to your payment flow.

<AccordionGroup>
  <Accordion title="Customer Information">
    <ParamField body="customer" type="object">
      Customer information. You can either attach an existing customer using their ID or create a new customer record during checkout.

      <Tabs>
        <Tab title="Attach Existing Customer">
          Attach an existing customer to the checkout session using their ID.

          <Expandable title="Existing Customer Properties">
            <ParamField body="customer_id" type="string" required>
              The unique identifier of an existing customer. Use this to attach the checkout session to an existing customer instead of creating a new one.
            </ParamField>
          </Expandable>
        </Tab>

        <Tab title="New Customer">
          Create a new customer record during checkout.

          <Expandable title="New Customer Properties">
            <ParamField body="email" type="string" required>
              Customer's email address. Required when creating a new customer.
            </ParamField>

            <ParamField body="name" type="string">
              Customer's full name as it should appear on receipts and invoices.

              **Example**: `"John Doe"` or `"Jane Smith"`
            </ParamField>

            <ParamField body="phone_number" type="string">
              Customer's phone number in international format. Required for some payment methods and fraud prevention.

              **Format**: Include country code, e.g., `"+1234567890"` for US numbers
            </ParamField>
          </Expandable>
        </Tab>
      </Tabs>
    </ParamField>

    <ParamField body="billing_address" type="object">
      Billing address information for accurate tax calculation, fraud prevention, and regulatory compliance.

      <Info>
        When `confirm` is set to `true`, all billing address fields become required for successful session creation.
      </Info>

      <Expandable title="Billing address object properties">
        <ParamField body="street" type="string">
          Complete street address including house number, street name, and apartment/unit number if applicable.

          **Example**: `"123 Main St, Apt 4B"` or `"456 Oak Avenue"`
        </ParamField>

        <ParamField body="city" type="string">
          City or municipality name.

          **Example**: `"San Francisco"`, `"New York"`, `"London"`
        </ParamField>

        <ParamField body="state" type="string">
          State, province, or region name. Use full names or standard abbreviations.

          **Example**: `"California"` or `"CA"`, `"Ontario"` or `"ON"`
        </ParamField>

        <ParamField body="country" type="string" required>
          Two-letter ISO country code (ISO 3166-1 alpha-2). This field is always required when billing\_address is provided.

          **Examples**: `"US"` (United States), `"CA"` (Canada), `"GB"` (United Kingdom), `"DE"` (Germany)

          <Card title="Country Code Reference" icon="globe" href="/api-reference/misc/supported-countries">
            View complete list of supported countries and their ISO codes
          </Card>
        </ParamField>

        <ParamField body="zipcode" type="string">
          Postal code, ZIP code, or equivalent based on country requirements.

          **Examples**: `"94102"` (US), `"M5V 3A8"` (Canada), `"SW1A 1AA"` (UK)
        </ParamField>
      </Expandable>
    </ParamField>
  </Accordion>

  <Accordion title="Payment Configuration">
    <ParamField body="allowed_payment_method_types" type="array">
      Control which payment methods are available to customers during checkout. This helps optimize for specific markets or business requirements.

      **الخيارات المتاحة**: `credit`, `debit`, `upi_collect`, `apple_pay`, `google_pay`, `amazon_pay`, `klarna`, `affirm`, `afterpay_clearpay`, `cashapp`, `multibanco`, `bancontact_card`, `eps`, `ideal`, `przelewy24`, `paypal`, `sunbit`

      <Warning>
        **Critical**: Always include `credit` and `debit` as fallback options to prevent checkout failures when preferred payment methods are unavailable.
      </Warning>

      **Example**:

      ```json expandable theme={null}
      ["apple_pay", "google_pay", "credit", "debit"]
      ```
    </ParamField>

    <ParamField body="billing_currency" type="string">
      Override the default currency selection with a fixed billing currency. Uses ISO 4217 currency codes.

      **Supported Currencies**: `USD`, `EUR`, `GBP`, `CAD`, `AUD`, `INR`, and more

      **Example**: `"USD"` for US Dollars, `"EUR"` for Euros

      <Note>
        This field is only effective when adaptive pricing is enabled. If adaptive pricing is disabled, the product's default currency will be used.
      </Note>
    </ParamField>

    <ParamField body="show_saved_payment_methods" type="boolean" default="false">
      Display previously saved payment methods for returning customers, improving checkout speed and user experience.
    </ParamField>
  </Accordion>

  <Accordion title="Session Management">
    <ParamField body="return_url" type="string">
      URL to redirect customers after payment completion. Dodo Payments appends the following query parameters to your URL on redirect:

      | Parameter         | Type     | Condition                                                                         |
      | ----------------- | -------- | --------------------------------------------------------------------------------- |
      | `payment_id`      | `string` | Always present for one-time payments                                              |
      | `subscription_id` | `string` | Always present for subscription payments                                          |
      | `status`          | `string` | Always present                                                                    |
      | `license_key`     | `string` | Present if the product has license keys enabled. Comma-separated if multiple keys |
      | `email`           | `string` | Present if the customer has an email on record                                    |

      **Example redirect URLs:**

      ```text theme={null}
      # One-time payment with license key
      https://yoursite.com/return?payment_id=pay_xxx&status=succeeded&license_key=LK-001&email=customer%40example.com

      # Subscription payment with multiple license keys
      https://yoursite.com/return?subscription_id=sub_xxx&status=active&license_key=LK-001,LK-002&email=customer%40example.com

      # Payment without license keys
      https://yoursite.com/return?payment_id=pay_xxx&status=succeeded&email=customer%40example.com
      ```

      <Tip>
        Use the `license_key` and `email` query parameters to display license keys or send a confirmation immediately on your return page, without needing an extra API call.
      </Tip>
    </ParamField>

    <ParamField body="cancel_url" type="string">
      URL to redirect customers when they click the back button or cancel the checkout session. If not provided, the back button will not be displayed.

      <Tip>
        Set a `cancel_url` to give customers a clear way to return to your site without completing the purchase. This improves the checkout experience and reduces friction.
      </Tip>
    </ParamField>

    <ParamField body="confirm" type="boolean" default="false">
      If true, finalizes all session details immediately. API will throw an error if required data is missing.
    </ParamField>

    <ParamField body="discount_codes" type="array">
      Apply one or more stacked discount codes to the checkout session. Codes are applied **in array order** (the first code reduces the base price, the second reduces the already-discounted price, and so on), up to a maximum of **20** codes per session.

      ```typescript theme={null}
      discount_codes: ['WELCOME10', 'BLACKFRIDAY20']
      ```

      <Info>
        The singular `discount_code` field below is **deprecated** but still fully supported — existing integrations continue to work without changes. It cannot be combined with `discount_codes` in the same request. Migrate to `discount_codes` when convenient to take advantage of stacking.
      </Info>
    </ParamField>

    <ParamField body="discount_code" type="string" deprecated>
      **Deprecated** — prefer `discount_codes` for new integrations. This field still works for backward compatibility, but cannot be combined with `discount_codes` in the same request.
    </ParamField>

    <ParamField body="metadata" type="object">
      Custom key-value pairs to store additional information about the session.
    </ParamField>

    <ParamField body="force_3ds" type="boolean">
      Override merchant default 3DS behaviour for this session.
    </ParamField>

    <ParamField body="minimal_address" type="boolean" default="false">
      Enable minimal address collection mode. When enabled, the checkout only collects:

      * **Country**: Always required for tax determination
      * **ZIP/Postal code**: Only in regions where it's necessary for sales tax, VAT, or GST calculation

      This significantly reduces checkout friction by eliminating unnecessary form fields.

      <Tip>
        Enable minimal address for faster checkout completion. Full address collection remains available for businesses that require complete billing details.
      </Tip>
    </ParamField>
  </Accordion>

  <Accordion title="UI Customization & Features">
    <ParamField body="customization" type="object">
      Customize the appearance and behavior of the checkout interface.

      <Expandable title="Customization object properties">
        <ParamField body="theme" type="string" default="system">
          Theme for the checkout interface. Options: `light`, `dark`, or `system`.
        </ParamField>

        <ParamField body="show_order_details" type="boolean" default="true">
          Display order details section in the checkout interface.
        </ParamField>

        <ParamField body="show_on_demand_tag" type="boolean" default="true">
          Show the "on-demand" tag for applicable products.
        </ParamField>

        <ParamField body="force_language" type="string">
          Force the checkout interface to render in a specific language. By default, the checkout auto-detects the customer's browser language.

          **Supported language codes:**
          `ar` (Arabic), `ca` (Catalan), `de` (German), `en` (English), `es` (Spanish), `fr` (French), `he` (Hebrew), `id` (Indonesian), `it` (Italian), `ja` (Japanese), `ko` (Korean), `ms` (Malay), `nl` (Dutch), `pl` (Polish), `pt` (Portuguese), `ro` (Romanian), `ru` (Russian), `sv` (Swedish), `th` (Thai), `tr` (Turkish), `zh` (Chinese)

          **Example**: `"es"` for Spanish, `"ja"` for Japanese
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="feature_flags" type="object">
      Configure specific features and behaviors for the checkout session.

      <Expandable title="Feature flags object properties">
        <ParamField body="allow_currency_selection" type="boolean" default="true">
          Allow customers to select their preferred currency during checkout.
        </ParamField>

        <ParamField body="allow_discount_code" type="boolean" default="true">
          Show discount code input field in the checkout interface.
        </ParamField>

        <ParamField body="allow_editing_addons" type="boolean" default="false">
          السماح للعملاء بإضافة أو إزالة الإضافات على منتج الاشتراك أثناء عملية الدفع. ينطبق فقط على منتجات الاشتراك.
        </ParamField>

        <ParamField body="allow_phone_number_collection" type="boolean" default="true">
          جمع أرقام هواتف العملاء أثناء عملية الدفع.
        </ParamField>

        <ParamField body="allow_tax_id" type="boolean" default="true">
          السماح للعملاء بإدخال أرقام التعريف الضريبي.
        </ParamField>

        <ParamField body="always_create_new_customer" type="boolean" default="false">
          إجبار إنشاء سجل عميل جديد بدلاً من تحديث السجلات الحالية.
        </ParamField>

        <ParamField body="allow_customer_editing_email" type="boolean">
          السماح للعملاء بتعديل عنوان البريد الإلكتروني أثناء عملية الدفع.
        </ParamField>

        <ParamField body="allow_customer_editing_name" type="boolean">
          السماح للعملاء بتعديل الاسم أثناء عملية الدفع.
        </ParamField>

        <ParamField body="allow_customer_editing_street" type="boolean">
          السماح للعملاء بتعديل عنوان الشارع أثناء عملية الدفع.
        </ParamField>

        <ParamField body="allow_customer_editing_city" type="boolean">
          السماح للعملاء بتعديل المدينة أثناء عملية الدفع.
        </ParamField>

        <ParamField body="allow_customer_editing_state" type="boolean">
          السماح للعملاء بتعديل الولاية أثناء عملية الدفع.
        </ParamField>

        <ParamField body="allow_customer_editing_country" type="boolean">
          السماح للعملاء بتعديل الدولة أثناء عملية الدفع.
        </ParamField>

        <ParamField body="allow_customer_editing_zipcode" type="boolean">
          السماح للعملاء بتعديل الرمز البريدي أثناء عملية الدفع.
        </ParamField>

        <ParamField body="redirect_immediately" type="boolean" default="false">
          تخطي صفحة نجاح الدفع الافتراضية وإعادة توجيه العملاء مباشرة إلى `return_url` بعد إكمال الدفع.

          <Tip>
            استخدم هذا عندما يكون لديك صفحة نجاح مخصصة توفر تجربة مستخدم أفضل، أو لتطبيقات الجوال وتدفقات الدفع المضمنة.
          </Tip>
        </ParamField>
      </Expandable>
    </ParamField>
  </Accordion>

  <Accordion title="Custom Fields">
    <ParamField body="custom_fields" type="array">
      جمع معلومات إضافية من العملاء أثناء الدفع باستخدام حقول النموذج المخصصة. يمكنك تعريف ما يصل إلى 5 حقول مخصصة لكل جلسة دفع. يتم تضمين ردود العملاء في تحميلات webhook ومتاحة عبر API.

      <Expandable title="Custom field object properties">
        <ParamField body="key" type="string" required>
          معرف فريد لهذا الحقل. يتم استخدامه كمفتاح في تحميلات webhook واستجابات API.

          **مثال**: `"company_name"`, `"referral_source"`, `"team_size"`
        </ParamField>

        <ParamField body="label" type="string" required>
          تسمية العرض التي تظهر للعميل على نموذج الدفع.

          **مثال**: `"Company Name"`, `"How did you hear about us?"`, `"Team Size"`
        </ParamField>

        <ParamField body="field_type" type="string" required>
          نوع الحقل الذي يحدد قواعد التحقق من الإدخال.

          **الأنواع المتاحة**:

          * `text` - إدخال نص بخط واحد
          * `number` - إدخال رقمي
          * `email` - عنوان بريد إلكتروني مع تحقق
          * `url` - عنوان URL مع تحقق
          * `date` - منتقي التاريخ
          * `dropdown` - اختر من الخيارات المحددة مسبقاً
          * `boolean` - تبديل نعم/لا
        </ParamField>

        <ParamField body="required" type="boolean" default="false">
          ما إذا كان يجب ملء هذا الحقل قبل أن يكتمل الدفع.
        </ParamField>

        <ParamField body="placeholder" type="string">
          نص العنصر النائب المعروض في حقل الإدخال.
        </ParamField>

        <ParamField body="options" type="array">
          قائمة الخيارات لنوع الحقل `dropdown`. مطلوب عندما يكون `field_type` هو `dropdown`، ويتم تجاهله للأنواع الأخرى.

          **مثال**: `["Google", "Twitter", "Friend referral", "Other"]`
        </ParamField>
      </Expandable>
    </ParamField>

    <Info>
      تتضمن ردود العملاء على الحقول المخصصة في:

      * **Webhooks**: `payment.succeeded`, `subscription.active`، وpayloads الأحداث ذات الصلة الأخرى تحتوي على مصفوفة `custom_field_responses`
      * **استجابات API**: تتضمن كائنات الدفع والاشتراك `custom_field_responses`
    </Info>
  </Accordion>

  <Accordion title="Subscription Configuration">
    <ParamField body="subscription_data" type="object">
      إعدادات إضافية لجلسات الدفع التي تحتوي على منتجات الاشتراكات.

      <Expandable title="Subscription data object properties">
        <ParamField body="trial_period_days" type="integer">
          عدد الأيام لفترة التجربة قبل أول رسوم. يجب أن تتراوح بين 0 و10000 يوم.
        </ParamField>

        <ParamField body="on_demand" type="object">
          إعداد الاشتراك عند الطلب للفواتير المستندة إلى الاستخدام أو المقاسة.

          <Expandable title="On-demand object properties">
            <ParamField body="mandate_only" type="boolean" required>
              إذا تم تعيينها إلى true، لن يتم تنفيذ أي رسوم ويتم فقط تفويض تفاصيل طريقة الدفع للاستخدام المستقبلي.
            </ParamField>

            <ParamField body="product_price" type="integer">
              سعر المنتج للرسوم الأولية للعميل. إذا لم يتم تحديده، سيتم استخدام السعر المخزن للمنتج.

              **التنسيق**: يتم تمثيله في أدنى قيمة من العملة (مثلاً، السنتات للدولار الأمريكي). على سبيل المثال، لفرض رسوم قدرها \$1.00، استخدم `100`.
            </ParamField>

            <ParamField body="product_currency" type="string">
              العملة الاختيارية لسعر المنتج. إذا لم يتم تحديده، سيتم الافتراضي إلى عملة المنتج.
            </ParamField>

            <ParamField body="product_description" type="string">
              تجاوز وصف المنتج الاختياري لفواتير العناصر الخطية. إذا لم يتم تحديده، سيتم استخدام الوصف المخزن للمنتج.
            </ParamField>

            <ParamField body="adaptive_currency_fees_inclusive" type="boolean">
              ما إذا كان يجب تضمين الرسوم التكيفية للعملة في سعر المنتج (true) أو إضافتها فوقه (false). يتم تجاهلها إذا لم يتم تمكين التسعير التكيفي.
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>
  </Accordion>
</AccordionGroup>

## أمثلة الاستخدام

إليكم 10 أمثلة شاملة تعرض تكوينات مختلفة لجلسات الدفع لسيناريوهات العمل المختلفة:

### 1. دفع بسيط لمنتج واحد

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_ebook_guide',
      quantity: 1
    }
  ],
  customer: {
    email: 'customer@example.com',
    name: 'John Doe'
  },
  return_url: 'https://yoursite.com/success'
});
```

### 2. سلة متعددة المنتجات

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_laptop',
      quantity: 1
    },
    {
      product_id: 'prod_mouse',
      quantity: 2
    },
    {
      product_id: 'prod_warranty',
      quantity: 1
    }
  ],
  customer: {
    email: 'customer@example.com',
    name: 'John Doe',
    phone_number: '+1234567890'
  },
  billing_address: {
    street: '123 Tech Street',
    city: 'San Francisco',
    state: 'CA',
    country: 'US',
    zipcode: '94102'
  },
  return_url: 'https://electronics-store.com/order-confirmation'
});
```

### 3. اشتراك مع فترة تجريبية

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_monthly_plan',
      quantity: 1
    }
  ],
  subscription_data: {
    trial_period_days: 14
  },
  customer: {
    email: 'user@startup.com',
    name: 'Jane Smith'
  },
  return_url: 'https://saas-app.com/onboarding',
  metadata: {
    plan_type: 'professional',
    referral_source: 'google_ads'
  }
});
```

### 4. دفع مؤكد مسبقاً

<Note>
  عندما يتم تعيين `confirm` إلى `true`، سيتم نقل العميل مباشرة إلى صفحة الدفع، متجاوزاً أي خطوات تأكيد.
</Note>

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_premium_course',
      quantity: 1
    }
  ],
  customer: {
    email: 'student@university.edu',
    name: 'Alex Johnson',
    phone_number: '+1555123456'
  },
  billing_address: {
    street: '456 University Ave',
    city: 'Boston',
    state: 'MA',
    country: 'US',
    zipcode: '02134'
  },
  confirm: true,
  return_url: 'https://learning-platform.com/course-access',
  metadata: {
    course_category: 'programming',
    enrollment_date: '2024-01-15'
  }
});
```

### 5. الدفع مع تجاوز العملة

<Note>
  سيؤثر تجاوز `billing_currency` فقط عندما يتم تمكين العملة التكيفية في إعدادات حسابك. إذا تم تعطيل العملة التكيفية، فلن يكون لهذا المعامل أي تأثير.
</Note>

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_consulting_service',
      quantity: 1
    }
  ],
  customer: {
    email: 'client@company.co.uk',
    name: 'Oliver Williams'
  },
  billing_address: {
    street: '789 Business Park',
    city: 'London',
    state: 'England',
    country: 'GB',
    zipcode: 'SW1A 1AA'
  },
  billing_currency: 'GBP',
  feature_flags: {
    allow_currency_selection: true,
    allow_tax_id: true
  },
  return_url: 'https://consulting-firm.com/service-confirmation'
});
```

### 6. طرق دفع محفوظة للعملاء العائدين

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_monthly_subscription',
      quantity: 1
    }
  ],
  customer: {
    email: 'returning.customer@example.com',
    name: 'Robert Johnson',
    phone_number: '+1555987654'
  },
  show_saved_payment_methods: true,
  feature_flags: {
    allow_phone_number_collection: true,
    always_create_new_customer: false
  },
  return_url: 'https://subscription-service.com/welcome-back',
  metadata: {
    customer_tier: 'premium',
    account_age: 'returning'
  }
});
```

### 7. الدفع بين الشركات مع جمع معرف الضرائب

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_enterprise_license',
      quantity: 5
    }
  ],
  customer: {
    email: 'procurement@enterprise.com',
    name: 'Sarah Davis',
    phone_number: '+1800555000'
  },
  billing_address: {
    street: '1000 Corporate Blvd',
    city: 'New York',
    state: 'NY',
    country: 'US',
    zipcode: '10001'
  },
  feature_flags: {
    allow_tax_id: true,
    allow_phone_number_collection: true,
    always_create_new_customer: false
  },
  return_url: 'https://enterprise-software.com/license-delivery',
  metadata: {
    customer_type: 'enterprise',
    contract_id: 'ENT-2024-001',
    sales_rep: 'john.sales@company.com'
  }
});
```

### 8. دفع بنمط داكن مع أكواد خصم مكدسة

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_gaming_chair',
      quantity: 1
    }
  ],
  discount_codes: ['BLACKFRIDAY2024'],
  customization: {
    theme: 'dark',
    show_order_details: true,
    show_on_demand_tag: false
  },
  feature_flags: {
    allow_discount_code: true
  },
  customer: {
    email: 'gamer@example.com',
    name: 'Mike Chen'
  },
  return_url: 'https://gaming-store.com/order-complete'
});
```

### 9. طرق الدفع الإقليمية (UPI للهند)

لمزيد من المعلومات حول تكوين UPI والاختبار، انظر صفحة <a href="/features/payment-methods/india">طرق الدفع في الهند</a>.

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_online_course_hindi',
      quantity: 1
    }
  ],
  allowed_payment_method_types: [
    'upi_collect',
    'credit',
    'debit'
  ],
  customer: {
    email: 'student@example.in',
    name: 'Priya Sharma',
    phone_number: '+919876543210'
  },
  billing_address: {
    street: 'MG Road',
    city: 'Bangalore',
    state: 'Karnataka',
    country: 'IN',
    zipcode: '560001'
  },
  billing_currency: 'INR',
  return_url: 'https://education-platform.in/course-access',
  metadata: {
    region: 'south_india',
    language: 'hindi'
  }
});
```

### 10. الدفع الآن والدفع لاحقاً (BNPL)

لمزيد من المعلومات حول تكوين BNPL والاختبار، انظر صفحة <a href="/features/payment-methods/bnpl">الدفع الآن والدفع لاحقاً (BNPL)</a>.

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_luxury_watch',
      quantity: 1
    }
  ],
  allowed_payment_method_types: [
    'klarna',
    'afterpay_clearpay',
    'credit',
    'debit'
  ],
  customer: {
    email: 'fashion.lover@example.com',
    name: 'Emma Thompson',
    phone_number: '+1234567890'
  },
  billing_address: {
    street: '555 Fashion Ave',
    city: 'Los Angeles',
    state: 'CA',
    country: 'US',
    zipcode: '90210'
  },
  feature_flags: {
    allow_phone_number_collection: true
  },
  return_url: 'https://luxury-store.com/purchase-confirmation',
  metadata: {
    product_category: 'luxury',
    price_range: 'high_value'
  }
});
```

### 11. استخدام طرق الدفع الحالية للدفع الفوري

استخدم طريقة الدفع المحفوظة للعميل لإنشاء جلسة دفع تتم على الفور، متخطية جمع معلومات طريقة الدفع:

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_premium_plan',
      quantity: 1
    }
  ],
  customer: {
    customer_id: 'cus_123'  // Required when using payment_method_id
  },
  payment_method_id: 'pm_abc123',  // Use customer's saved payment method
  confirm: true,  // Required when using payment_method_id
  return_url: 'https://yourapp.com/success'
});
```

<Warning>
  عند استخدام `payment_method_id`، يجب تعيين `confirm` إلى `true` ويجب تقديم `customer_id` موجود. سيتم التحقق من أهلية طريقة الدفع بالنسبة لعملة الدفع.
</Warning>

<Info>
  يجب أن تكون طريقة الدفع تابعة للعميل ومتوافقة مع عملة الدفع. هذا يمكّن العملاء العائدين من الشراء بنقرة واحدة.
</Info>

### 12. روابط قصيرة للحصول على روابط دفع أنظف

توليد روابط دفع قصيرة وقابلة للمشاركة مع عناوين مخصصة:

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_monthly_subscription',
      quantity: 1
    }
  ],
  short_link: true,  // Generate a shortened payment link
  return_url: 'https://yourapp.com/success',
  customer: {
    email: 'customer@example.com',
    name: 'John Doe'
  }
});

// The checkout_url will be a shortened, cleaner link
console.log(session.checkout_url);  // e.g., https://checkout.dodopayments.com/buy/abc123
```

<Tip>
  الروابط القصيرة مثالية للمشاركة عبر الرسائل النصية أو البريد الإلكتروني أو وسائل التواصل الاجتماعي. من الأسهل تذكرها وتبني ثقة العملاء بشكل أكبر من الروابط الطويلة.
</Tip>

### 13. تخطي صفحة نجاح الدفع بإعادة التوجيه الفوري

إعادة توجيه العملاء مباشرة بعد إتمام الدفع، متجاوزاً صفحة النجاح الافتراضية:

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_digital_product',
      quantity: 1
    }
  ],
  feature_flags: {
    redirect_immediately: true  // Skip success page, redirect immediately
  },
  return_url: 'https://yourapp.com/success',
  customer: {
    email: 'customer@example.com',
    name: 'Jane Smith'
  }
});
```

<Tip>
  استخدم `redirect_immediately: true` عندما يكون لديك صفحة نجاح مخصصة توفر تجربة مستخدم أفضل من صفحة نجاح الدفع الافتراضية. هذا مفيد بشكل خاص لتطبيقات الجوال وتدفق الدفع المضمنة.
</Tip>

<Note>
  عندما يتم تمكين `redirect_immediately`، يتم إعادة توجيه العملاء إلى `return_url` بعد إتمام الدفع مباشرةً، متجاوزين صفحة النجاح الافتراضية تماماً.
</Note>

### 14. فرض لغة معينة

إجبار الدفع ليظهر بلغة معينة، متجاوزاً كشف لغة متصفح العميل:

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_subscription',
      quantity: 1
    }
  ],
  customization: {
    force_language: 'ja'  // Force Japanese language
  },
  customer: {
    email: 'customer@example.jp',
    name: 'Tanaka Yuki'
  },
  return_url: 'https://yourapp.com/success'
});
```

<Tip>
  استخدم `force_language` عندما تعرف لغة العميل المفضلة (مثلما هو موضح في إعدادات حسابه) أو عند استهداف أسواق إقليمية معينة.
</Tip>

**اللغات المدعومة:** العربية (`ar`)، الكتالونية (`ca`)، الصينية (`zh`)، الهولندية (`nl`)، الإنجليزية (`en`)، الفرنسية (`fr`)، الألمانية (`de`)، العبرية (`he`)، الإندونيسية (`id`)، الإيطالية (`it`)، اليابانية (`ja`)، الكورية (`ko`)، الملايوية (`ms`)، البولندية (`pl`)، البرتغالية (`pt`)، الرومانية (`ro`)، الروسية (`ru`)، الإسبانية (`es`)، السويدية (`sv`)، التايلاندية (`th`)، التركية (`tr`)

### 15. جمع الحقول المخصصة

جمع معلومات إضافية من العملاء أثناء الدفع باستخدام الحقول المخصصة:

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_saas_plan',
      quantity: 1
    }
  ],
  custom_fields: [
    {
      key: 'company_name',
      label: 'Company Name',
      field_type: 'text',
      required: true,
      placeholder: 'Acme Inc.'
    },
    {
      key: 'team_size',
      label: 'Team Size',
      field_type: 'dropdown',
      required: true,
      options: ['1-10', '11-50', '51-200', '201-500', '500+']
    },
    {
      key: 'referral_source',
      label: 'How did you hear about us?',
      field_type: 'dropdown',
      required: false,
      options: ['Google', 'Twitter', 'Friend referral', 'Blog post', 'Other']
    },
    {
      key: 'website',
      label: 'Company Website',
      field_type: 'url',
      required: false,
      placeholder: 'https://example.com'
    }
  ],
  customer: {
    email: 'buyer@company.com',
    name: 'Jane Doe'
  },
  return_url: 'https://yourapp.com/success'
});
```

<Info>
  يتم تضمين ردود الحقول المخصصة تلقائيًا في تحميلات webhook (`payment.succeeded`, `subscription.active`، إلخ.) ويمكن استردادها عبر API. استخدامها لإثراء إدارة علاقات العملاء، تشغيل تدفقات الإعداد، أو تخصيص تجربة العميل.
</Info>

**أنواع الحقول المتاحة:** `text`, `number`, `email`, `url`, `date`, `dropdown`, `boolean`

## معاينة لجلسات الدفع

قبل إنشاء جلسة دفع، يمكنك معاينة تفاصيل الأسعار بما في ذلك الضرائب، الخصومات، والإجماليات. هذا مفيد لعرض أسعار دقيقة للعملاء قبل متابعة عملية الدفع.

<Tabs>
  <Tab title="Node.js SDK">
    ```javascript theme={null}
    const preview = await client.checkoutSessions.preview({
      product_cart: [
        { product_id: 'prod_123', quantity: 1 }
      ],
      billing_address: {
        country: 'US',
        state: 'CA',
        zipcode: '94102'
      },
      discount_codes: ['SAVE20']
    });

    console.log('Subtotal:', preview.subtotal);
    console.log('Tax:', preview.tax);
    console.log('Discount:', preview.discount);
    console.log('Total:', preview.total);
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    preview = client.checkout_sessions.preview(
        product_cart=[
            {"product_id": "prod_123", "quantity": 1}
        ],
        billing_address={
            "country": "US",
            "state": "CA",
            "zipcode": "94102"
        },
        discount_codes=["SAVE20"]
    )

    print(f"Subtotal: {preview.subtotal}")
    print(f"Tax: {preview.tax}")
    print(f"Discount: {preview.discount}")
    print(f"Total: {preview.total}")
    ```
  </Tab>
</Tabs>

<Card title="Preview API Reference" icon="code" href="/api-reference/checkout-sessions/preview">
  عرض وثائق نقطة النهاية الكاملة للمعاينة.
</Card>

## الانتقال من الروابط الديناميكية إلى جلسات الدفع

### الاختلافات الرئيسية

في السابق، عند إنشاء رابط دفع باستخدام الروابط الديناميكية، كان يتعين عليك توفير عنوان الفواتير الكامل للعميل.

مع جلسات الدفع، لم يعد ذلك ضرورياً. يمكنك ببساطة تمرير أي معلومات تمتلكها، وسنتولى نحن الباقي. على سبيل المثال:

* إذا كنت تعرف فقط بلد فواتير العميل، فقط قدم ذلك.
* سيجمع تدفق الدفع تلقائياً التفاصيل المفقودة قبل نقل العميل إلى صفحة الدفع.
* من ناحية أخرى، إذا كان لديك جميع المعلومات المطلوبة بالفعل وترغب في التوجه مباشرة إلى صفحة الدفع، يمكنك تمرير مجموعة البيانات الكاملة وتضمين `confirm=true` في طلبك.

### عملية الانتقال

الانتقال من الروابط الديناميكية إلى جلسات الدفع بسيط:

<Steps>
  <Step title="Update your integration">
    قم بتحديث التكامل الخاص بك لاستخدام الطريقة الجديدة لـ API أو SDK.
  </Step>

  <Step title="Adjust request payload">
    قم بتعديل حمولة الطلب وفقًا لتنسيق جلسات الدفع.
  </Step>

  <Step title="That's it!">
    نعم. لا يتطلب الأمر معالجة إضافية أو خطوات انتقال خاصة على جانبك.
  </Step>
</Steps>

## المرجع الكامل لـ API ذو الصلة

<CardGroup cols={2}>
  <Card title="Create Checkout Session" icon="code" href="/api-reference/checkout-sessions/create">
    المرجع الكامل لإنشاء جلسات الدفع مع جميع المعلمات والخيارات المتاحة
  </Card>

  <Card title="Preview Checkout Session" icon="eye" href="/api-reference/checkout-sessions/preview">
    مرجع API لمعاينة التسعير، الضرائب، والإجماليات قبل إنشاء جلسة
  </Card>
</CardGroup>
