<?php

/**
 * Adyen Checkout API
 *
 * The version of the OpenAPI document: 71
 * Generated by: https://openapi-generator.tech
 * OpenAPI Generator version: 6.0.1
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */


namespace Adyen\Model\Checkout;

use ArrayAccess;
use Adyen\Model\Checkout\ObjectSerializer;

/**
 * CreateCheckoutSessionResponse Class Doc Comment
 *
 * @package  Adyen
 * @implements ArrayAccess<string, mixed>
 */
class CreateCheckoutSessionResponse implements ModelInterface, ArrayAccess, \JsonSerializable
{
    public const DISCRIMINATOR = null;

    /**
      * The original name of the model.
      *
      * @var string
      */
    protected static $openAPIModelName = 'CreateCheckoutSessionResponse';

    /**
      * Array of property to type mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $openAPITypes = [
        'accountInfo' => '\Adyen\Model\Checkout\AccountInfo',
        'additionalAmount' => '\Adyen\Model\Checkout\Amount',
        'additionalData' => 'array<string,string>',
        'allowedPaymentMethods' => 'string[]',
        'amount' => '\Adyen\Model\Checkout\Amount',
        'applicationInfo' => '\Adyen\Model\Checkout\ApplicationInfo',
        'authenticationData' => '\Adyen\Model\Checkout\AuthenticationData',
        'billingAddress' => '\Adyen\Model\Checkout\BillingAddress',
        'blockedPaymentMethods' => 'string[]',
        'captureDelayHours' => 'int',
        'channel' => 'string',
        'company' => '\Adyen\Model\Checkout\Company',
        'countryCode' => 'string',
        'dateOfBirth' => '\DateTime',
        'deliverAt' => '\DateTime',
        'deliveryAddress' => '\Adyen\Model\Checkout\DeliveryAddress',
        'enableOneClick' => 'bool',
        'enablePayOut' => 'bool',
        'enableRecurring' => 'bool',
        'expiresAt' => '\DateTime',
        'fundOrigin' => '\Adyen\Model\Checkout\FundOrigin',
        'fundRecipient' => '\Adyen\Model\Checkout\FundRecipient',
        'id' => 'string',
        'installmentOptions' => 'array<string,\Adyen\Model\Checkout\CheckoutSessionInstallmentOption>',
        'lineItems' => '\Adyen\Model\Checkout\LineItem[]',
        'mandate' => '\Adyen\Model\Checkout\Mandate',
        'mcc' => 'string',
        'merchantAccount' => 'string',
        'merchantOrderReference' => 'string',
        'metadata' => 'array<string,string>',
        'mode' => 'string',
        'mpiData' => '\Adyen\Model\Checkout\ThreeDSecureData',
        'platformChargebackLogic' => '\Adyen\Model\Checkout\PlatformChargebackLogic',
        'recurringExpiry' => 'string',
        'recurringFrequency' => 'string',
        'recurringProcessingModel' => 'string',
        'redirectFromIssuerMethod' => 'string',
        'redirectToIssuerMethod' => 'string',
        'reference' => 'string',
        'returnUrl' => 'string',
        'riskData' => '\Adyen\Model\Checkout\RiskData',
        'sessionData' => 'string',
        'shopperEmail' => 'string',
        'shopperIP' => 'string',
        'shopperInteraction' => 'string',
        'shopperLocale' => 'string',
        'shopperName' => '\Adyen\Model\Checkout\ShopperName',
        'shopperReference' => 'string',
        'shopperStatement' => 'string',
        'showInstallmentAmount' => 'bool',
        'showRemovePaymentMethodButton' => 'bool',
        'socialSecurityNumber' => 'string',
        'splitCardFundingSources' => 'bool',
        'splits' => '\Adyen\Model\Checkout\Split[]',
        'store' => 'string',
        'storeFiltrationMode' => 'string',
        'storePaymentMethod' => 'bool',
        'storePaymentMethodMode' => 'string',
        'telephoneNumber' => 'string',
        'themeId' => 'string',
        'threeDS2RequestData' => '\Adyen\Model\Checkout\CheckoutSessionThreeDS2RequestData',
        'threeDSAuthenticationOnly' => 'bool',
        'trustedShopper' => 'bool',
        'url' => 'string'
    ];

    /**
      * Array of property to format mappings. Used for (de)serialization
      *
      * @var string[]
      * @phpstan-var array<string, string|null>
      * @psalm-var array<string, string|null>
      */
    protected static $openAPIFormats = [
        'accountInfo' => null,
        'additionalAmount' => null,
        'additionalData' => null,
        'allowedPaymentMethods' => null,
        'amount' => null,
        'applicationInfo' => null,
        'authenticationData' => null,
        'billingAddress' => null,
        'blockedPaymentMethods' => null,
        'captureDelayHours' => 'int32',
        'channel' => null,
        'company' => null,
        'countryCode' => null,
        'dateOfBirth' => 'date-time',
        'deliverAt' => 'date-time',
        'deliveryAddress' => null,
        'enableOneClick' => null,
        'enablePayOut' => null,
        'enableRecurring' => null,
        'expiresAt' => 'date-time',
        'fundOrigin' => null,
        'fundRecipient' => null,
        'id' => null,
        'installmentOptions' => null,
        'lineItems' => null,
        'mandate' => null,
        'mcc' => null,
        'merchantAccount' => null,
        'merchantOrderReference' => null,
        'metadata' => null,
        'mode' => null,
        'mpiData' => null,
        'platformChargebackLogic' => null,
        'recurringExpiry' => null,
        'recurringFrequency' => null,
        'recurringProcessingModel' => null,
        'redirectFromIssuerMethod' => null,
        'redirectToIssuerMethod' => null,
        'reference' => null,
        'returnUrl' => null,
        'riskData' => null,
        'sessionData' => null,
        'shopperEmail' => null,
        'shopperIP' => null,
        'shopperInteraction' => null,
        'shopperLocale' => null,
        'shopperName' => null,
        'shopperReference' => null,
        'shopperStatement' => null,
        'showInstallmentAmount' => null,
        'showRemovePaymentMethodButton' => null,
        'socialSecurityNumber' => null,
        'splitCardFundingSources' => null,
        'splits' => null,
        'store' => null,
        'storeFiltrationMode' => null,
        'storePaymentMethod' => null,
        'storePaymentMethodMode' => null,
        'telephoneNumber' => null,
        'themeId' => null,
        'threeDS2RequestData' => null,
        'threeDSAuthenticationOnly' => null,
        'trustedShopper' => null,
        'url' => null
    ];

    /**
      * Array of nullable properties. Used for (de)serialization
      *
      * @var boolean[]
      */
    protected static $openAPINullables = [
        'accountInfo' => false,
        'additionalAmount' => false,
        'additionalData' => false,
        'allowedPaymentMethods' => false,
        'amount' => false,
        'applicationInfo' => false,
        'authenticationData' => false,
        'billingAddress' => false,
        'blockedPaymentMethods' => false,
        'captureDelayHours' => true,
        'channel' => false,
        'company' => false,
        'countryCode' => false,
        'dateOfBirth' => false,
        'deliverAt' => false,
        'deliveryAddress' => false,
        'enableOneClick' => false,
        'enablePayOut' => false,
        'enableRecurring' => false,
        'expiresAt' => false,
        'fundOrigin' => false,
        'fundRecipient' => false,
        'id' => false,
        'installmentOptions' => false,
        'lineItems' => false,
        'mandate' => false,
        'mcc' => false,
        'merchantAccount' => false,
        'merchantOrderReference' => false,
        'metadata' => false,
        'mode' => false,
        'mpiData' => false,
        'platformChargebackLogic' => false,
        'recurringExpiry' => false,
        'recurringFrequency' => false,
        'recurringProcessingModel' => false,
        'redirectFromIssuerMethod' => false,
        'redirectToIssuerMethod' => false,
        'reference' => false,
        'returnUrl' => false,
        'riskData' => false,
        'sessionData' => false,
        'shopperEmail' => false,
        'shopperIP' => false,
        'shopperInteraction' => false,
        'shopperLocale' => false,
        'shopperName' => false,
        'shopperReference' => false,
        'shopperStatement' => false,
        'showInstallmentAmount' => false,
        'showRemovePaymentMethodButton' => false,
        'socialSecurityNumber' => false,
        'splitCardFundingSources' => false,
        'splits' => false,
        'store' => false,
        'storeFiltrationMode' => false,
        'storePaymentMethod' => false,
        'storePaymentMethodMode' => false,
        'telephoneNumber' => false,
        'themeId' => false,
        'threeDS2RequestData' => false,
        'threeDSAuthenticationOnly' => false,
        'trustedShopper' => false,
        'url' => false
    ];

    /**
      * If a nullable field gets set to null, insert it here
      *
      * @var boolean[]
      */
    protected $openAPINullablesSetToNull = [];

    /**
     * Array of property to type mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function openAPITypes()
    {
        return self::$openAPITypes;
    }

    /**
     * Array of property to format mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function openAPIFormats()
    {
        return self::$openAPIFormats;
    }

    /**
     * Array of nullable properties
     *
     * @return array
     */
    protected static function openAPINullables(): array
    {
        return self::$openAPINullables;
    }

