content: {-# LANGUAGE FlexibleInstances     #-}
  {-# LANGUAGE MultiParamTypeClasses #-}
  {-# LANGUAGE OverloadedStrings     #-}
  {-# LANGUAGE TypeFamilies          #-}
  -------------------------------------------
  -- |
  -- Module      : Web.Stripe.Customer
  -- Copyright   : (c) David Johnson, 2014
  -- Maintainer  : code@dmj.io
  -- Stability   : experimental
  -- Portability : POSIX
  --
  -- < https:/\/\stripe.com/docs/api#customers >
  --
  -- @
  -- {-\# LANGUAGE OverloadedStrings \#-}
  -- import Web.Stripe
  -- import Web.Stripe.Customer
  --
  -- main :: IO ()
  -- main = do
  --   let config = StripeConfig (StripeKey "secret_key")
  --   result <- stripe config createCustomer
  --   case result of
  --     Right customer    -> print customer
  --     Left  stripeError -> print stripeError
  -- @
  module Web.Stripe.Customer
      ( -- * API
        ---- * Create customer
        CreateCustomer
      , createCustomer
        ---- * Retrieve customer
      , GetCustomer
      , getCustomer
        ---- * Update customer
      , UpdateCustomer
      , updateCustomer
        ---- * Delete customer
      , DeleteCustomer
      , deleteCustomer
        ---- * List customers
      , GetCustomers
      , getCustomers
        -- * Types
      , AccountBalance     (..)
      , CardId             (..)
      , CardNumber         (..)
      , CouponId           (..)
      , Created            (..)
      , Customer           (..)
      , CustomerId         (..)
      , CVC                (..)
      , Description        (..)
      , Email              (..)
      , EndingBefore       (..)
      , ExpandParams       (..)
      , ExpMonth           (..)
      , ExpYear            (..)
      , Limit              (..)
      , MetaData           (..)
      , mkNewCard
      , NewCard            (..)
      , PlanId             (..)
      , Quantity           (..)
      , StartingAfter      (..)
      , StripeDeleteResult (..)
      , StripeList         (..)
      , TokenId            (..)
      , TrialEnd           (..)
      ) where
  
  import           Web.Stripe.StripeRequest   (Method (GET, POST, DELETE),
                                               StripeHasParam, StripeRequest (..),
                                               StripeReturn, mkStripeRequest)
  import           Web.Stripe.Util            ((</>))
  import           Web.Stripe.Types           (AccountBalance(..), CVC (..),
                                               CardId (..), CardNumber (..),
                                               CouponId (..), Created(..), Customer (..),
                                               CustomerId (..), DefaultCard(..),
                                               Description(..), Email (..),
                                               EndingBefore(..), ExpMonth (..),
                                               ExpYear (..), Limit(..), PlanId (..),
                                               Quantity (..), MetaData(..),
                                               mkNewCard, NewCard(..), StartingAfter(..),
                                               StripeDeleteResult (..),
                                               StripeList (..), TokenId (..),
                                               TrialEnd(..), ExpandParams(..))
  import           Web.Stripe.Types.Util
  
  ------------------------------------------------------------------------------
  -- | Create a customer
  createCustomer :: StripeRequest CreateCustomer
  createCustomer = request
    where request = mkStripeRequest POST url params
          url     = "customers"
          params  = []
  
  data CreateCustomer
  type instance StripeReturn CreateCustomer = Customer
  instance StripeHasParam CreateCustomer AccountBalance
  instance StripeHasParam CreateCustomer NewCard
  instance StripeHasParam CreateCustomer TokenId
  instance StripeHasParam CreateCustomer CouponId
  instance StripeHasParam CreateCustomer Description
  instance StripeHasParam CreateCustomer Email
  instance StripeHasParam CreateCustomer MetaData
  instance StripeHasParam CreateCustomer PlanId
  instance StripeHasParam CreateCustomer Quantity
  instance StripeHasParam CreateCustomer TrialEnd
  
  ------------------------------------------------------------------------------
  -- | Retrieve a customer
  getCustomer
      :: CustomerId  -- ^ `CustomerId` of `Customer` to retrieve
      -> StripeRequest GetCustomer
  getCustomer
    customerid = request
    where request = mkStripeRequest GET url params
          url     = "customers" </> getCustomerId customerid
          params  = []
  
  data GetCustomer
  type instance StripeReturn GetCustomer = Customer
  instance StripeHasParam GetCustomer ExpandParams
  
  ------------------------------------------------------------------------------
  -- | Update a `Customer`
  updateCustomer
      :: CustomerId -- ^ `CustomerId` of `Customer` to update
      -> StripeRequest UpdateCustomer
  updateCustomer customerid = request
    where request = mkStripeRequest POST url params
          url     = "customers" </> getCustomerId customerid
          params  = []
  
  data UpdateCustomer
  type instance StripeReturn UpdateCustomer = Customer
  instance StripeHasParam UpdateCustomer AccountBalance
  instance StripeHasParam UpdateCustomer TokenId
  instance StripeHasParam UpdateCustomer NewCard
  instance StripeHasParam UpdateCustomer CouponId
  instance StripeHasParam UpdateCustomer DefaultCard
  instance StripeHasParam UpdateCustomer Description
  instance StripeHasParam UpdateCustomer Email
  instance StripeHasParam UpdateCustomer MetaData
  
  ------------------------------------------------------------------------------
  -- | Deletes the specified `Customer`
  data DeleteCustomer
  type instance StripeReturn DeleteCustomer = StripeDeleteResult
  deleteCustomer
      :: CustomerId -- ^ The `CustomerId` of the `Customer` to delete
      -> StripeRequest DeleteCustomer
  deleteCustomer customerid = request
    where request = mkStripeRequest DELETE url params
          url     = "customers" </> getCustomerId customerid
          params  = []
  
  
  ------------------------------------------------------------------------------
  -- | Retrieve up to 100 customers at a time
  getCustomers
      :: StripeRequest GetCustomers
  getCustomers =
    request
    where request = mkStripeRequest GET url params
          url     = "customers"
          params  = []
  
  data GetCustomers
  type instance StripeReturn GetCustomers = (StripeList Customer)
  instance StripeHasParam GetCustomers ExpandParams
  instance StripeHasParam GetCustomers Created
  instance StripeHasParam GetCustomers (EndingBefore CustomerId)
  instance StripeHasParam GetCustomers Limit
  instance StripeHasParam GetCustomers (StartingAfter CustomerId)
  
  