<?php
/**
 * MetafieldsApi
 * PHP version 8.1
 *
 * @category Class
 * @package  Bigcommerce\OrdersV3
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */

/**
 * Orders V3
 *
 * Surfaces endpoints related to payment processing. The `/orders/{id}/transactions` endpoint returns transaction details for the specified order. To programmatically create, update, and delete orders themselves, see [Orders v2](https://developer.bigcommerce.com/api-reference/store-management/orders). To process payments, see [Payment Processing](https://developer.bigcommerce.com/api-reference/payments/payments-process-payments).  - [Authentication](#authentication) - [Order Transactions](#order-transactions) - [Order refunds](#order-refunds) - [Resources](#resources)  ## Authentication  Authenticate requests by including an [OAuth](https://developer.bigcommerce.com/api-docs/getting-started/authentication) `access_token` in the request header.  ```http GET https://api.bigcommerce.com/stores/{{STORE_HASH}}/v3/{{ENDPOINT}} Content-Type: application/json X-Auth-Token: {{ACCESS_TOKEN}} ```  ### OAuth Scopes  | UI Name| Permission |Parameter| |----------------------------------------------|------------|----------| | Order Transactions|modify|`store_v2_transactions`| | Order Transactions|read-only  |`store_v2_transactions_read_only`| | Orders| modify|`store_v2_orders`| | Orders| read-only|`store_v2_orders_read_only`|  ## Order Transactions The `/orders/{id}/transactions` endpoint returns details about the payment instruments used to pay for an order. Depending on the payment method used, different details will be available. Not all credit card payment gateways return full card or fraud details. Transactions endpoints are primarily used to get detailed gateway response information for credit card transactions; however they will also return any available information about digital wallet and offline payments.  **Note**: transactions are not created for the following payment methods: * Test Payment Gateway * PayPal Express * Amazon Pay  ## Order Refunds The Order API refund endpoints allow developers to process refunds against orders with settled payments. Refund endpoints are useful when building order management or payment integrations. They make embedding refund functionality directly into the application possible without requiring merchants to return to their BigCommerce Control Panel.  ## Resources * [Orders Overview](https://developer.bigcommerce.com/api-docs/orders/orders-overview) * [Orders V2](https://developer.bigcommerce.com/api-reference/store-management/orders)
 *
 * The version of the OpenAPI document: 
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.13.0
 */

/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

namespace Bigcommerce\OrdersV3\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Bigcommerce\OrdersV3\ApiException;
use Bigcommerce\OrdersV3\Configuration;
use Bigcommerce\OrdersV3\FormDataProcessor;
use Bigcommerce\OrdersV3\HeaderSelector;
use Bigcommerce\OrdersV3\ObjectSerializer;

/**
 * MetafieldsApi Class Doc Comment
 *
 * @category Class
 * @package  Bigcommerce\OrdersV3
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */
class MetafieldsApi
{
    /**
     * @var ClientInterface
     */
    protected $client;

    /**
     * @var Configuration
     */
    protected $config;

    /**
     * @var HeaderSelector
     */
    protected $headerSelector;