    /**
     * Array of nullable field names deliberately set to null
     *
     * @return boolean[]
     */
    private function getOpenAPINullablesSetToNull(): array
    {
        return $this->openAPINullablesSetToNull;
    }

    /**
     * Setter - Array of nullable field names deliberately set to null
     *
     * @param boolean[] $openAPINullablesSetToNull
     */
    private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void
    {
        $this->openAPINullablesSetToNull = $openAPINullablesSetToNull;
    }

    /**
     * Checks if a property is nullable
     *
     * @param string $property
     * @return bool
     */
    public static function isNullable(string $property): bool
    {
        return self::openAPINullables()[$property] ?? false;
    }

    /**
     * Checks if a nullable property is set to null.
     *
     * @param string $property
     * @return bool
     */
    public function isNullableSetToNull(string $property): bool
    {
        return in_array($property, $this->getOpenAPINullablesSetToNull(), true);
    }

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @var string[]
     */
    protected static $attributeMap = [
        'accountInfo' => 'accountInfo',
        'additionalAmount' => 'additionalAmount',
        'additionalData' => 'additionalData',
        'allowedPaymentMethods' => 'allowedPaymentMethods',
        'amount' => 'amount',
        'applicationInfo' => 'applicationInfo',
        'authenticationData' => 'authenticationData',
        'billingAddress' => 'billingAddress',
        'blockedPaymentMethods' => 'blockedPaymentMethods',
        'captureDelayHours' => 'captureDelayHours',
        'channel' => 'channel',
        'company' => 'company',
        'countryCode' => 'countryCode',
        'dateOfBirth' => 'dateOfBirth',
        'deliverAt' => 'deliverAt',
        'deliveryAddress' => 'deliveryAddress',
        'enableOneClick' => 'enableOneClick',
        'enablePayOut' => 'enablePayOut',
        'enableRecurring' => 'enableRecurring',
        'expiresAt' => 'expiresAt',
        'fundOrigin' => 'fundOrigin',
        'fundRecipient' => 'fundRecipient',
        'id' => 'id',
        'installmentOptions' => 'installmentOptions',
        'lineItems' => 'lineItems',
        'mandate' => 'mandate',
        'mcc' => 'mcc',
        'merchantAccount' => 'merchantAccount',
        'merchantOrderReference' => 'merchantOrderReference',
        'metadata' => 'metadata',
        'mode' => 'mode',
        'mpiData' => 'mpiData',
        'platformChargebackLogic' => 'platformChargebackLogic',
        'recurringExpiry' => 'recurringExpiry',
        'recurringFrequency' => 'recurringFrequency',
        'recurringProcessingModel' => 'recurringProcessingModel',
        'redirectFromIssuerMethod' => 'redirectFromIssuerMethod',
        'redirectToIssuerMethod' => 'redirectToIssuerMethod',
        'reference' => 'reference',
        'returnUrl' => 'returnUrl',
        'riskData' => 'riskData',
        'sessionData' => 'sessionData',
        'shopperEmail' => 'shopperEmail',
        'shopperIP' => 'shopperIP',
        'shopperInteraction' => 'shopperInteraction',
        'shopperLocale' => 'shopperLocale',
        'shopperName' => 'shopperName',
        'shopperReference' => 'shopperReference',
        'shopperStatement' => 'shopperStatement',
        'showInstallmentAmount' => 'showInstallmentAmount',
        'showRemovePaymentMethodButton' => 'showRemovePaymentMethodButton',
        'socialSecurityNumber' => 'socialSecurityNumber',
        'splitCardFundingSources' => 'splitCardFundingSources',
        'splits' => 'splits',
        'store' => 'store',
        'storeFiltrationMode' => 'storeFiltrationMode',
        'storePaymentMethod' => 'storePaymentMethod',
        'storePaymentMethodMode' => 'storePaymentMethodMode',
        'telephoneNumber' => 'telephoneNumber',
        'themeId' => 'themeId',
        'threeDS2RequestData' => 'threeDS2RequestData',
        'threeDSAuthenticationOnly' => 'threeDSAuthenticationOnly',
        'trustedShopper' => 'trustedShopper',
        'url' => 'url'
    ];

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @var string[]
     */
    protected static $setters = [
        'accountInfo' => 'setAccountInfo',
        'additionalAmount' => 'setAdditionalAmount',
        'additionalData' => 'setAdditionalData',
        'allowedPaymentMethods' => 'setAllowedPaymentMethods',
        'amount' => 'setAmount',
        'applicationInfo' => 'setApplicationInfo',
        'authenticationData' => 'setAuthenticationData',
        'billingAddress' => 'setBillingAddress',
        'blockedPaymentMethods' => 'setBlockedPaymentMethods',
        'captureDelayHours' => 'setCaptureDelayHours',
        'channel' => 'setChannel',
        'company' => 'setCompany',
        'countryCode' => 'setCountryCode',
        'dateOfBirth' => 'setDateOfBirth',
        'deliverAt' => 'setDeliverAt',
        'deliveryAddress' => 'setDeliveryAddress',
        'enableOneClick' => 'setEnableOneClick',
        'enablePayOut' => 'setEnablePayOut',
        'enableRecurring' => 'setEnableRecurring',
        'expiresAt' => 'setExpiresAt',
        'fundOrigin' => 'setFundOrigin',
        'fundRecipient' => 'setFundRecipient',
        'id' => 'setId',
        'installmentOptions' => 'setInstallmentOptions',
        'lineItems' => 'setLineItems',
        'mandate' => 'setMandate',
        'mcc' => 'setMcc',
        'merchantAccount' => 'setMerchantAccount',
        'merchantOrderReference' => 'setMerchantOrderReference',
        'metadata' => 'setMetadata',
        'mode' => 'setMode',
        'mpiData' => 'setMpiData',
        'platformChargebackLogic' => 'setPlatformChargebackLogic',
        'recurringExpiry' => 'setRecurringExpiry',
        'recurringFrequency' => 'setRecurringFrequency',
        'recurringProcessingModel' => 'setRecurringProcessingModel',
        'redirectFromIssuerMethod' => 'setRedirectFromIssuerMethod',
        'redirectToIssuerMethod' => 'setRedirectToIssuerMethod',
        'reference' => 'setReference',
        'returnUrl' => 'setReturnUrl',
        'riskData' => 'setRiskData',
        'sessionData' => 'setSessionData',
        'shopperEmail' => 'setShopperEmail',
        'shopperIP' => 'setShopperIP',
        'shopperInteraction' => 'setShopperInteraction',
        'shopperLocale' => 'setShopperLocale',
        'shopperName' => 'setShopperName',
        'shopperReference' => 'setShopperReference',
        'shopperStatement' => 'setShopperStatement',
        'showInstallmentAmount' => 'setShowInstallmentAmount',
        'showRemovePaymentMethodButton' => 'setShowRemovePaymentMethodButton',
        'socialSecurityNumber' => 'setSocialSecurityNumber',
        'splitCardFundingSources' => 'setSplitCardFundingSources',
        'splits' => 'setSplits',
        'store' => 'setStore',
        'storeFiltrationMode' => 'setStoreFiltrationMode',
        'storePaymentMethod' => 'setStorePaymentMethod',
        'storePaymentMethodMode' => 'setStorePaymentMethodMode',
        'telephoneNumber' => 'setTelephoneNumber',
        'themeId' => 'setThemeId',
        'threeDS2RequestData' => 'setThreeDS2RequestData',
        'threeDSAuthenticationOnly' => 'setThreeDSAuthenticationOnly',
        'trustedShopper' => 'setTrustedShopper',
        'url' => 'setUrl'
    ];

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @var string[]
     */
    protected static $getters = [
        'accountInfo' => 'getAccountInfo',
        'additionalAmount' => 'getAdditionalAmount',
        'additionalData' => 'getAdditionalData',
        'allowedPaymentMethods' => 'getAllowedPaymentMethods',
        'amount' => 'getAmount',
        'applicationInfo' => 'getApplicationInfo',
        'authenticationData' => 'getAuthenticationData',
        'billingAddress' => 'getBillingAddress',
        'blockedPaymentMethods' => 'getBlockedPaymentMethods',
        'captureDelayHours' => 'getCaptureDelayHours',
        'channel' => 'getChannel',
        'company' => 'getCompany',
        'countryCode' => 'getCountryCode',
        'dateOfBirth' => 'getDateOfBirth',
        'deliverAt' => 'getDeliverAt',
        'deliveryAddress' => 'getDeliveryAddress',
        'enableOneClick' => 'getEnableOneClick',
        'enablePayOut' => 'getEnablePayOut',
        'enableRecurring' => 'getEnableRecurring',
        'expiresAt' => 'getExpiresAt',
        'fundOrigin' => 'getFundOrigin',
        'fundRecipient' => 'getFundRecipient',
        'id' => 'getId',
        'installmentOptions' => 'getInstallmentOptions',
        'lineItems' => 'getLineItems',
        'mandate' => 'getMandate',
        'mcc' => 'getMcc',
        'merchantAccount' => 'getMerchantAccount',
        'merchantOrderReference' => 'getMerchantOrderReference',
        'metadata' => 'getMetadata',
        'mode' => 'getMode',
        'mpiData' => 'getMpiData',
        'platformChargebackLogic' => 'getPlatformChargebackLogic',
        'recurringExpiry' => 'getRecurringExpiry',
        'recurringFrequency' => 'getRecurringFrequency',
        'recurringProcessingModel' => 'getRecurringProcessingModel',
        'redirectFromIssuerMethod' => 'getRedirectFromIssuerMethod',
        'redirectToIssuerMethod' => 'getRedirectToIssuerMethod',
        'reference' => 'getReference',
        'returnUrl' => 'getReturnUrl',
        'riskData' => 'getRiskData',
        'sessionData' => 'getSessionData',
        'shopperEmail' => 'getShopperEmail',
        'shopperIP' => 'getShopperIP',
        'shopperInteraction' => 'getShopperInteraction',
        'shopperLocale' => 'getShopperLocale',
        'shopperName' => 'getShopperName',
        'shopperReference' => 'getShopperReference',
        'shopperStatement' => 'getShopperStatement',
        'showInstallmentAmount' => 'getShowInstallmentAmount',
        'showRemovePaymentMethodButton' => 'getShowRemovePaymentMethodButton',
        'socialSecurityNumber' => 'getSocialSecurityNumber',
        'splitCardFundingSources' => 'getSplitCardFundingSources',
        'splits' => 'getSplits',
        'store' => 'getStore',
        'storeFiltrationMode' => 'getStoreFiltrationMode',
        'storePaymentMethod' => 'getStorePaymentMethod',
        'storePaymentMethodMode' => 'getStorePaymentMethodMode',
        'telephoneNumber' => 'getTelephoneNumber',
        'themeId' => 'getThemeId',
        'threeDS2RequestData' => 'getThreeDS2RequestData',
        'threeDSAuthenticationOnly' => 'getThreeDSAuthenticationOnly',
        'trustedShopper' => 'getTrustedShopper',
        'url' => 'getUrl'
    ];

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @return array
     */
    public static function attributeMap()
    {
        return self::$attributeMap;
    }

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @return array
     */
    public static function setters()
    {
        return self::$setters;
    }

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @return array
     */
    public static function getters()
    {
        return self::$getters;
    }

