content: {-# LANGUAGE FlexibleInstances     #-}
  {-# LANGUAGE MultiParamTypeClasses #-}
  {-# LANGUAGE OverloadedStrings     #-}
  {-# LANGUAGE TypeFamilies          #-}
  -------------------------------------------
  -- |
  -- Module      : Web.Stripe.Refund
  -- Copyright   : (c) David Johnson, 2014
  -- Maintainer  : code@dmj.io
  -- Stability   : experimental
  -- Portability : POSIX
  --
  -- < https:/\/\stripe.com/docs/api#refunds >
  --
  -- @
  -- {-\# LANGUAGE OverloadedStrings \#-}
  -- import Web.Stripe
  -- import Web.Stripe.Customer
  -- import Web.Stripe.Charge
  -- import Web.Stripe.Refund
  --
  -- main :: IO ()
  -- main = do
  --   let config = StripeConfig (StripeKey "secret_key")
  --       credit = CardNumber "4242424242424242"
  --       em  = ExpMonth 12
  --       ey  = ExpYear 2015
  --       cvc = CVC "123"
  --       cardinfo = (mkNewCard credit em ey) { newCardCVC = Just cvc }
  --   result <- stripe config $ createCustomer -&- cardinfo
  --   case result of
  --     (Left stripeError) -> print stripeError
  --     (Right (Customer { customerId = cid })) -> do
  --       result <- stripe config $ createCharge (Amount 100) USD -&- cid
  --       case result of
  --         (Left stripeError) -> print stripeError
  --         (Right (Charge { chargeId   = chid })) -> do
  --           result <- stripe config $ createRefund chid
  --           case result of
  --             (Left stripeError) -> print stripeError
  --             (Right refund)     -> print refund
  -- @
  module Web.Stripe.Refund
      ( -- * API
        CreateRefund
      , createRefund
      , GetRefund
      , getRefund
      , GetRefunds
      , getRefunds
      , UpdateRefund
      , updateRefund
        -- * Types
      , Amount       (..)
      , Charge       (..)
      , ChargeId     (..)
      , EndingBefore (..)
      , ExpandParams (..)
      , Refund       (..)
      , RefundApplicationFee(..)
      , RefundReason (..)
      , RefundId     (..)
      , StripeList   (..)
      ) where
  
  import           Web.Stripe.StripeRequest   (Method (GET, POST),
                                               StripeHasParam, StripeReturn,
                                               StripeRequest (..), mkStripeRequest)
  import           Web.Stripe.Util            ((</>))
  import           Web.Stripe.Types           (Amount(..), Charge (..), ChargeId (..),
                                               EndingBefore(..), Limit(..),
                                               MetaData(..), Refund (..),
                                               RefundApplicationFee(..),
                                               RefundId (..), RefundReason(..),
                                               StartingAfter(..), ExpandParams(..),
                                               StripeList (..))
  import           Web.Stripe.Types.Util      (getChargeId)
  
  ------------------------------------------------------------------------------
  -- | create a `Refund`
  createRefund
      :: ChargeId -- ^ `ChargeId` associated with the `Charge` to be refunded
      -> StripeRequest CreateRefund
  createRefund
      chargeid    = request
    where request = mkStripeRequest POST url params
          url     = "charges" </> getChargeId chargeid </> "refunds"
          params  = []
  
  data CreateRefund
  type instance StripeReturn CreateRefund = Refund
  instance StripeHasParam CreateRefund Amount
  instance StripeHasParam CreateRefund RefundApplicationFee
  instance StripeHasParam CreateRefund RefundReason
  instance StripeHasParam CreateRefund MetaData
  
  ------------------------------------------------------------------------------
  -- | Retrieve a `Refund` by `ChargeId` and `RefundId`
  getRefund
      :: ChargeId -- ^ `ChargeId` associated with the `Refund` to be retrieved
      -> RefundId -- ^ `RefundId` associated with the `Refund` to be retrieved
      -> StripeRequest GetRefund
  getRefund
     chargeid
     (RefundId refundid) = request
     where request = mkStripeRequest GET url params
           url     = "charges" </> getChargeId chargeid </> "refunds" </> refundid
           params  = []
  
  data GetRefund
  type instance StripeReturn GetRefund = Refund
  instance StripeHasParam GetRefund ExpandParams
  
  ------------------------------------------------------------------------------
  -- | Update a `Refund` by `ChargeId` and `RefundId`
  updateRefund
      :: ChargeId -- ^ `ChargeId` associated with the `Charge` to be updated
      -> RefundId -- ^ `RefundId` associated with the `Refund` to be retrieved
      -> StripeRequest UpdateRefund
  updateRefund
     chargeid
     (RefundId refid)
                  = request
    where request = mkStripeRequest POST url params
          url     = "charges" </> getChargeId chargeid  </> "refunds" </> refid
          params  = []
  
  data UpdateRefund
  type instance StripeReturn UpdateRefund = Refund
  instance StripeHasParam UpdateRefund MetaData
  
  ------------------------------------------------------------------------------
  -- | Retrieve a lot of Refunds by `ChargeId`
  getRefunds
      :: ChargeId               -- ^ `ChargeId` associated with the `Refunds` to get
      -> StripeRequest GetRefunds
  getRefunds
    chargeid = request
    where request = mkStripeRequest GET url params
          url     = "charges" </> getChargeId chargeid </> "refunds"
          params  = []
  
  data GetRefunds
  type instance StripeReturn GetRefunds = StripeList Refund
  instance StripeHasParam GetRefunds ExpandParams
  instance StripeHasParam GetRefunds (EndingBefore RefundId)
  instance StripeHasParam GetRefunds Limit
  instance StripeHasParam GetRefunds (StartingAfter RefundId)
  