(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['ApiClient', 'models/CreateCustomerRequest', 'models/CustomerResponse', 'models/CustomersResponse', 'models/ErrorResponseVo', 'models/UpdateCustomerRequest'], factory);
  } else if (typeof module === 'object' && module.exports) {
    // CommonJS-like environments that support module.exports, like Node.
    module.exports = factory(require('../ApiClient'), require('../models/CreateCustomerRequest'), require('../models/CustomerResponse'), require('../models/CustomersResponse'), require('../models/ErrorResponseVo'), require('../models/UpdateCustomerRequest'));
  } else {
    // Browser globals (root is window)
    if (!root.OrbipayPaymentsapiClient) {
      root.OrbipayPaymentsapiClient = {};
    }
    root.OrbipayPaymentsapiClient.CustomerApi = factory(root.OrbipayPaymentsapiClient.ApiClient, root.OrbipayPaymentsapiClient.CreateCustomerRequest, root.OrbipayPaymentsapiClient.CustomerResponse, root.OrbipayPaymentsapiClient.CustomersResponse, root.OrbipayPaymentsapiClient.ErrorResponseVo, root.OrbipayPaymentsapiClient.UpdateCustomerRequest);
  }
}(this, function(ApiClient, CreateCustomerRequest, CustomerResponse, CustomersResponse, ErrorResponseVo, UpdateCustomerRequest) {
  'use strict';

  /**
   * Customer service.
   * @module api/CustomerApi
   */

  /**
   * <h3 style="color:red"> This class subject to change without prior notice, Please dont use this class directly. </h3>

   * Constructs a new CustomerApi. 
   * @alias module:api/CustomerApi
   * @class
   * @param {module:ApiClient} [apiClient] Optional API client implementation to use,
   * default to {@link module:ApiClient#instance} if unspecified.
   */
  var exports = function(apiClient) {
    this.apiClient = apiClient || ApiClient.instance;


    /**
     * Callback function to receive the result of the createCustomer operation.
     * @callback module:api/CustomerApi~createCustomerCallback
     * @param {String} error Error message, if any.
     * @param {module:models/CustomerResponse} data The data returned by the service call.
     * @param {String} response The complete HTTP response.
     */

    /**
     * Create Customer
     * The Create Customer API is used to register a customer with a biller in EBPP. It is also mandatory to create a customer account for the customer. So, at least one customer account should be provided in order to register a customer. There is no limit on the number of accounts that can be associated with the customer. Either first_name or last_name is required to create a customer.
     * @param {String} channel The channel through which the API is invoked.
     * @param {String} client_key The unique identifier assigned by EBPP to the client.
     * @param {module:models/String} product The product identifier corresponding to the API.
     * @param {String} timestamp The timestamp for the moment when the API request is created.
     * @param {String} idempotent_request_key The unique token that clients can generate and maintain in order to identify an API request.
     * @param {module:models/String} requestor_type Type of the requestor of the API.
     * @param {module:models/CreateCustomerRequest} create_customer_request The JSON that contains all the attributes of customer to be created.
     * @param {Object} opts Optional parameters
     * @param {String} opts.requestor The identifier for the requestor of the API. If the requestor_type is &lt;b&gt;system&lt;/b&gt;, requestor is optional.
     * @param {String} opts.x_opay_headers Intended for the future use.
     * @param {String} opts.trace_id The unique reference that can be used for tracing and debugging an API call.
     * @param {module:api/CustomerApi~createCustomerCallback} callback The callback function, accepting three arguments: error, data, response
     * data is of type: {@link module:models/CustomerResponse}
     */
    this.createCustomer = function(channel, client_key, product, timestamp, idempotent_request_key, requestor_type, create_customer_request, opts, callback) {
      opts = opts || {};
      var postBody = create_customer_request;

      var pathParams = {
      };
      var queryParams = {
      };
      var headerParams = {
        'channel': channel,
        'client_key': client_key,
        'product': product,
        'timestamp': timestamp,
        'idempotent_request_key': idempotent_request_key,
        'requestor_type': requestor_type,
        'requestor': opts['requestor'],
        'X-OPAY-Headers': opts['x_opay_headers'],
        'trace_id': opts['trace_id']
      };
      var formParams = {
      };

      var authNames = [];
      var contentTypes = ['application/json'];
      var accepts = ['application/json'];
      var returnType = CustomerResponse;

      return this.apiClient.callApi(
        '/customers', 'POST',
        pathParams, queryParams, headerParams, formParams, postBody,
        authNames, contentTypes, accepts, returnType, callback
      );
    };

    /**
     * Callback function to receive the result of the getCustomer operation.
     * @callback module:api/CustomerApi~getCustomerCallback
     * @param {String} error Error message, if any.
     * @param {module:models/CustomerResponse} data The data returned by the service call.
     * @param {String} response The complete HTTP response.
     */

    /**
     * Get Customer
     * The Get Customer API is used to retrieve the details of the customer based on the id.
     * @param {String} channel The channel through which the API is invoked.
     * @param {String} client_key The unique identifier assigned by EBPP to the client.
     * @param {module:models/String} product The product identifier corresponding to the API.
     * @param {String} timestamp The timestamp for the moment when the API request is created.
     * @param {String} idempotent_request_key The unique token that clients can generate and maintain in order to identify an API request.
     * @param {module:models/String} requestor_type Type of the requestor of the API.
     * @param {String} id_customer The unique identifier assigned by EBPP to the customer.
     * @param {Object} opts Optional parameters
     * @param {String} opts.requestor The identifier for the requestor of the API. If the requestor_type is &lt;b&gt;system&lt;/b&gt;, requestor is optional.
     * @param {String} opts.x_opay_headers Intended for the future use.
     * @param {String} opts.trace_id The unique reference that can be used for tracing and debugging an API call.
     * @param {module:api/CustomerApi~getCustomerCallback} callback The callback function, accepting three arguments: error, data, response
     * data is of type: {@link module:models/CustomerResponse}
     */
    this.getCustomer = function(channel, client_key, product, timestamp, idempotent_request_key, requestor_type, id_customer, opts, callback) {
      opts = opts || {};
      var postBody = null;

      var pathParams = {
        'ID_CUSTOMER': id_customer
      };
      var queryParams = {
      };
      var headerParams = {
        'channel': channel,
        'client_key': client_key,
        'product': product,
        'timestamp': timestamp,
        'idempotent_request_key': idempotent_request_key,
        'requestor_type': requestor_type,
        'requestor': opts['requestor'],
        'X-OPAY-Headers': opts['x_opay_headers'],
        'trace_id': opts['trace_id']
      };
      var formParams = {
      };

      var authNames = [];
      var contentTypes = [];
      var accepts = ['application/json'];
      var returnType = CustomerResponse;

      return this.apiClient.callApi(
        '/customers/{ID_CUSTOMER}', 'GET',
        pathParams, queryParams, headerParams, formParams, postBody,
        authNames, contentTypes, accepts, returnType, callback
      );
    };

    /**
     * Callback function to receive the result of the retrieveCustomers operation.
     * @callback module:api/CustomerApi~retrieveCustomersCallback
     * @param {String} error Error message, if any.
     * @param {module:models/CustomersResponse} data The data returned by the service call.
     * @param {String} response The complete HTTP response.
     */

    /**
     * Retrieve Customers
     * This API is used to retrieve/lookup customers from EBPP. Customers can be retrieved matching criteria that includes the customer_reference, the ssn, the email or the customer account number. A unique customer can be retrieved by using search criteria as per the customer uniqueness parameters opted by the client/biller. If the requestor_type is customer, the Retrieve Customers API will return an error if it cannot retrieve a unique customer.
     * @param {String} channel The channel through which the API is invoked.
     * @param {String} client_key The unique identifier assigned by EBPP to the client.
     * @param {module:models/String} product The product identifier corresponding to the API.
     * @param {String} timestamp The timestamp for the moment when the API request is created.
     * @param {String} idempotent_request_key The unique token that clients can generate and maintain in order to identify an API request.
     * @param {module:models/String} requestor_type Type of the requestor of the API.
     * @param {Object} opts Optional parameters
     * @param {String} opts.requestor The identifier for the requestor of the API. If the requestor_type is &lt;b&gt;system&lt;/b&gt;, requestor is optional.
     * @param {String} opts.x_opay_headers Intended for the future use.
     * @param {String} opts.trace_id The unique reference that can be used for tracing and debugging an API call.
     * @param {String} opts.page_size The maximum number of objects returned in the query.
     * @param {String} opts.customer_reference Unique ID assigned by the biller/client system for a given customer.
     * @param {String} opts.ssn The SSN of the customer if the account holder is an individual or the tax ID, if the customer is a business.
     * @param {String} opts.email This field contains the customer’s email address within EBPP.
     * @param {String} opts.account_number Customer Account Number of the customer to get details of.
     * @param {module:api/CustomerApi~retrieveCustomersCallback} callback The callback function, accepting three arguments: error, data, response
     * data is of type: {@link module:models/CustomersResponse}
     */
    this.retrieveCustomers = function(channel, client_key, product, timestamp, idempotent_request_key, requestor_type, opts, callback) {
      opts = opts || {};
      var postBody = null;

      var pathParams = {
      };
      var queryParams = {
        'page_size': opts['page_size']
      };
      var headerParams = {
        'channel': channel,
        'client_key': client_key,
        'product': product,
        'timestamp': timestamp,
        'idempotent_request_key': idempotent_request_key,
        'requestor_type': requestor_type,
        'requestor': opts['requestor'],
        'X-OPAY-Headers': opts['x_opay_headers'],
        'trace_id': opts['trace_id']
      };
      var formParams = {
        'customer_reference': opts['customer_reference'],
        'ssn': opts['ssn'],
        'email': opts['email'],
        'account_number': opts['account_number']
      };

      var authNames = [];
      var contentTypes = ['application/x-www-form-urlencoded'];
      var accepts = ['application/json'];
      var returnType = CustomersResponse;

      return this.apiClient.callApi(
        '/customers/lists', 'POST',
        pathParams, queryParams, headerParams, formParams, postBody,
        authNames, contentTypes, accepts, returnType, callback
      );
    };

    /**
     * Callback function to receive the result of the retrieveCustomersPage operation.
     * @callback module:api/CustomerApi~retrieveCustomersPageCallback
     * @param {String} error Error message, if any.
     * @param {module:models/CustomersResponse} data The data returned by the service call.
     * @param {String} response The complete HTTP response.
     */

    /**
     * Retrieve Customers Pagination
     * This API is used to paginate through the list of customers returned in the Retrieve Customers API. 
     * @param {String} channel The channel through which the API is invoked.
     * @param {String} client_key The unique identifier assigned by EBPP to the client.
     * @param {module:models/String} product The product identifier corresponding to the API.
     * @param {String} timestamp The timestamp for the moment when the API request is created.
     * @param {String} idempotent_request_key The unique token that clients can generate and maintain in order to identify an API request.
     * @param {module:models/String} requestor_type Type of the requestor of the API.
     * @param {String} query_id query id of the Retrieve/Search Customers lookup.
     * @param {Object} opts Optional parameters
     * @param {String} opts.requestor The identifier for the requestor of the API. If the requestor_type is &lt;b&gt;system&lt;/b&gt;, requestor is optional.
     * @param {String} opts.x_opay_headers Intended for the future use.
     * @param {String} opts.trace_id The unique reference that can be used for tracing and debugging an API call.
     * @param {String} opts.page_size The maximum number of objects returned in the query.
     * @param {String} opts.from_index To fetch the next set of objects that start after this object
     * @param {String} opts.to_index To fetch the previous set of objects that end at this object
     * @param {module:api/CustomerApi~retrieveCustomersPageCallback} callback The callback function, accepting three arguments: error, data, response
     * data is of type: {@link module:models/CustomersResponse}
     */
    this.retrieveCustomersPage = function(channel, client_key, product, timestamp, idempotent_request_key, requestor_type, query_id, opts, callback) {
      opts = opts || {};
      var postBody = null;

      var pathParams = {
      };
      var queryParams = {
        'page_size': opts['page_size'],
        'query_id': query_id,
        'from_index': opts['from_index'],
        'to_index': opts['to_index']
      };
      var headerParams = {
        'channel': channel,
        'client_key': client_key,
        'product': product,
        'timestamp': timestamp,
        'idempotent_request_key': idempotent_request_key,
        'requestor_type': requestor_type,
        'requestor': opts['requestor'],
        'X-OPAY-Headers': opts['x_opay_headers'],
        'trace_id': opts['trace_id']
      };
      var formParams = {
      };

      var authNames = [];
      var contentTypes = [];
      var accepts = ['application/json'];
      var returnType = CustomersResponse;

      return this.apiClient.callApi(
        '/customers/lists', 'GET',
        pathParams, queryParams, headerParams, formParams, postBody,
        authNames, contentTypes, accepts, returnType, callback
      );
    };

    /**
     * Callback function to receive the result of the updateCustomer operation.
     * @callback module:api/CustomerApi~updateCustomerCallback
     * @param {String} error Error message, if any.
     * @param {module:models/CustomerResponse} data The data returned by the service call.
     * @param {String} response The complete HTTP response.
     */

    /**
     * Update Customer
     * The Update Customer API is used to edit the customer&#39;&#39;s personal details, accounts or the customer&#39;&#39;s status. Only the information being updated needs to be sent in the request, along with the id of the customer being updated. A customer can also be associated with new customer accounts using the API. &lt;br&gt;&lt;br&gt; Along with Customer details ,  Customer and Customer Account statuses also can be updated using the Update Customer API. Below are the possible customer state transformations.  | from_status | to_status | allowed requestor_type | | ------------ | ------------ | ------------ | | active | suspended| &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; | | active | revoked | &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; &lt;/ul&gt; | | suspended | active | &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; &lt;/ul&gt; | | suspended | revoked | &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; &lt;/ul&gt; | | revoked | active | &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt;&lt;/ul&gt; &lt;/ul&gt; |  Below are the possible customer account state transformation.  | from_status | to_status | allowed requestor_type | | ------------ | ------------ | ------------ | | active | inactive| &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; | | inactive | active | &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; &lt;/ul&gt; | | active | incollections | &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; &lt;/ul&gt; | | incollections | active | &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; &lt;/ul&gt; | | inactive | incollections | &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; &lt;/ul&gt; | | incollections | inactive | &lt;ul&gt; &lt;li&gt;external_user&lt;/li&gt; &lt;li&gt; client_agent&lt;/li&gt; &lt;li&gt; system&lt;/li&gt;&lt;/ul&gt; &lt;/ul&gt; | 
     * @param {String} channel The channel through which the API is invoked.
     * @param {String} client_key The unique identifier assigned by EBPP to the client.
     * @param {module:models/String} product The product identifier corresponding to the API.
     * @param {String} timestamp The timestamp for the moment when the API request is created.
     * @param {String} idempotent_request_key The unique token that clients can generate and maintain in order to identify an API request.
     * @param {module:models/String} requestor_type Type of the requestor of the API.
     * @param {String} id_customer The unique identifier assigned by EBPP to the customer.
     * @param {module:models/UpdateCustomerRequest} update_customer_request JSON containing all the attributes of the customer to be updated.
     * @param {Object} opts Optional parameters
     * @param {String} opts.requestor The identifier for the requestor of the API. If the requestor_type is &lt;b&gt;system&lt;/b&gt;, requestor is optional.
     * @param {String} opts.x_opay_headers Intended for the future use.
     * @param {String} opts.trace_id The unique reference that can be used for tracing and debugging an API call.
     * @param {module:api/CustomerApi~updateCustomerCallback} callback The callback function, accepting three arguments: error, data, response
     * data is of type: {@link module:models/CustomerResponse}
     */
    this.updateCustomer = function(channel, client_key, product, timestamp, idempotent_request_key, requestor_type, id_customer, update_customer_request, opts, callback) {
      opts = opts || {};
      var postBody = update_customer_request;

      var pathParams = {
        'ID_CUSTOMER': id_customer
      };
      var queryParams = {
      };
      var headerParams = {
        'channel': channel,
        'client_key': client_key,
        'product': product,
        'timestamp': timestamp,
        'idempotent_request_key': idempotent_request_key,
        'requestor_type': requestor_type,
        'requestor': opts['requestor'],
        'X-OPAY-Headers': opts['x_opay_headers'],
        'trace_id': opts['trace_id']
      };
      var formParams = {
      };

      var authNames = [];
      var contentTypes = ['application/json'];
      var accepts = ['application/json'];
      var returnType = CustomerResponse;

      return this.apiClient.callApi(
        '/customers/{ID_CUSTOMER}', 'PUT',
        pathParams, queryParams, headerParams, formParams, postBody,
        authNames, contentTypes, accepts, returnType, callback
      );
    };
  };

  return exports;
}));