    /**
     * The original name of the model.
     *
     * @return string
     */
    public function getModelName()
    {
        return self::$openAPIModelName;
    }

    public const CHANNEL_I_OS = 'iOS';
    public const CHANNEL_ANDROID = 'Android';
    public const CHANNEL_WEB = 'Web';
    public const MODE_EMBEDDED = 'embedded';
    public const MODE_HOSTED = 'hosted';
    public const RECURRING_PROCESSING_MODEL_CARD_ON_FILE = 'CardOnFile';
    public const RECURRING_PROCESSING_MODEL_SUBSCRIPTION = 'Subscription';
    public const RECURRING_PROCESSING_MODEL_UNSCHEDULED_CARD_ON_FILE = 'UnscheduledCardOnFile';
    public const SHOPPER_INTERACTION_ECOMMERCE = 'Ecommerce';
    public const SHOPPER_INTERACTION_CONT_AUTH = 'ContAuth';
    public const SHOPPER_INTERACTION_MOTO = 'Moto';
    public const SHOPPER_INTERACTION_POS = 'POS';
    public const STORE_FILTRATION_MODE_EXCLUSIVE = 'exclusive';
    public const STORE_FILTRATION_MODE_INCLUSIVE = 'inclusive';
    public const STORE_FILTRATION_MODE_SKIP_FILTER = 'skipFilter';
    public const STORE_PAYMENT_METHOD_MODE_ASK_FOR_CONSENT = 'askForConsent';
    public const STORE_PAYMENT_METHOD_MODE_DISABLED = 'disabled';
    public const STORE_PAYMENT_METHOD_MODE_ENABLED = 'enabled';

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getChannelAllowableValues()
    {
        return [
            self::CHANNEL_I_OS,
            self::CHANNEL_ANDROID,
            self::CHANNEL_WEB,
        ];
    }
    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getModeAllowableValues()
    {
        return [
            self::MODE_EMBEDDED,
            self::MODE_HOSTED,
        ];
    }
    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getRecurringProcessingModelAllowableValues()
    {
        return [
            self::RECURRING_PROCESSING_MODEL_CARD_ON_FILE,
            self::RECURRING_PROCESSING_MODEL_SUBSCRIPTION,
            self::RECURRING_PROCESSING_MODEL_UNSCHEDULED_CARD_ON_FILE,
        ];
    }
    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getShopperInteractionAllowableValues()
    {
        return [
            self::SHOPPER_INTERACTION_ECOMMERCE,
            self::SHOPPER_INTERACTION_CONT_AUTH,
            self::SHOPPER_INTERACTION_MOTO,
            self::SHOPPER_INTERACTION_POS,
        ];
    }
    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getStoreFiltrationModeAllowableValues()
    {
        return [
            self::STORE_FILTRATION_MODE_EXCLUSIVE,
            self::STORE_FILTRATION_MODE_INCLUSIVE,
            self::STORE_FILTRATION_MODE_SKIP_FILTER,
        ];
    }
    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getStorePaymentMethodModeAllowableValues()
    {
        return [
            self::STORE_PAYMENT_METHOD_MODE_ASK_FOR_CONSENT,
            self::STORE_PAYMENT_METHOD_MODE_DISABLED,
            self::STORE_PAYMENT_METHOD_MODE_ENABLED,
        ];
    }
    /**
     * Associative array for storing property values
     *
     * @var mixed[]
     */
    protected $container = [];

    /**
     * Constructor
     *
     * @param mixed[] $data Associated array of property values
     *                      initializing the model
     */
    public function __construct(?array $data = null)
    {
        $this->setIfExists('accountInfo', $data ?? [], null);
        $this->setIfExists('additionalAmount', $data ?? [], null);
        $this->setIfExists('additionalData', $data ?? [], null);
        $this->setIfExists('allowedPaymentMethods', $data ?? [], null);
        $this->setIfExists('amount', $data ?? [], null);
        $this->setIfExists('applicationInfo', $data ?? [], null);
        $this->setIfExists('authenticationData', $data ?? [], null);
        $this->setIfExists('billingAddress', $data ?? [], null);
        $this->setIfExists('blockedPaymentMethods', $data ?? [], null);
        $this->setIfExists('captureDelayHours', $data ?? [], null);
        $this->setIfExists('channel', $data ?? [], null);
        $this->setIfExists('company', $data ?? [], null);
        $this->setIfExists('countryCode', $data ?? [], null);
        $this->setIfExists('dateOfBirth', $data ?? [], null);
        $this->setIfExists('deliverAt', $data ?? [], null);
        $this->setIfExists('deliveryAddress', $data ?? [], null);
        $this->setIfExists('enableOneClick', $data ?? [], null);
        $this->setIfExists('enablePayOut', $data ?? [], null);
        $this->setIfExists('enableRecurring', $data ?? [], null);
        $this->setIfExists('expiresAt', $data ?? [], null);
        $this->setIfExists('fundOrigin', $data ?? [], null);
        $this->setIfExists('fundRecipient', $data ?? [], null);
        $this->setIfExists('id', $data ?? [], null);
        $this->setIfExists('installmentOptions', $data ?? [], null);
        $this->setIfExists('lineItems', $data ?? [], null);
        $this->setIfExists('mandate', $data ?? [], null);
        $this->setIfExists('mcc', $data ?? [], null);
        $this->setIfExists('merchantAccount', $data ?? [], null);
        $this->setIfExists('merchantOrderReference', $data ?? [], null);
        $this->setIfExists('metadata', $data ?? [], null);
        $this->setIfExists('mode', $data ?? [], null);
        $this->setIfExists('mpiData', $data ?? [], null);
        $this->setIfExists('platformChargebackLogic', $data ?? [], null);
        $this->setIfExists('recurringExpiry', $data ?? [], null);
        $this->setIfExists('recurringFrequency', $data ?? [], null);
        $this->setIfExists('recurringProcessingModel', $data ?? [], null);
        $this->setIfExists('redirectFromIssuerMethod', $data ?? [], null);
        $this->setIfExists('redirectToIssuerMethod', $data ?? [], null);
        $this->setIfExists('reference', $data ?? [], null);
        $this->setIfExists('returnUrl', $data ?? [], null);
        $this->setIfExists('riskData', $data ?? [], null);
        $this->setIfExists('sessionData', $data ?? [], null);
        $this->setIfExists('shopperEmail', $data ?? [], null);
        $this->setIfExists('shopperIP', $data ?? [], null);
        $this->setIfExists('shopperInteraction', $data ?? [], null);
        $this->setIfExists('shopperLocale', $data ?? [], null);
        $this->setIfExists('shopperName', $data ?? [], null);
        $this->setIfExists('shopperReference', $data ?? [], null);
        $this->setIfExists('shopperStatement', $data ?? [], null);
        $this->setIfExists('showInstallmentAmount', $data ?? [], null);
        $this->setIfExists('showRemovePaymentMethodButton', $data ?? [], null);
        $this->setIfExists('socialSecurityNumber', $data ?? [], null);
        $this->setIfExists('splitCardFundingSources', $data ?? [], null);
        $this->setIfExists('splits', $data ?? [], null);
        $this->setIfExists('store', $data ?? [], null);
        $this->setIfExists('storeFiltrationMode', $data ?? [], null);
        $this->setIfExists('storePaymentMethod', $data ?? [], null);
        $this->setIfExists('storePaymentMethodMode', $data ?? [], null);
        $this->setIfExists('telephoneNumber', $data ?? [], null);
        $this->setIfExists('themeId', $data ?? [], null);
        $this->setIfExists('threeDS2RequestData', $data ?? [], null);
        $this->setIfExists('threeDSAuthenticationOnly', $data ?? [], null);
        $this->setIfExists('trustedShopper', $data ?? [], null);
        $this->setIfExists('url', $data ?? [], null);
    }