    /**
     * @var int Host index
     */
    protected $hostIndex;

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'createOrderMetafield' => [
            'application/json',
        ],
        'deleteOrderMetafieldById' => [
            'application/json',
        ],
        'getOrderMetafieldByOrderIdAndMetafieldId' => [
            'application/json',
        ],
        'getOrderMetafieldsByOrderId' => [
            'application/json',
        ],
        'updateOrderMetafield' => [
            'application/json',
        ],
    ];

    /**
     * @param ClientInterface $client
     * @param Configuration   $config
     * @param HeaderSelector  $selector
     * @param int             $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec
     */
    public function __construct(
        ?ClientInterface $client = null,
        ?Configuration $config = null,
        ?HeaderSelector $selector = null,
        int $hostIndex = 0
    ) {
        $this->client = $client ?: new Client();
        $this->config = $config ?: Configuration::getDefaultConfiguration();
        $this->headerSelector = $selector ?: new HeaderSelector();
        $this->hostIndex = $hostIndex;
    }

    /**
     * Set the host index
     *
     * @param int $hostIndex Host index (required)
     */
    public function setHostIndex($hostIndex): void
    {
        $this->hostIndex = $hostIndex;
    }

    /**
     * Get the host index
     *
     * @return int Host index
     */
    public function getHostIndex()
    {
        return $this->hostIndex;
    }

    /**
     * @return Configuration
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * Operation createOrderMetafield
     *
     * Create Metafields
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPost $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderMetafield'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Bigcommerce\OrdersV3\Model\MetafieldResponse|\Bigcommerce\OrdersV3\Model\ErrorResponse|\Bigcommerce\OrdersV3\Model\ErrorResponse
     */
    public function createOrderMetafield($order_id, $metafield, string $contentType = self::contentTypes['createOrderMetafield'][0])
    {
        list($response) = $this->createOrderMetafieldWithHttpInfo($order_id, $metafield, $contentType);
        return $response;
    }

    /**
     * Operation createOrderMetafieldWithHttpInfo
     *
     * Create Metafields
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPost $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderMetafield'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Bigcommerce\OrdersV3\Model\MetafieldResponse|\Bigcommerce\OrdersV3\Model\ErrorResponse|\Bigcommerce\OrdersV3\Model\ErrorResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function createOrderMetafieldWithHttpInfo($order_id, $metafield, string $contentType = self::contentTypes['createOrderMetafield'][0])
    {
        $request = $this->createOrderMetafieldRequest($order_id, $metafield, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV3\Model\MetafieldResponse',
                        $request,
                        $response,
                    );
                case 409:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV3\Model\ErrorResponse',
                        $request,
                        $response,
                    );
                case 422:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV3\Model\ErrorResponse',
                        $request,
                        $response,
                    );
            }

            

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Bigcommerce\OrdersV3\Model\MetafieldResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV3\Model\MetafieldResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 409:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV3\Model\ErrorResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 422:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV3\Model\ErrorResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation createOrderMetafieldAsync
     *
     * Create Metafields
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPost $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderMetafield'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createOrderMetafieldAsync($order_id, $metafield, string $contentType = self::contentTypes['createOrderMetafield'][0])
    {
        return $this->createOrderMetafieldAsyncWithHttpInfo($order_id, $metafield, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation createOrderMetafieldAsyncWithHttpInfo
     *
     * Create Metafields
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPost $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderMetafield'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createOrderMetafieldAsyncWithHttpInfo($order_id, $metafield, string $contentType = self::contentTypes['createOrderMetafield'][0])
    {
        $returnType = '\Bigcommerce\OrdersV3\Model\MetafieldResponse';
        $request = $this->createOrderMetafieldRequest($order_id, $metafield, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createOrderMetafield'
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPost $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderMetafield'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function createOrderMetafieldRequest($order_id, $metafield, string $contentType = self::contentTypes['createOrderMetafield'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling createOrderMetafield'
            );
        }

        // verify the required parameter 'metafield' is set
        if ($metafield === null || (is_array($metafield) && count($metafield) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $metafield when calling createOrderMetafield'
            );
        }


        $resourcePath = '/orders/{order_id}/metafields';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (isset($metafield)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($metafield));
            } else {
                $httpBody = $metafield;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'POST',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteOrderMetafieldById
     *
     * Delete a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderMetafieldById'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return void
     */
    public function deleteOrderMetafieldById($order_id, $metafield_id, string $contentType = self::contentTypes['deleteOrderMetafieldById'][0])
    {
        $this->deleteOrderMetafieldByIdWithHttpInfo($order_id, $metafield_id, $contentType);
    }

    /**
     * Operation deleteOrderMetafieldByIdWithHttpInfo
     *
     * Delete a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderMetafieldById'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteOrderMetafieldByIdWithHttpInfo($order_id, $metafield_id, string $contentType = self::contentTypes['deleteOrderMetafieldById'][0])
    {
        $request = $this->deleteOrderMetafieldByIdRequest($order_id, $metafield_id, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            return [null, $statusCode, $response->getHeaders()];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
            }
        

            throw $e;
        }
    }

    /**
     * Operation deleteOrderMetafieldByIdAsync
     *
     * Delete a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderMetafieldById'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteOrderMetafieldByIdAsync($order_id, $metafield_id, string $contentType = self::contentTypes['deleteOrderMetafieldById'][0])
    {
        return $this->deleteOrderMetafieldByIdAsyncWithHttpInfo($order_id, $metafield_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation deleteOrderMetafieldByIdAsyncWithHttpInfo
     *
     * Delete a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderMetafieldById'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteOrderMetafieldByIdAsyncWithHttpInfo($order_id, $metafield_id, string $contentType = self::contentTypes['deleteOrderMetafieldById'][0])
    {
        $returnType = '';
        $request = $this->deleteOrderMetafieldByIdRequest($order_id, $metafield_id, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    return [null, $response->getStatusCode(), $response->getHeaders()];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteOrderMetafieldById'
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderMetafieldById'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function deleteOrderMetafieldByIdRequest($order_id, $metafield_id, string $contentType = self::contentTypes['deleteOrderMetafieldById'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling deleteOrderMetafieldById'
            );
        }

        // verify the required parameter 'metafield_id' is set
        if ($metafield_id === null || (is_array($metafield_id) && count($metafield_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $metafield_id when calling deleteOrderMetafieldById'
            );
        }


        $resourcePath = '/orders/{order_id}/metafields/{metafield_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }
        // path params
        if ($metafield_id !== null) {
            $resourcePath = str_replace(
                '{' . 'metafield_id' . '}',
                ObjectSerializer::toPathValue($metafield_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            [],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'DELETE',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOrderMetafieldByOrderIdAndMetafieldId
     *
     * Get a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Bigcommerce\OrdersV3\Model\MetafieldResponse|\Bigcommerce\OrdersV3\Model\NotFound
     */
    public function getOrderMetafieldByOrderIdAndMetafieldId($order_id, $metafield_id, string $contentType = self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'][0])
    {
        list($response) = $this->getOrderMetafieldByOrderIdAndMetafieldIdWithHttpInfo($order_id, $metafield_id, $contentType);
        return $response;
    }

    /**
     * Operation getOrderMetafieldByOrderIdAndMetafieldIdWithHttpInfo
     *
     * Get a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Bigcommerce\OrdersV3\Model\MetafieldResponse|\Bigcommerce\OrdersV3\Model\NotFound, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOrderMetafieldByOrderIdAndMetafieldIdWithHttpInfo($order_id, $metafield_id, string $contentType = self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'][0])
    {
        $request = $this->getOrderMetafieldByOrderIdAndMetafieldIdRequest($order_id, $metafield_id, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV3\Model\MetafieldResponse',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV3\Model\NotFound',
                        $request,
                        $response,
                    );
            }

            

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Bigcommerce\OrdersV3\Model\MetafieldResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV3\Model\MetafieldResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV3\Model\NotFound',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getOrderMetafieldByOrderIdAndMetafieldIdAsync
     *
     * Get a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOrderMetafieldByOrderIdAndMetafieldIdAsync($order_id, $metafield_id, string $contentType = self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'][0])
    {
        return $this->getOrderMetafieldByOrderIdAndMetafieldIdAsyncWithHttpInfo($order_id, $metafield_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getOrderMetafieldByOrderIdAndMetafieldIdAsyncWithHttpInfo
     *
     * Get a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOrderMetafieldByOrderIdAndMetafieldIdAsyncWithHttpInfo($order_id, $metafield_id, string $contentType = self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'][0])
    {
        $returnType = '\Bigcommerce\OrdersV3\Model\MetafieldResponse';
        $request = $this->getOrderMetafieldByOrderIdAndMetafieldIdRequest($order_id, $metafield_id, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOrderMetafieldByOrderIdAndMetafieldId'
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getOrderMetafieldByOrderIdAndMetafieldIdRequest($order_id, $metafield_id, string $contentType = self::contentTypes['getOrderMetafieldByOrderIdAndMetafieldId'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling getOrderMetafieldByOrderIdAndMetafieldId'
            );
        }

        // verify the required parameter 'metafield_id' is set
        if ($metafield_id === null || (is_array($metafield_id) && count($metafield_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $metafield_id when calling getOrderMetafieldByOrderIdAndMetafieldId'
            );
        }


        $resourcePath = '/orders/{order_id}/metafields/{metafield_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }
        // path params
        if ($metafield_id !== null) {
            $resourcePath = str_replace(
                '{' . 'metafield_id' . '}',
                ObjectSerializer::toPathValue($metafield_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOrderMetafieldsByOrderId
     *
     * Get Metafields
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int|null $page Specifies the page number in a limited (paginated) list of products. (optional)
     * @param  int|null $limit Controls the number of items per page in a limited (paginated) list of products. (optional)
     * @param  string|null $key Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $namespace Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $direction Sort direction. Acceptable values are: &#x60;asc&#x60;, &#x60;desc&#x60;. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldsByOrderId'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Bigcommerce\OrdersV3\Model\MetaFieldCollectionResponse|\Bigcommerce\OrdersV3\Model\NotFound
     */
    public function getOrderMetafieldsByOrderId($order_id, $page = null, $limit = null, $key = null, $namespace = null, $direction = null, string $contentType = self::contentTypes['getOrderMetafieldsByOrderId'][0])
    {
        list($response) = $this->getOrderMetafieldsByOrderIdWithHttpInfo($order_id, $page, $limit, $key, $namespace, $direction, $contentType);
        return $response;
    }

    /**
     * Operation getOrderMetafieldsByOrderIdWithHttpInfo
     *
     * Get Metafields
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int|null $page Specifies the page number in a limited (paginated) list of products. (optional)
     * @param  int|null $limit Controls the number of items per page in a limited (paginated) list of products. (optional)
     * @param  string|null $key Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $namespace Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $direction Sort direction. Acceptable values are: &#x60;asc&#x60;, &#x60;desc&#x60;. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldsByOrderId'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Bigcommerce\OrdersV3\Model\MetaFieldCollectionResponse|\Bigcommerce\OrdersV3\Model\NotFound, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOrderMetafieldsByOrderIdWithHttpInfo($order_id, $page = null, $limit = null, $key = null, $namespace = null, $direction = null, string $contentType = self::contentTypes['getOrderMetafieldsByOrderId'][0])
    {
        $request = $this->getOrderMetafieldsByOrderIdRequest($order_id, $page, $limit, $key, $namespace, $direction, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV3\Model\MetaFieldCollectionResponse',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV3\Model\NotFound',
                        $request,
                        $response,
                    );
            }

            

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Bigcommerce\OrdersV3\Model\MetaFieldCollectionResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV3\Model\MetaFieldCollectionResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV3\Model\NotFound',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getOrderMetafieldsByOrderIdAsync
     *
     * Get Metafields
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int|null $page Specifies the page number in a limited (paginated) list of products. (optional)
     * @param  int|null $limit Controls the number of items per page in a limited (paginated) list of products. (optional)
     * @param  string|null $key Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $namespace Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $direction Sort direction. Acceptable values are: &#x60;asc&#x60;, &#x60;desc&#x60;. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldsByOrderId'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOrderMetafieldsByOrderIdAsync($order_id, $page = null, $limit = null, $key = null, $namespace = null, $direction = null, string $contentType = self::contentTypes['getOrderMetafieldsByOrderId'][0])
    {
        return $this->getOrderMetafieldsByOrderIdAsyncWithHttpInfo($order_id, $page, $limit, $key, $namespace, $direction, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getOrderMetafieldsByOrderIdAsyncWithHttpInfo
     *
     * Get Metafields
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int|null $page Specifies the page number in a limited (paginated) list of products. (optional)
     * @param  int|null $limit Controls the number of items per page in a limited (paginated) list of products. (optional)
     * @param  string|null $key Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $namespace Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $direction Sort direction. Acceptable values are: &#x60;asc&#x60;, &#x60;desc&#x60;. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldsByOrderId'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOrderMetafieldsByOrderIdAsyncWithHttpInfo($order_id, $page = null, $limit = null, $key = null, $namespace = null, $direction = null, string $contentType = self::contentTypes['getOrderMetafieldsByOrderId'][0])
    {
        $returnType = '\Bigcommerce\OrdersV3\Model\MetaFieldCollectionResponse';
        $request = $this->getOrderMetafieldsByOrderIdRequest($order_id, $page, $limit, $key, $namespace, $direction, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOrderMetafieldsByOrderId'
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int|null $page Specifies the page number in a limited (paginated) list of products. (optional)
     * @param  int|null $limit Controls the number of items per page in a limited (paginated) list of products. (optional)
     * @param  string|null $key Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $namespace Filter based on a metafield&#39;s key. (optional)
     * @param  string|null $direction Sort direction. Acceptable values are: &#x60;asc&#x60;, &#x60;desc&#x60;. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderMetafieldsByOrderId'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getOrderMetafieldsByOrderIdRequest($order_id, $page = null, $limit = null, $key = null, $namespace = null, $direction = null, string $contentType = self::contentTypes['getOrderMetafieldsByOrderId'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling getOrderMetafieldsByOrderId'
            );
        }







        $resourcePath = '/orders/{order_id}/metafields';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $page,
            'page', // param base name
            'integer', // openApiType
            '', // style
            false, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $limit,
            'limit', // param base name
            'integer', // openApiType
            '', // style
            false, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $key,
            'key', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $namespace,
            'namespace', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $direction,
            'direction', // param base name
            'string', // openApiType
            '', // style
            false, // explode
            false // required
        ) ?? []);


        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrderMetafield
     *
     * Update a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPut $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderMetafield'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Bigcommerce\OrdersV3\Model\MetafieldResponse|\Bigcommerce\OrdersV3\Model\NotFound
     */
    public function updateOrderMetafield($order_id, $metafield_id, $metafield, string $contentType = self::contentTypes['updateOrderMetafield'][0])
    {
        list($response) = $this->updateOrderMetafieldWithHttpInfo($order_id, $metafield_id, $metafield, $contentType);
        return $response;
    }

    /**
     * Operation updateOrderMetafieldWithHttpInfo
     *
     * Update a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPut $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderMetafield'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV3\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Bigcommerce\OrdersV3\Model\MetafieldResponse|\Bigcommerce\OrdersV3\Model\NotFound, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrderMetafieldWithHttpInfo($order_id, $metafield_id, $metafield, string $contentType = self::contentTypes['updateOrderMetafield'][0])
    {
        $request = $this->updateOrderMetafieldRequest($order_id, $metafield_id, $metafield, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV3\Model\MetafieldResponse',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV3\Model\NotFound',
                        $request,
                        $response,
                    );
            }

            

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Bigcommerce\OrdersV3\Model\MetafieldResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV3\Model\MetafieldResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV3\Model\NotFound',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation updateOrderMetafieldAsync
     *
     * Update a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPut $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderMetafield'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrderMetafieldAsync($order_id, $metafield_id, $metafield, string $contentType = self::contentTypes['updateOrderMetafield'][0])
    {
        return $this->updateOrderMetafieldAsyncWithHttpInfo($order_id, $metafield_id, $metafield, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation updateOrderMetafieldAsyncWithHttpInfo
     *
     * Update a Metafield
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPut $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderMetafield'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrderMetafieldAsyncWithHttpInfo($order_id, $metafield_id, $metafield, string $contentType = self::contentTypes['updateOrderMetafield'][0])
    {
        $returnType = '\Bigcommerce\OrdersV3\Model\MetafieldResponse';
        $request = $this->updateOrderMetafieldRequest($order_id, $metafield_id, $metafield, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrderMetafield'
     *
     * @param  int $order_id The ID of the &#x60;Order&#x60; to which the transactions belong. (required)
     * @param  int $metafield_id The ID of the &#x60;Metafield&#x60;. (required)
     * @param  \Bigcommerce\OrdersV3\Model\MetafieldPut $metafield A &#x60;Metafield&#x60; object. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderMetafield'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function updateOrderMetafieldRequest($order_id, $metafield_id, $metafield, string $contentType = self::contentTypes['updateOrderMetafield'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling updateOrderMetafield'
            );
        }

        // verify the required parameter 'metafield_id' is set
        if ($metafield_id === null || (is_array($metafield_id) && count($metafield_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $metafield_id when calling updateOrderMetafield'
            );
        }

        // verify the required parameter 'metafield' is set
        if ($metafield === null || (is_array($metafield) && count($metafield) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $metafield when calling updateOrderMetafield'
            );
        }


        $resourcePath = '/orders/{order_id}/metafields/{metafield_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }
        // path params
        if ($metafield_id !== null) {
            $resourcePath = str_replace(
                '{' . 'metafield_id' . '}',
                ObjectSerializer::toPathValue($metafield_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (isset($metafield)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($metafield));
            } else {
                $httpBody = $metafield;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'PUT',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option
     *
     * @throws \RuntimeException on file opening failure
     * @return array of http client options
     */
    protected function createHttpClientOption()
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile());
            }
        }

        return $options;
    }

    private function handleResponseWithDataType(
        string $dataType,
        RequestInterface $request,
        ResponseInterface $response
    ): array {
        if ($dataType === '\SplFileObject') {
            $content = $response->getBody(); //stream goes to serializer
        } else {
            $content = (string) $response->getBody();
            if ($dataType !== 'string') {
                try {
                    $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR);
                } catch (\JsonException $exception) {
                    throw new ApiException(
                        sprintf(
                            'Error JSON decoding server response (%s)',
                            $request->getUri()
                        ),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                        $content
                    );
                }
            }
        }

        return [
            ObjectSerializer::deserialize($content, $dataType, []),
            $response->getStatusCode(),
            $response->getHeaders()
        ];
    }

    private function responseWithinRangeCode(
        string $rangeCode,
        int $statusCode
    ): bool {
        $left = (int) ($rangeCode[0].'00');
        $right = (int) ($rangeCode[0].'99');

        return $statusCode >= $left && $statusCode <= $right;
    }
}