    /**
    * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName
    * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the
    * $this->openAPINullablesSetToNull array
    *
    * @param string $variableName
    * @param array  $fields
    * @param mixed  $defaultValue
    */
    private function setIfExists(string $variableName, array $fields, $defaultValue): void
    {
        if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) {
            $this->openAPINullablesSetToNull[] = $variableName;
        }

        $this->container[$variableName] = $fields[$variableName] ?? $defaultValue;
    }

    /**
     * Show all the invalid properties with reasons.
     *
     * @return array invalid properties with reasons
     */
    public function listInvalidProperties()
    {
        $invalidProperties = [];

        if ($this->container['amount'] === null) {
            $invalidProperties[] = "'amount' can't be null";
        }
        $allowedValues = $this->getChannelAllowableValues();
        if (!is_null($this->container['channel']) && !in_array($this->container['channel'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'channel', must be one of '%s'",
                $this->container['channel'],
                implode("', '", $allowedValues)
            );
        }

        if ($this->container['expiresAt'] === null) {
            $invalidProperties[] = "'expiresAt' can't be null";
        }
        if ($this->container['id'] === null) {
            $invalidProperties[] = "'id' can't be null";
        }
        if ($this->container['merchantAccount'] === null) {
            $invalidProperties[] = "'merchantAccount' can't be null";
        }
        $allowedValues = $this->getModeAllowableValues();
        if (!is_null($this->container['mode']) && !in_array($this->container['mode'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'mode', must be one of '%s'",
                $this->container['mode'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getRecurringProcessingModelAllowableValues();
        if (!is_null($this->container['recurringProcessingModel']) && !in_array($this->container['recurringProcessingModel'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'recurringProcessingModel', must be one of '%s'",
                $this->container['recurringProcessingModel'],
                implode("', '", $allowedValues)
            );
        }

        if ($this->container['reference'] === null) {
            $invalidProperties[] = "'reference' can't be null";
        }
        if ($this->container['returnUrl'] === null) {
            $invalidProperties[] = "'returnUrl' can't be null";
        }
        $allowedValues = $this->getShopperInteractionAllowableValues();
        if (!is_null($this->container['shopperInteraction']) && !in_array($this->container['shopperInteraction'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'shopperInteraction', must be one of '%s'",
                $this->container['shopperInteraction'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getStoreFiltrationModeAllowableValues();
        if (!is_null($this->container['storeFiltrationMode']) && !in_array($this->container['storeFiltrationMode'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'storeFiltrationMode', must be one of '%s'",
                $this->container['storeFiltrationMode'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getStorePaymentMethodModeAllowableValues();
        if (!is_null($this->container['storePaymentMethodMode']) && !in_array($this->container['storePaymentMethodMode'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'storePaymentMethodMode', must be one of '%s'",
                $this->container['storePaymentMethodMode'],
                implode("', '", $allowedValues)
            );
        }

        return $invalidProperties;
    }

    /**
     * Validate all the properties in the model
     * return true if all passed
     *
     * @return bool True if all properties are valid
     */
    public function valid()
    {
        return count($this->listInvalidProperties()) === 0;
    }


    /**
     * Gets accountInfo
     *
     * @return \Adyen\Model\Checkout\AccountInfo|null
     */
    public function getAccountInfo()
    {
        return $this->container['accountInfo'];
    }

    /**
     * Sets accountInfo
     *
     * @param \Adyen\Model\Checkout\AccountInfo|null $accountInfo accountInfo
     *
     * @return self
     */
    public function setAccountInfo($accountInfo)
    {
        $this->container['accountInfo'] = $accountInfo;

        return $this;
    }

    /**
     * Gets additionalAmount
     *
     * @return \Adyen\Model\Checkout\Amount|null
     */
    public function getAdditionalAmount()
    {
        return $this->container['additionalAmount'];
    }

    /**
     * Sets additionalAmount
     *
     * @param \Adyen\Model\Checkout\Amount|null $additionalAmount additionalAmount
     *
     * @return self
     */
    public function setAdditionalAmount($additionalAmount)
    {
        $this->container['additionalAmount'] = $additionalAmount;

        return $this;
    }

    /**
     * Gets additionalData
     *
     * @return array<string,string>|null
     */
    public function getAdditionalData()
    {
        return $this->container['additionalData'];
    }

    /**
     * Sets additionalData
     *
     * @param array<string,string>|null $additionalData This field contains additional data, which may be required for a particular payment request.  The `additionalData` object consists of entries, each of which includes the key and value.
     *
     * @return self
     */
    public function setAdditionalData($additionalData)
    {
        $this->container['additionalData'] = $additionalData;

        return $this;
    }

    /**
     * Gets allowedPaymentMethods
     *
     * @return string[]|null
     */
    public function getAllowedPaymentMethods()
    {
        return $this->container['allowedPaymentMethods'];
    }

    /**
     * Sets allowedPaymentMethods
     *
     * @param string[]|null $allowedPaymentMethods List of payment methods to be presented to the shopper. To refer to payment methods, use their [payment method type](https://docs.adyen.com/payment-methods/payment-method-types).  Example: `\"allowedPaymentMethods\":[\"ideal\",\"applepay\"]`
     *
     * @return self
     */
    public function setAllowedPaymentMethods($allowedPaymentMethods)
    {
        $this->container['allowedPaymentMethods'] = $allowedPaymentMethods;

        return $this;
    }

    /**
     * Gets amount
     *
     * @return \Adyen\Model\Checkout\Amount
     */
    public function getAmount()
    {
        return $this->container['amount'];
    }

    /**
     * Sets amount
     *
     * @param \Adyen\Model\Checkout\Amount $amount amount
     *
     * @return self
     */
    public function setAmount($amount)
    {
        $this->container['amount'] = $amount;

        return $this;
    }

    /**
     * Gets applicationInfo
     *
     * @return \Adyen\Model\Checkout\ApplicationInfo|null
     */
    public function getApplicationInfo()
    {
        return $this->container['applicationInfo'];
    }

    /**
     * Sets applicationInfo
     *
     * @param \Adyen\Model\Checkout\ApplicationInfo|null $applicationInfo applicationInfo
     *
     * @return self
     */
    public function setApplicationInfo($applicationInfo)
    {
        $this->container['applicationInfo'] = $applicationInfo;

        return $this;
    }

    /**
     * Gets authenticationData
     *
     * @return \Adyen\Model\Checkout\AuthenticationData|null
     */
    public function getAuthenticationData()
    {
        return $this->container['authenticationData'];
    }

    /**
     * Sets authenticationData
     *
     * @param \Adyen\Model\Checkout\AuthenticationData|null $authenticationData authenticationData
     *
     * @return self
     */
    public function setAuthenticationData($authenticationData)
    {
        $this->container['authenticationData'] = $authenticationData;

        return $this;
    }

    /**
     * Gets billingAddress
     *
     * @return \Adyen\Model\Checkout\BillingAddress|null
     */
    public function getBillingAddress()
    {
        return $this->container['billingAddress'];
    }

    /**
     * Sets billingAddress
     *
     * @param \Adyen\Model\Checkout\BillingAddress|null $billingAddress billingAddress
     *
     * @return self
     */
    public function setBillingAddress($billingAddress)
    {
        $this->container['billingAddress'] = $billingAddress;

        return $this;
    }

    /**
     * Gets blockedPaymentMethods
     *
     * @return string[]|null
     */
    public function getBlockedPaymentMethods()
    {
        return $this->container['blockedPaymentMethods'];
    }

    /**
     * Sets blockedPaymentMethods
     *
     * @param string[]|null $blockedPaymentMethods List of payment methods to be hidden from the shopper. To refer to payment methods, use their [payment method type](https://docs.adyen.com/payment-methods/payment-method-types).  Example: `\"blockedPaymentMethods\":[\"ideal\",\"applepay\"]`
     *
     * @return self
     */
    public function setBlockedPaymentMethods($blockedPaymentMethods)
    {
        $this->container['blockedPaymentMethods'] = $blockedPaymentMethods;

        return $this;
    }

    /**
     * Gets captureDelayHours
     *
     * @return int|null
     */
    public function getCaptureDelayHours()
    {
        return $this->container['captureDelayHours'];
    }

    /**
     * Sets captureDelayHours
     *
     * @param int|null $captureDelayHours The delay between the authorisation and scheduled auto-capture, specified in hours.
     *
     * @return self
     */
    public function setCaptureDelayHours($captureDelayHours)
    {
        $this->container['captureDelayHours'] = $captureDelayHours;

        return $this;
    }

    /**
     * Gets channel
     *
     * @return string|null
     */
    public function getChannel()
    {
        return $this->container['channel'];
    }

    /**
     * Sets channel
     *
     * @param string|null $channel The platform where a payment transaction takes place. This field is optional for filtering out payment methods that are only available on specific platforms. If this value is not set, then we will try to infer it from the `sdkVersion` or `token`.  Possible values: * **iOS** * **Android** * **Web**
     *
     * @return self
     */
    public function setChannel($channel)
    {
        $allowedValues = $this->getChannelAllowableValues();
        if (!in_array($channel, $allowedValues, true)) {
            error_log(
                sprintf(
                    "channel: unexpected enum value '%s' - Supported values are [%s]",
                    $channel,
                    implode(', ', $allowedValues)
                )
            );
        }
        $this->container['channel'] = $channel;

        return $this;
    }

    /**
     * Gets company
     *
     * @return \Adyen\Model\Checkout\Company|null
     */
    public function getCompany()
    {
        return $this->container['company'];
    }

    /**
     * Sets company
     *
     * @param \Adyen\Model\Checkout\Company|null $company company
     *
     * @return self
     */
    public function setCompany($company)
    {
        $this->container['company'] = $company;

        return $this;
    }

    /**
     * Gets countryCode
     *
     * @return string|null
     */
    public function getCountryCode()
    {
        return $this->container['countryCode'];
    }

    /**
     * Sets countryCode
     *
     * @param string|null $countryCode The shopper's two-letter country code.
     *
     * @return self
     */
    public function setCountryCode($countryCode)
    {
        $this->container['countryCode'] = $countryCode;

        return $this;
    }

    /**
     * Gets dateOfBirth
     *
     * @return \DateTime|null
     */
    public function getDateOfBirth()
    {
        return $this->container['dateOfBirth'];
    }

    /**
     * Sets dateOfBirth
     *
     * @param \DateTime|null $dateOfBirth The shopper's date of birth in [ISO8601](https://www.iso.org/iso-8601-date-and-time-format.html) format.
     *
     * @return self
     */
    public function setDateOfBirth($dateOfBirth)
    {
        $this->container['dateOfBirth'] = $dateOfBirth;

        return $this;
    }

    /**
     * Gets deliverAt
     *
     * @return \DateTime|null
     */
    public function getDeliverAt()
    {
        return $this->container['deliverAt'];
    }

    /**
     * Sets deliverAt
     *
     * @param \DateTime|null $deliverAt The date and time when the purchased goods should be delivered.  [ISO 8601](https://www.w3.org/TR/NOTE-datetime) format: YYYY-MM-DDThh:mm:ss+TZD, for example, **2020-12-18T10:15:30+01:00**.
     *
     * @return self
     */
    public function setDeliverAt($deliverAt)
    {
        $this->container['deliverAt'] = $deliverAt;

        return $this;
    }

    /**
     * Gets deliveryAddress
     *
     * @return \Adyen\Model\Checkout\DeliveryAddress|null
     */
    public function getDeliveryAddress()
    {
        return $this->container['deliveryAddress'];
    }

    /**
     * Sets deliveryAddress
     *
     * @param \Adyen\Model\Checkout\DeliveryAddress|null $deliveryAddress deliveryAddress
     *
     * @return self
     */
    public function setDeliveryAddress($deliveryAddress)
    {
        $this->container['deliveryAddress'] = $deliveryAddress;

        return $this;
    }

    /**
     * Gets enableOneClick
     *
     * @return bool|null
     */
    public function getEnableOneClick()
    {
        return $this->container['enableOneClick'];
    }

    /**
     * Sets enableOneClick
     *
     * @param bool|null $enableOneClick When true and `shopperReference` is provided, the shopper will be asked if the payment details should be stored for future [one-click payments](https://docs.adyen.com/get-started-with-adyen/payment-glossary/#one-click-payments-definition).
     *
     * @return self
     */
    public function setEnableOneClick($enableOneClick)
    {
        $this->container['enableOneClick'] = $enableOneClick;

        return $this;
    }

    /**
     * Gets enablePayOut
     *
     * @return bool|null
     */
    public function getEnablePayOut()
    {
        return $this->container['enablePayOut'];
    }

    /**
     * Sets enablePayOut
     *
     * @param bool|null $enablePayOut When true and `shopperReference` is provided, the payment details will be tokenized for payouts.
     *
     * @return self
     */
    public function setEnablePayOut($enablePayOut)
    {
        $this->container['enablePayOut'] = $enablePayOut;

        return $this;
    }

    /**
     * Gets enableRecurring
     *
     * @return bool|null
     */
    public function getEnableRecurring()
    {
        return $this->container['enableRecurring'];
    }

    /**
     * Sets enableRecurring
     *
     * @param bool|null $enableRecurring When true and `shopperReference` is provided, the payment details will be stored for [recurring payments](https://docs.adyen.com/online-payments/tokenization/#recurring-payment-types) where the shopper is not present, such as subscription or automatic top-up payments.
     *
     * @return self
     */
    public function setEnableRecurring($enableRecurring)
    {
        $this->container['enableRecurring'] = $enableRecurring;

        return $this;
    }

    /**
     * Gets expiresAt
     *
     * @return \DateTime
     */
    public function getExpiresAt()
    {
        return $this->container['expiresAt'];
    }

    /**
     * Sets expiresAt
     *
     * @param \DateTime $expiresAt The date the session expires in [ISO8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. When not specified, the expiry date is set to 1 hour after session creation. You cannot set the session expiry to more than 24 hours after session creation.
     *
     * @return self
     */
    public function setExpiresAt($expiresAt)
    {
        $this->container['expiresAt'] = $expiresAt;

        return $this;
    }

    /**
     * Gets fundOrigin
     *
     * @return \Adyen\Model\Checkout\FundOrigin|null
     */
    public function getFundOrigin()
    {
        return $this->container['fundOrigin'];
    }

    /**
     * Sets fundOrigin
     *
     * @param \Adyen\Model\Checkout\FundOrigin|null $fundOrigin fundOrigin
     *
     * @return self
     */
    public function setFundOrigin($fundOrigin)
    {
        $this->container['fundOrigin'] = $fundOrigin;

        return $this;
    }

    /**
     * Gets fundRecipient
     *
     * @return \Adyen\Model\Checkout\FundRecipient|null
     */
    public function getFundRecipient()
    {
        return $this->container['fundRecipient'];
    }

    /**
     * Sets fundRecipient
     *
     * @param \Adyen\Model\Checkout\FundRecipient|null $fundRecipient fundRecipient
     *
     * @return self
     */
    public function setFundRecipient($fundRecipient)
    {
        $this->container['fundRecipient'] = $fundRecipient;

        return $this;
    }

    /**
     * Gets id
     *
     * @return string
     */
    public function getId()
    {
        return $this->container['id'];
    }

    /**
     * Sets id
     *
     * @param string $id A unique identifier of the session.
     *
     * @return self
     */
    public function setId($id)
    {
        $this->container['id'] = $id;

        return $this;
    }

    /**
     * Gets installmentOptions
     *
     * @return array<string,\Adyen\Model\Checkout\CheckoutSessionInstallmentOption>|null
     */
    public function getInstallmentOptions()
    {
        return $this->container['installmentOptions'];
    }

    /**
     * Sets installmentOptions
     *
     * @param array<string,\Adyen\Model\Checkout\CheckoutSessionInstallmentOption>|null $installmentOptions A set of key-value pairs that specifies the installment options available per payment method. The key must be a payment method name in lowercase. For example, **card** to specify installment options for all cards, or **visa** or **mc**. The value must be an object containing the installment options.
     *
     * @return self
     */
    public function setInstallmentOptions($installmentOptions)
    {
        $this->container['installmentOptions'] = $installmentOptions;

        return $this;
    }

    /**
     * Gets lineItems
     *
     * @return \Adyen\Model\Checkout\LineItem[]|null
     */
    public function getLineItems()
    {
        return $this->container['lineItems'];
    }

    /**
     * Sets lineItems
     *
     * @param \Adyen\Model\Checkout\LineItem[]|null $lineItems Price and product information about the purchased items, to be included on the invoice sent to the shopper. > This field is required for 3x 4x Oney, Affirm, Afterpay, Clearpay, Klarna, Ratepay, and Riverty.
     *
     * @return self
     */
    public function setLineItems($lineItems)
    {
        $this->container['lineItems'] = $lineItems;

        return $this;
    }

    /**
     * Gets mandate
     *
     * @return \Adyen\Model\Checkout\Mandate|null
     */
    public function getMandate()
    {
        return $this->container['mandate'];
    }

    /**
     * Sets mandate
     *
     * @param \Adyen\Model\Checkout\Mandate|null $mandate mandate
     *
     * @return self
     */
    public function setMandate($mandate)
    {
        $this->container['mandate'] = $mandate;

        return $this;
    }

    /**
     * Gets mcc
     *
     * @return string|null
     */
    public function getMcc()
    {
        return $this->container['mcc'];
    }

    /**
     * Sets mcc
     *
     * @param string|null $mcc The [merchant category code](https://en.wikipedia.org/wiki/Merchant_category_code) (MCC) is a four-digit number, which relates to a particular market segment. This code reflects the predominant activity that is conducted by the merchant.
     *
     * @return self
     */
    public function setMcc($mcc)
    {
        $this->container['mcc'] = $mcc;

        return $this;
    }

    /**
     * Gets merchantAccount
     *
     * @return string
     */
    public function getMerchantAccount()
    {
        return $this->container['merchantAccount'];
    }

    /**
     * Sets merchantAccount
     *
     * @param string $merchantAccount The merchant account identifier, with which you want to process the transaction.
     *
     * @return self
     */
    public function setMerchantAccount($merchantAccount)
    {
        $this->container['merchantAccount'] = $merchantAccount;

        return $this;
    }

    /**
     * Gets merchantOrderReference
     *
     * @return string|null
     */
    public function getMerchantOrderReference()
    {
        return $this->container['merchantOrderReference'];
    }

    /**
     * Sets merchantOrderReference
     *
     * @param string|null $merchantOrderReference This reference allows linking multiple transactions to each other for reporting purposes (i.e. order auth-rate). The reference should be unique per billing cycle. The same merchant order reference should never be reused after the first authorised attempt. If used, this field should be supplied for all incoming authorisations. > We strongly recommend you send the `merchantOrderReference` value to benefit from linking payment requests when authorisation retries take place. In addition, we recommend you provide `retry.orderAttemptNumber`, `retry.chainAttemptNumber`, and `retry.skipRetry` values in `PaymentRequest.additionalData`.
     *
     * @return self
     */
    public function setMerchantOrderReference($merchantOrderReference)
    {
        $this->container['merchantOrderReference'] = $merchantOrderReference;

        return $this;
    }

    /**
     * Gets metadata
     *
     * @return array<string,string>|null
     */
    public function getMetadata()
    {
        return $this->container['metadata'];
    }

    /**
     * Sets metadata
     *
     * @param array<string,string>|null $metadata Metadata consists of entries, each of which includes a key and a value. Limits: * Maximum 20 key-value pairs per request. * Maximum 20 characters per key. * Maximum 80 characters per value.
     *
     * @return self
     */
    public function setMetadata($metadata)
    {
        $this->container['metadata'] = $metadata;

        return $this;
    }

    /**
     * Gets mode
     *
     * @return string|null
     */
    public function getMode()
    {
        return $this->container['mode'];
    }

    /**
     * Sets mode
     *
     * @param string|null $mode Indicates the type of front end integration. Possible values: * **embedded** (default): Drop-in or Components integration * **hosted**: Hosted Checkout integration
     *
     * @return self
     */
    public function setMode($mode)
    {
        $allowedValues = $this->getModeAllowableValues();
        if (!in_array($mode, $allowedValues, true)) {
            error_log(
                sprintf(
                    "mode: unexpected enum value '%s' - Supported values are [%s]",
                    $mode,
                    implode(', ', $allowedValues)
                )
            );
        }
        $this->container['mode'] = $mode;

        return $this;
    }

    /**
     * Gets mpiData
     *
     * @return \Adyen\Model\Checkout\ThreeDSecureData|null
     */
    public function getMpiData()
    {
        return $this->container['mpiData'];
    }

    /**
     * Sets mpiData
     *
     * @param \Adyen\Model\Checkout\ThreeDSecureData|null $mpiData mpiData
     *
     * @return self
     */
    public function setMpiData($mpiData)
    {
        $this->container['mpiData'] = $mpiData;

        return $this;
    }

    /**
     * Gets platformChargebackLogic
     *
     * @return \Adyen\Model\Checkout\PlatformChargebackLogic|null
     */
    public function getPlatformChargebackLogic()
    {
        return $this->container['platformChargebackLogic'];
    }

    /**
     * Sets platformChargebackLogic
     *
     * @param \Adyen\Model\Checkout\PlatformChargebackLogic|null $platformChargebackLogic platformChargebackLogic
     *
     * @return self
     */
    public function setPlatformChargebackLogic($platformChargebackLogic)
    {
        $this->container['platformChargebackLogic'] = $platformChargebackLogic;

        return $this;
    }

    /**
     * Gets recurringExpiry
     *
     * @return string|null
     */
    public function getRecurringExpiry()
    {
        return $this->container['recurringExpiry'];
    }

    /**
     * Sets recurringExpiry
     *
     * @param string|null $recurringExpiry Date after which no further authorisations shall be performed. Only for 3D Secure 2.
     *
     * @return self
     */
    public function setRecurringExpiry($recurringExpiry)
    {
        $this->container['recurringExpiry'] = $recurringExpiry;

        return $this;
    }

    /**
     * Gets recurringFrequency
     *
     * @return string|null
     */
    public function getRecurringFrequency()
    {
        return $this->container['recurringFrequency'];
    }

    /**
     * Sets recurringFrequency
     *
     * @param string|null $recurringFrequency Minimum number of days between authorisations. Only for 3D Secure 2.
     *
     * @return self
     */
    public function setRecurringFrequency($recurringFrequency)
    {
        $this->container['recurringFrequency'] = $recurringFrequency;

        return $this;
    }

    /**
     * Gets recurringProcessingModel
     *
     * @return string|null
     */
    public function getRecurringProcessingModel()
    {
        return $this->container['recurringProcessingModel'];
    }

    /**
     * Sets recurringProcessingModel
     *
     * @param string|null $recurringProcessingModel Defines a recurring payment type. Required when creating a token to store payment details. Allowed values: * `Subscription` – A transaction for a fixed or variable amount, which follows a fixed schedule. * `CardOnFile` – With a card-on-file (CoF) transaction, card details are stored to enable one-click or omnichannel journeys, or simply to streamline the checkout process. Any subscription not following a fixed schedule is also considered a card-on-file transaction. * `UnscheduledCardOnFile` – An unscheduled card-on-file (UCoF) transaction is a transaction that occurs on a non-fixed schedule and/or have variable amounts. For example, automatic top-ups when a cardholder's balance drops below a certain amount.
     *
     * @return self
     */
    public function setRecurringProcessingModel($recurringProcessingModel)
    {
        $allowedValues = $this->getRecurringProcessingModelAllowableValues();
        if (!in_array($recurringProcessingModel, $allowedValues, true)) {
            error_log(
                sprintf(
                    "recurringProcessingModel: unexpected enum value '%s' - Supported values are [%s]",
                    $recurringProcessingModel,
                    implode(', ', $allowedValues)
                )
            );
        }
        $this->container['recurringProcessingModel'] = $recurringProcessingModel;

        return $this;
    }

    /**
     * Gets redirectFromIssuerMethod
     *
     * @return string|null
     */
    public function getRedirectFromIssuerMethod()
    {
        return $this->container['redirectFromIssuerMethod'];
    }

    /**
     * Sets redirectFromIssuerMethod
     *
     * @param string|null $redirectFromIssuerMethod Specifies the redirect method (GET or POST) when redirecting back from the issuer.
     *
     * @return self
     */
    public function setRedirectFromIssuerMethod($redirectFromIssuerMethod)
    {
        $this->container['redirectFromIssuerMethod'] = $redirectFromIssuerMethod;

        return $this;
    }

    /**
     * Gets redirectToIssuerMethod
     *
     * @return string|null
     */
    public function getRedirectToIssuerMethod()
    {
        return $this->container['redirectToIssuerMethod'];
    }

    /**
     * Sets redirectToIssuerMethod
     *
     * @param string|null $redirectToIssuerMethod Specifies the redirect method (GET or POST) when redirecting to the issuer.
     *
     * @return self
     */
    public function setRedirectToIssuerMethod($redirectToIssuerMethod)
    {
        $this->container['redirectToIssuerMethod'] = $redirectToIssuerMethod;

        return $this;
    }

    /**
     * Gets reference
     *
     * @return string
     */
    public function getReference()
    {
        return $this->container['reference'];
    }

    /**
     * Sets reference
     *
     * @param string $reference The reference to uniquely identify a payment.
     *
     * @return self
     */
    public function setReference($reference)
    {
        $this->container['reference'] = $reference;

        return $this;
    }

    /**
     * Gets returnUrl
     *
     * @return string
     */
    public function getReturnUrl()
    {
        return $this->container['returnUrl'];
    }

    /**
     * Sets returnUrl
     *
     * @param string $returnUrl The URL to return to in case of a redirection. The format depends on the channel.  * For web, include the protocol `http://` or `https://`. You can also include your own additional query parameters, for example, shopper ID or order reference number. Example: `https://your-company.example.com/checkout?shopperOrder=12xy` * For iOS, use the custom URL for your app. To know more about setting custom URL schemes, refer to the [Apple Developer documentation](https://developer.apple.com/documentation/uikit/inter-process_communication/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app). Example: `my-app://` * For Android, use a custom URL handled by an Activity on your app. You can configure it with an [intent filter](https://developer.android.com/guide/components/intents-filters). Example: `my-app://your.package.name`  If the URL to return to includes non-ASCII characters, like spaces or special letters, URL encode the value.  We strongly recommend that you use a maximum of 1024 characters.  > The URL must not include personally identifiable information (PII), for example name or email address.
     *
     * @return self
     */
    public function setReturnUrl($returnUrl)
    {
        $this->container['returnUrl'] = $returnUrl;

        return $this;
    }

    /**
     * Gets riskData
     *
     * @return \Adyen\Model\Checkout\RiskData|null
     */
    public function getRiskData()
    {
        return $this->container['riskData'];
    }

    /**
     * Sets riskData
     *
     * @param \Adyen\Model\Checkout\RiskData|null $riskData riskData
     *
     * @return self
     */
    public function setRiskData($riskData)
    {
        $this->container['riskData'] = $riskData;

        return $this;
    }

    /**
     * Gets sessionData
     *
     * @return string|null
     */
    public function getSessionData()
    {
        return $this->container['sessionData'];
    }

    /**
     * Sets sessionData
     *
     * @param string|null $sessionData The payment session data you need to pass to your front end.
     *
     * @return self
     */
    public function setSessionData($sessionData)
    {
        $this->container['sessionData'] = $sessionData;

        return $this;
    }

    /**
     * Gets shopperEmail
     *
     * @return string|null
     */
    public function getShopperEmail()
    {
        return $this->container['shopperEmail'];
    }

    /**
     * Sets shopperEmail
     *
     * @param string|null $shopperEmail The shopper's email address.
     *
     * @return self
     */
    public function setShopperEmail($shopperEmail)
    {
        $this->container['shopperEmail'] = $shopperEmail;

        return $this;
    }

    /**
     * Gets shopperIP
     *
     * @return string|null
     */
    public function getShopperIP()
    {
        return $this->container['shopperIP'];
    }

    /**
     * Sets shopperIP
     *
     * @param string|null $shopperIP The shopper's IP address. We recommend that you provide this data, as it is used in a number of risk checks (for instance, number of payment attempts or location-based checks). > Required for Visa and JCB transactions that require 3D Secure 2 authentication for all web and mobile integrations, if you did not include the `shopperEmail`. For native mobile integrations, the field is required to support cases where authentication is routed to the redirect flow. This field is also mandatory for some merchants depending on your business model. For more information, [contact Support](https://www.adyen.help/hc/en-us/requests/new).
     *
     * @return self
     */
    public function setShopperIP($shopperIP)
    {
        $this->container['shopperIP'] = $shopperIP;

        return $this;
    }

    /**
     * Gets shopperInteraction
     *
     * @return string|null
     */
    public function getShopperInteraction()
    {
        return $this->container['shopperInteraction'];
    }

    /**
     * Sets shopperInteraction
     *
     * @param string|null $shopperInteraction Specifies the sales channel, through which the shopper gives their card details, and whether the shopper is a returning customer. For the web service API, Adyen assumes Ecommerce shopper interaction by default.  This field has the following possible values: * `Ecommerce` - Online transactions where the cardholder is present (online). For better authorisation rates, we recommend sending the card security code (CSC) along with the request. * `ContAuth` - Card on file and/or subscription transactions, where the cardholder is known to the merchant (returning customer). If the shopper is present (online), you can supply also the CSC to improve authorisation (one-click payment). * `Moto` - Mail-order and telephone-order transactions where the shopper is in contact with the merchant via email or telephone. * `POS` - Point-of-sale transactions where the shopper is physically present to make a payment using a secure payment terminal.
     *
     * @return self
     */
    public function setShopperInteraction($shopperInteraction)
    {
        $allowedValues = $this->getShopperInteractionAllowableValues();
        if (!in_array($shopperInteraction, $allowedValues, true)) {
            error_log(
                sprintf(
                    "shopperInteraction: unexpected enum value '%s' - Supported values are [%s]",
                    $shopperInteraction,
                    implode(', ', $allowedValues)
                )
            );
        }
        $this->container['shopperInteraction'] = $shopperInteraction;

        return $this;
    }

    /**
     * Gets shopperLocale
     *
     * @return string|null
     */
    public function getShopperLocale()
    {
        return $this->container['shopperLocale'];
    }

    /**
     * Sets shopperLocale
     *
     * @param string|null $shopperLocale The language for the payment. The value combines the two-letter [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) language code with the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) country code. For example, **nl-NL**.  When using Drop-in/Components, the specified language appears if your front-end global configuration does not set the `locale`.
     *
     * @return self
     */
    public function setShopperLocale($shopperLocale)
    {
        $this->container['shopperLocale'] = $shopperLocale;

        return $this;
    }

    /**
     * Gets shopperName
     *
     * @return \Adyen\Model\Checkout\ShopperName|null
     */
    public function getShopperName()
    {
        return $this->container['shopperName'];
    }

    /**
     * Sets shopperName
     *
     * @param \Adyen\Model\Checkout\ShopperName|null $shopperName shopperName
     *
     * @return self
     */
    public function setShopperName($shopperName)
    {
        $this->container['shopperName'] = $shopperName;

        return $this;
    }

    /**
     * Gets shopperReference
     *
     * @return string|null
     */
    public function getShopperReference()
    {
        return $this->container['shopperReference'];
    }

    /**
     * Sets shopperReference
     *
     * @param string|null $shopperReference Your reference to uniquely identify this shopper, for example user ID or account ID. The value is case-sensitive and must be at least three characters. > Your reference must not include personally identifiable information (PII) such as name or email address.
     *
     * @return self
     */
    public function setShopperReference($shopperReference)
    {
        $this->container['shopperReference'] = $shopperReference;

        return $this;
    }

    /**
     * Gets shopperStatement
     *
     * @return string|null
     */
    public function getShopperStatement()
    {
        return $this->container['shopperStatement'];
    }

    /**
     * Sets shopperStatement
     *
     * @param string|null $shopperStatement The text to be shown on the shopper's bank statement.  We recommend sending a maximum of 22 characters, otherwise banks might truncate the string.  Allowed characters: **a-z**, **A-Z**, **0-9**, spaces, and special characters **. , ' _ - ? + * /_**.
     *
     * @return self
     */
    public function setShopperStatement($shopperStatement)
    {
        $this->container['shopperStatement'] = $shopperStatement;

        return $this;
    }

    /**
     * Gets showInstallmentAmount
     *
     * @return bool|null
     */
    public function getShowInstallmentAmount()
    {
        return $this->container['showInstallmentAmount'];
    }

    /**
     * Sets showInstallmentAmount
     *
     * @param bool|null $showInstallmentAmount Set to true to show the payment amount per installment.
     *
     * @return self
     */
    public function setShowInstallmentAmount($showInstallmentAmount)
    {
        $this->container['showInstallmentAmount'] = $showInstallmentAmount;

        return $this;
    }

    /**
     * Gets showRemovePaymentMethodButton
     *
     * @return bool|null
     */
    public function getShowRemovePaymentMethodButton()
    {
        return $this->container['showRemovePaymentMethodButton'];
    }

    /**
     * Sets showRemovePaymentMethodButton
     *
     * @param bool|null $showRemovePaymentMethodButton Set to **true** to show a button that lets the shopper remove a stored payment method.
     *
     * @return self
     */
    public function setShowRemovePaymentMethodButton($showRemovePaymentMethodButton)
    {
        $this->container['showRemovePaymentMethodButton'] = $showRemovePaymentMethodButton;

        return $this;
    }

    /**
     * Gets socialSecurityNumber
     *
     * @return string|null
     */
    public function getSocialSecurityNumber()
    {
        return $this->container['socialSecurityNumber'];
    }

    /**
     * Sets socialSecurityNumber
     *
     * @param string|null $socialSecurityNumber The shopper's social security number.
     *
     * @return self
     */
    public function setSocialSecurityNumber($socialSecurityNumber)
    {
        $this->container['socialSecurityNumber'] = $socialSecurityNumber;

        return $this;
    }

    /**
     * Gets splitCardFundingSources
     *
     * @return bool|null
     */
    public function getSplitCardFundingSources()
    {
        return $this->container['splitCardFundingSources'];
    }

    /**
     * Sets splitCardFundingSources
     *
     * @param bool|null $splitCardFundingSources Boolean value indicating whether the card payment method should be split into separate debit and credit options.
     *
     * @return self
     */
    public function setSplitCardFundingSources($splitCardFundingSources)
    {
        $this->container['splitCardFundingSources'] = $splitCardFundingSources;

        return $this;
    }

    /**
     * Gets splits
     *
     * @return \Adyen\Model\Checkout\Split[]|null
     */
    public function getSplits()
    {
        return $this->container['splits'];
    }

    /**
     * Sets splits
     *
     * @param \Adyen\Model\Checkout\Split[]|null $splits An array of objects specifying how to split a payment when using [Adyen for Platforms](https://docs.adyen.com/platforms/process-payments#providing-split-information), [Classic Platforms integration](https://docs.adyen.com/classic-platforms/processing-payments#providing-split-information), or [Issuing](https://docs.adyen.com/issuing/manage-funds#split).
     *
     * @return self
     */
    public function setSplits($splits)
    {
        $this->container['splits'] = $splits;

        return $this;
    }

    /**
     * Gets store
     *
     * @return string|null
     */
    public function getStore()
    {
        return $this->container['store'];
    }

    /**
     * Sets store
     *
     * @param string|null $store Required for Adyen for Platforms integrations if you are a platform model. This is your [reference](https://docs.adyen.com/api-explorer/Management/3/post/merchants/(merchantId)/stores#request-reference) (on [balance platform](https://docs.adyen.com/platforms)) or the [storeReference](https://docs.adyen.com/api-explorer/Account/latest/post/updateAccountHolder#request-accountHolderDetails-storeDetails-storeReference) (in the [classic integration](https://docs.adyen.com/classic-platforms/processing-payments/route-payment-to-store/#route-a-payment-to-a-store)) for the ecommerce or point-of-sale store that is processing the payment.
     *
     * @return self
     */
    public function setStore($store)
    {
        $this->container['store'] = $store;

        return $this;
    }

    /**
     * Gets storeFiltrationMode
     *
     * @return string|null
     */
    public function getStoreFiltrationMode()
    {
        return $this->container['storeFiltrationMode'];
    }

    /**
     * Sets storeFiltrationMode
     *
     * @param string|null $storeFiltrationMode Specifies how payment methods should be filtered based on the 'store' parameter:   - 'exclusive': Only payment methods belonging to the specified 'store' are returned.   - 'inclusive': Payment methods from the 'store' and those not associated with any other store are returned.
     *
     * @return self
     */
    public function setStoreFiltrationMode($storeFiltrationMode)
    {
        $allowedValues = $this->getStoreFiltrationModeAllowableValues();
        if (!in_array($storeFiltrationMode, $allowedValues, true)) {
            error_log(
                sprintf(
                    "storeFiltrationMode: unexpected enum value '%s' - Supported values are [%s]",
                    $storeFiltrationMode,
                    implode(', ', $allowedValues)
                )
            );
        }
        $this->container['storeFiltrationMode'] = $storeFiltrationMode;

        return $this;
    }

    /**
     * Gets storePaymentMethod
     *
     * @return bool|null
     */
    public function getStorePaymentMethod()
    {
        return $this->container['storePaymentMethod'];
    }

    /**
     * Sets storePaymentMethod
     *
     * @param bool|null $storePaymentMethod When true and `shopperReference` is provided, the payment details will be stored for future [recurring payments](https://docs.adyen.com/online-payments/tokenization/#recurring-payment-types).
     *
     * @return self
     */
    public function setStorePaymentMethod($storePaymentMethod)
    {
        $this->container['storePaymentMethod'] = $storePaymentMethod;

        return $this;
    }

    /**
     * Gets storePaymentMethodMode
     *
     * @return string|null
     */
    public function getStorePaymentMethodMode()
    {
        return $this->container['storePaymentMethodMode'];
    }

    /**
     * Sets storePaymentMethodMode
     *
     * @param string|null $storePaymentMethodMode Indicates if the details of the payment method will be stored for the shopper. Possible values: * **disabled** – No details will be stored (default). * **askForConsent** – If the `shopperReference` is provided, the Drop-in/Component shows a checkbox where the shopper can select to store their payment details for card payments. * **enabled** – If the `shopperReference` is provided, the details will be stored without asking the shopper for consent.
     *
     * @return self
     */
    public function setStorePaymentMethodMode($storePaymentMethodMode)
    {
        $allowedValues = $this->getStorePaymentMethodModeAllowableValues();
        if (!in_array($storePaymentMethodMode, $allowedValues, true)) {
            error_log(
                sprintf(
                    "storePaymentMethodMode: unexpected enum value '%s' - Supported values are [%s]",
                    $storePaymentMethodMode,
                    implode(', ', $allowedValues)
                )
            );
        }
        $this->container['storePaymentMethodMode'] = $storePaymentMethodMode;

        return $this;
    }

    /**
     * Gets telephoneNumber
     *
     * @return string|null
     */
    public function getTelephoneNumber()
    {
        return $this->container['telephoneNumber'];
    }

    /**
     * Sets telephoneNumber
     *
     * @param string|null $telephoneNumber The shopper's telephone number.  The phone number must include a plus sign (+) and a country code (1-3 digits), followed by the number (4-15 digits). If the value you provide does not follow the guidelines, we do not submit it for authentication. > Required for Visa and JCB transactions that require 3D Secure 2 authentication, if you did not include the `shopperEmail`.
     *
     * @return self
     */
    public function setTelephoneNumber($telephoneNumber)
    {
        $this->container['telephoneNumber'] = $telephoneNumber;

        return $this;
    }

    /**
     * Gets themeId
     *
     * @return string|null
     */
    public function getThemeId()
    {
        return $this->container['themeId'];
    }

    /**
     * Sets themeId
     *
     * @param string|null $themeId Sets a custom theme for [Hosted Checkout](https://docs.adyen.com/online-payments/build-your-integration/?platform=Web&integration=Hosted+Checkout). The value can be any of the **Theme ID** values from your Customer Area.
     *
     * @return self
     */
    public function setThemeId($themeId)
    {
        $this->container['themeId'] = $themeId;

        return $this;
    }

    /**
     * Gets threeDS2RequestData
     *
     * @return \Adyen\Model\Checkout\CheckoutSessionThreeDS2RequestData|null
     */
    public function getThreeDS2RequestData()
    {
        return $this->container['threeDS2RequestData'];
    }

    /**
     * Sets threeDS2RequestData
     *
     * @param \Adyen\Model\Checkout\CheckoutSessionThreeDS2RequestData|null $threeDS2RequestData threeDS2RequestData
     *
     * @return self
     */
    public function setThreeDS2RequestData($threeDS2RequestData)
    {
        $this->container['threeDS2RequestData'] = $threeDS2RequestData;

        return $this;
    }

    /**
     * Gets threeDSAuthenticationOnly
     *
     * @return bool|null
     * @deprecated since Adyen Checkout API v69. "Use `authenticationData.authenticationOnly` instead."
     */
    public function getThreeDSAuthenticationOnly()
    {
        return $this->container['threeDSAuthenticationOnly'];
    }

    /**
     * Sets threeDSAuthenticationOnly
     *
     * @param bool|null $threeDSAuthenticationOnly Required to trigger the [authentication-only flow](https://docs.adyen.com/online-payments/3d-secure/authentication-only/). If set to **true**, you will only perform the 3D Secure 2 authentication, and will not proceed to the payment authorization.Default: **false**.
     *
     * @return self
     * @deprecated since Adyen Checkout API v69. "Use `authenticationData.authenticationOnly` instead."
     */
    public function setThreeDSAuthenticationOnly($threeDSAuthenticationOnly)
    {
        $this->container['threeDSAuthenticationOnly'] = $threeDSAuthenticationOnly;

        return $this;
    }

    /**
     * Gets trustedShopper
     *
     * @return bool|null
     */
    public function getTrustedShopper()
    {
        return $this->container['trustedShopper'];
    }

    /**
     * Sets trustedShopper
     *
     * @param bool|null $trustedShopper Set to true if the payment should be routed to a trusted MID.
     *
     * @return self
     */
    public function setTrustedShopper($trustedShopper)
    {
        $this->container['trustedShopper'] = $trustedShopper;

        return $this;
    }

    /**
     * Gets url
     *
     * @return string|null
     */
    public function getUrl()
    {
        return $this->container['url'];
    }

    /**
     * Sets url
     *
     * @param string|null $url The URL for the Hosted Checkout page. Redirect the shopper to this URL so they can make the payment.
     *
     * @return self
     */
    public function setUrl($url)
    {
        $this->container['url'] = $url;

        return $this;
    }
    /**
     * Returns true if offset exists. False otherwise.
     *
     * @param integer $offset Offset
     *
     * @return boolean
     */
    public function offsetExists($offset): bool
    {
        return isset($this->container[$offset]);
    }

    /**
     * Gets offset.
     *
     * @param integer $offset Offset
     *
     * @return mixed|null
     */
    #[\ReturnTypeWillChange]
    public function offsetGet($offset)
    {
        return $this->container[$offset] ?? null;
    }

    /**
     * Sets value based on offset.
     *
     * @param int|null $offset Offset
     * @param mixed    $value  Value to be set
     *
     * @return void
     */
    public function offsetSet($offset, $value): void
    {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    /**
     * Unsets offset.
     *
     * @param integer $offset Offset
     *
     * @return void
     */
    public function offsetUnset($offset): void
    {
        unset($this->container[$offset]);
    }

    /**
     * Serializes the object to a value that can be serialized natively by json_encode().
     * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php
     *
     * @return mixed Returns data which can be serialized by json_encode(), which is a value
     * of any type other than a resource.
     */
    #[\ReturnTypeWillChange]
    public function jsonSerialize()
    {
        return ObjectSerializer::sanitizeForSerialization($this);
    }

    public function toArray(): array
    {
        $array = [];
        foreach (self::$openAPITypes as $propertyName => $propertyType) {
            $propertyValue = $this[$propertyName];
            if ($propertyValue !== null) {
                // Check if the property value is an object and has a toArray() method
                if (is_object($propertyValue) && method_exists($propertyValue, 'toArray')) {
                    $array[$propertyName] = $propertyValue->toArray();
                // Check if it's type datetime
                } elseif ($propertyValue instanceof \DateTime) {
                    $array[$propertyName] = $propertyValue->format(DATE_ATOM);
                // If it's an array type we should check whether it contains objects and if so call toArray method
                } elseif (is_array($propertyValue)) {
                    $array[$propertyName] = array_map(function ($item) {
                        return $item instanceof ModelInterface ? $item->toArray() : $item;
                    }, $propertyValue);
                } else {
                    // Otherwise, directly assign the property value to the array
                    $array[$propertyName] = $propertyValue;
                }
            }
        }
        return $array;
    }

    /**
     * Gets the string presentation of the object
     *
     * @return string
     */
    public function __toString()
    {
        return json_encode(
            ObjectSerializer::sanitizeForSerialization($this),
            JSON_PRETTY_PRINT
        );
    }
}
