diff --git a/stripe-haskell.cabal b/stripe-haskell.cabal
--- a/stripe-haskell.cabal
+++ b/stripe-haskell.cabal
@@ -1,5 +1,5 @@
 name:                stripe-haskell
-version:             0.1.4.0
+version:             0.1.4.1
 synopsis:            Stripe API for Haskell
 license:             MIT
 license-file:        LICENSE
@@ -112,15 +112,40 @@
                     , base >=4.6 && < 5
                     , bytestring
                     , either
+                    , hspec == 2.1.*
                     , hspec >= 2.1.4
                     , http-streams
                     , random
-                    , random >= 1.1
                     , stripe-haskell
                     , text
                     , time
                     , transformers
     default-language: Haskell2010
+    other-modules:
+      Test.Account
+      Test.ApplicationFee
+      Test.ApplicationFeeRefund
+      Test.Balance
+      Test.Bitcoin
+      Test.Card
+      Test.Charge
+      Test.Config
+      Test.Coupon
+      Test.Customer
+      Test.Discount
+      Test.Dispute
+      Test.Event
+      Test.Invoice
+      Test.InvoiceItem
+      Test.Plan
+      Test.Raw
+      Test.Recipient
+      Test.Refund
+      Test.Subscription
+      Test.Token
+      Test.Transfer
+      Test.Util
+                  
     ghc-options:      -Wall -threaded -rtsopts
 
 library 
@@ -130,6 +155,7 @@
                      , base >=4.6 && < 5
                      , bytestring
                      , either
+                     , hspec == 2.1.*
                      , http-streams
                      , io-streams
                      , mtl >= 2.1.3.1
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RecordWildCards   #-}
 module Main where
@@ -30,29 +31,32 @@
 -- | Main test function entry point
 main :: IO ()
 main = do
-  config <- getConfig
-  hspec $ parallel $ do
-    rawTest config
-    bitcoinTests config
-    chargeTests config
-    refundTests config
-    customerTests config
-    cardTests config
-    subscriptionTests config
-    planTests config
-    couponTests config
-    discountTests config
-    invoiceTests config
-    invoiceItemTests config
-    disputeTests config
-    transferTests config
-    recipientTests config
-    applicationFeeTests config
-    applicationFeeRefundTests config
-    accountTests config
-    balanceTests config
-    tokenTests config
-    eventTests config
+   let msg = "You must export STRIPEKEY in order to run the tests, returning Success"
+   getConfig >>= \case
+     Nothing -> putStrLn msg
+     Just config -> do
+       hspec $ parallel $ do
+         rawTest config
+         bitcoinTests config
+         chargeTests config
+         refundTests config
+         customerTests config
+         cardTests config
+         subscriptionTests config
+         planTests config
+         couponTests config
+         discountTests config
+         invoiceTests config
+         invoiceItemTests config
+         disputeTests config
+         transferTests config
+         recipientTests config
+         applicationFeeTests config
+         applicationFeeRefundTests config
+         accountTests config
+         balanceTests config
+         tokenTests config
+         eventTests config
 
 
 
diff --git a/tests/Test/Account.hs b/tests/Test/Account.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Account.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Account where
+
+import           Data.Either
+import           Test.Hspec
+import           Web.Stripe
+import           Web.Stripe.Account
+
+accountTests :: StripeConfig -> Spec
+accountTests config = do
+  describe "Account tests" $ do
+    it "Succesfully retrieves account information" $ do
+      result <- stripe config getAccountDetails
+      result `shouldSatisfy` isRight
+
diff --git a/tests/Test/ApplicationFee.hs b/tests/Test/ApplicationFee.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/ApplicationFee.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Test.ApplicationFee where
+
+import Test.Hspec
+import Web.Stripe.ApplicationFee
+import Web.Stripe
+import Data.Either
+
+applicationFeeTests :: StripeConfig -> Spec 
+applicationFeeTests config = do
+  describe "Application Fee tests" $ do
+    it "Succesfully fails to retrieve an unknown application fee" $ do
+      result <- stripe config $ getApplicationFee (FeeId "fee_unknown")
+      result `shouldSatisfy` isLeft
+    it "Succesfully retrieves all application fees" $ do
+      result <- stripe config $ getApplicationFees Nothing Nothing Nothing
+      result `shouldSatisfy` isRight
diff --git a/tests/Test/ApplicationFeeRefund.hs b/tests/Test/ApplicationFeeRefund.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/ApplicationFeeRefund.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards   #-}
+module Test.ApplicationFeeRefund where
+
+import           Data.Either
+import           Test.Hspec
+import           Web.Stripe
+import           Web.Stripe.ApplicationFeeRefund
+
+applicationFeeRefundTests :: StripeConfig -> Spec
+applicationFeeRefundTests config = do
+  describe "Application Fee Refund tests" $ do
+    it "Succesfully fails to refund an unknown application fee" $ do
+      result <- stripe config $ createApplicationFeeRefund (FeeId "blah") Nothing []
+      result `shouldSatisfy` isLeft
+    it "Succesfully fails to retrieve a Application ID with an unknown Refund id" $ do
+      result <- stripe config $ getApplicationFeeRefund (FeeId "blah") (RefundId "adsf")
+      result `shouldSatisfy` isLeft
+    it "Succesfully fails to update an ApplicationRefund for an Invalid Fee ID" $ do
+      result <- stripe config $ updateApplicationFeeRefund (FeeId "blah") (RefundId "blah") []
+      result `shouldSatisfy` isLeft
+    it "Succesfully fails to retrieve all ApplicationRefunds for an Invalid Fee ID" $ do
+      result <- stripe config $ getApplicationFeeRefunds (FeeId "blah") Nothing Nothing Nothing
+      result `shouldSatisfy` isLeft
diff --git a/tests/Test/Balance.hs b/tests/Test/Balance.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Balance.hs
@@ -0,0 +1,50 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Balance where
+
+import           Control.Monad
+import           Data.Either
+import           Test.Hspec
+
+import           Web.Stripe
+import           Web.Stripe.Balance
+import           Web.Stripe.Charge
+import           Web.Stripe.Customer
+
+balanceTests :: StripeConfig -> Spec
+balanceTests config = do
+  describe "Balance tests" $ do
+    it "Succesfully retrieves a Balance" $ do
+      result <- stripe config getBalance
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves a Balance Transaction" $ do
+      result <- stripe config $ do
+          Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+          Charge { chargeBalanceTransaction = Just txid } <-
+            chargeCustomer cid USD 100 Nothing
+          balance <- getBalanceTransaction txid
+          void $ deleteCustomer cid
+          return balance
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves an Expanded Balance Transaction" $ do
+       result <- stripe config $ do
+          Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+          Charge   { chargeBalanceTransaction = Just txid
+                   } <- chargeCustomer cid USD 100 Nothing
+          result <- getBalanceTransactionExpandable txid ["source"]
+          void $ deleteCustomer cid
+          return result
+       result `shouldSatisfy` isRight
+    it "Succesfully retrieves Balance Transaction History" $ do
+      result <- stripe config $ getBalanceTransactionHistory Nothing Nothing Nothing
+      result `shouldSatisfy` isRight
+  where
+    cn  = CardNumber "4242424242424242"
+    em  = ExpMonth 12
+    ey  = ExpYear 2015
+    cvc = CVC "123"
+
+
+
+
+
+
diff --git a/tests/Test/Bitcoin.hs b/tests/Test/Bitcoin.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Bitcoin.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Bitcoin ( bitcoinTests ) where
+
+import           Data.Either
+import           Test.Hspec
+import           Web.Stripe
+import           Web.Stripe.Bitcoin
+
+bitcoinTests :: StripeConfig -> Spec
+bitcoinTests config = do
+  describe "Bitcoin tests" $ do
+    result <- runIO $ stripe config $ createReceiver 10 (Email "fake@gmail.com")
+    it "Succesfully creates a bitcoin receiver" $ do
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves a bitcoin receiver" $ do
+      let Right BitcoinReceiver {..} = result
+      result <- stripe config $ getReceiver btcId
+      result `shouldSatisfy` isRight
+    it "Succesfully lists bitcoin receivers" $ do
+      result <- stripe config $ listReceivers Nothing Nothing Nothing
+      result `shouldSatisfy` isRight
diff --git a/tests/Test/Card.hs b/tests/Test/Card.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Card.hs
@@ -0,0 +1,223 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards   #-}
+
+module Test.Card where
+
+import           Control.Monad
+import           Data.Either
+import           Data.Maybe
+
+import           Test.Hspec
+
+import           Web.Stripe
+import           Web.Stripe.Card
+import           Web.Stripe.Customer
+import           Web.Stripe.Recipient
+import           Web.Stripe.Token
+
+cardTests :: StripeConfig -> Spec
+cardTests config = do
+    describe "Card tests" $ do
+      it "Can create a Customer Card by CardNumber" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid } <- createEmptyCustomer
+          card <- createCustomerCard cid credit em ey cvc
+          void $ deleteCustomer cid
+          return card
+        result `shouldSatisfy` isRight
+      it "Can create a Customer Card by TokenId" $ do
+        result <- stripe config $ do
+          Token    { tokenId = tkid   } <- createCardToken credit em ey cvc
+          Customer { customerId = cid } <- createEmptyCustomer
+          card <- createCustomerCardByToken cid tkid
+          void $ deleteCustomer cid
+          return card
+        result `shouldSatisfy` isRight
+      it "Can retrieve a Customer Card" $ do
+        result <- stripe config $ do
+          Customer { customerId = customerid
+                   , customerCards = StripeList { list = [ Card { cardId = cardid } ] }
+                   } <- createCustomerByCard credit em ey cvc
+          card <- getCustomerCard customerid cardid
+          void $ deleteCustomer customerid
+          return card
+        result `shouldSatisfy` isRight
+        let Right Card{..} = result
+        cardLastFour `shouldBe` "4242"
+        cardExpMonth `shouldBe` em
+        cardExpYear `shouldBe` ey
+      it "Can retrieve a Customer's Card with expansion" $ do
+        result <- stripe config $ do
+          Customer { customerId = customerid
+                   , customerCards = StripeList { list = [ Card { cardId = cardid } ] }
+                   } <- createCustomerByCard credit em ey cvc
+          card <- getCustomerCardExpandable customerid cardid ["customer"]
+          void $ deleteCustomer customerid
+          return card
+        result `shouldSatisfy` isRight
+        let Right Card{..} = result
+        cardLastFour `shouldBe` "4242"
+        cardExpMonth `shouldBe` em
+        cardExpYear `shouldBe` ey
+      it "Can retrieve a Customer's Cards" $ do
+        result <- stripe config $ do
+          Customer { customerId = customerid
+                   } <- createCustomerByCard credit em ey cvc
+          card <- getCustomerCards customerid Nothing Nothing Nothing
+          void $ deleteCustomer customerid
+          return card
+        result `shouldSatisfy` isRight
+      it "Can retrieve a Customer's Cards with Expansion" $ do
+        result <- stripe config $ do
+          Customer { customerId = customerid
+                   } <- createCustomerByCard credit em ey cvc
+          card <- getCustomerCardsExpandable customerid Nothing Nothing Nothing ["data.customer"]
+          void $ deleteCustomer customerid
+          return card
+        result `shouldSatisfy` isRight
+      it "Can delete a Customer's Cards" $ do
+        result <- stripe config $ do
+          Customer { customerId = customerid
+                    , customerDefaultCard = Just cardid
+                   } <- createCustomerByCard credit em ey cvc
+          result <- deleteCustomerCard customerid cardid
+          void $ deleteCustomer customerid
+          return result
+        result `shouldSatisfy` isRight
+      it "Can update a Customer's Card" $ do
+        result <- stripe config $ do
+          Customer { customerId = customerid
+                    , customerDefaultCard = Just cardid
+                   } <- createCustomerByCard credit em ey cvc
+          result <- updateCustomerCard customerid cardid
+                       cardname
+                       cardcity
+                       cardcountry
+                       cardaddressOne
+                       cardaddressTwo
+                       cardaddressState
+                       cardzip
+          void $ deleteCustomer customerid
+          return result
+        result `shouldSatisfy` isRight
+        let Right Card{..} = result
+        cardName `shouldBe` cardname
+        cardAddressCity `shouldBe` cardcity
+        cardAddressCountry `shouldBe` cardcountry
+        cardAddressLine1 `shouldBe` cardaddressOne
+        cardAddressLine2 `shouldBe` cardaddressTwo
+        cardAddressState `shouldBe` cardaddressState
+        cardAddressZip `shouldBe` cardzip
+    describe "Recipient Card tests" $ do
+      it "Can create a RecipientCard by CardNumber" $ do
+        result <- stripe config $ do
+          r@Recipient{..} <- createRecipientByCard firstname lastname Nothing Individual debit em ey cvc
+          void $ deleteRecipient recipientId
+          return r
+        result `shouldSatisfy` isRight
+        let Right Recipient {..} = result
+        length (list recipientCards) `shouldBe` 1
+      it "Can create a RecipientCard by Card TokenId" $ do
+        result <- stripe config $ do
+          Token { tokenId = tkid } <- createCardToken debit em ey cvc
+          Recipient { recipientId = rid } <- createRecipient firstname lastname (Just 'M') Individual
+          rcard <- createRecipientCardByToken rid tkid
+          void $ deleteRecipient rid
+          return rcard
+        result `shouldSatisfy` isRight
+      it "Fails to create a RecipientCard by BankAccount TokenId" $ do
+        result <- stripe config $ do
+          Token { tokenId = tkid } <- createBankAccountToken country routingnumber accountnumber
+          Recipient { recipientId = rid } <- createRecipient firstname lastname (Just 'M') Corporation
+          rcard <- createRecipientCardByToken rid tkid
+          void $ deleteRecipient rid
+          return rcard
+        result `shouldSatisfy` isLeft
+      it "Can retrieve a RecipientCard" $ do
+        result <- stripe config $ do
+          Recipient{..} <- createRecipientByCard firstname lastname Nothing Individual debit em ey cvc
+          rcard <- getRecipientCard recipientId (fromJust recipientDefaultCard)
+          void $ deleteRecipient recipientId
+          return rcard
+        result `shouldSatisfy` isRight
+      it "Can retrieve a RecipientCard Expanded" $ do
+        result <- stripe config $ do
+          Recipient{..} <- createRecipientByCard firstname lastname Nothing Individual debit em ey cvc
+          rcard <- getRecipientCardExpandable recipientId (fromJust recipientDefaultCard) ["recipient"]
+          void $ deleteRecipient recipientId
+          return rcard
+        result `shouldSatisfy` isRight
+      it "Can retrieve a Recipient's Cards" $ do
+        result <- stripe config $ do
+          Recipient{..} <- createRecipientByCard firstname lastname Nothing Individual debit em ey cvc
+          rcard <- getRecipientCards recipientId Nothing Nothing Nothing
+          void $ deleteRecipient recipientId
+          return rcard
+        result `shouldSatisfy` isRight
+      it "Can retrieve a Recipient's Cards Expanded" $ do
+        result <- stripe config $ do
+          Recipient{..} <- createRecipientByCard firstname lastname Nothing Individual debit em ey cvc
+          rcard <- getRecipientCardsExpandable recipientId Nothing Nothing Nothing ["data.recipient"]
+          void $ deleteRecipient recipientId
+          return rcard
+        result `shouldSatisfy` isRight
+      it "Can delete a Recipient Card Expanded" $ do
+        result <- stripe config $ do
+          Recipient{..} <- createRecipientByCard firstname lastname Nothing Individual debit em ey cvc
+          rcard <- deleteRecipientCard recipientId (fromJust recipientDefaultCard)
+          void $ deleteRecipient recipientId
+          return rcard
+        result `shouldSatisfy` isRight
+      it "Can update a Recipient's Card" $ do
+        result <- stripe config $ do
+          Recipient{..} <- createRecipientByCard firstname lastname Nothing Individual debit em ey cvc
+          rcard@RecipientCard{..} <-
+                       updateRecipientCard
+                       recipientId
+                       (fromJust recipientDefaultCard)
+                       cardname
+                       cardcity
+                       cardcountry
+                       cardaddressOne
+                       cardaddressTwo
+                       cardaddressState
+                       cardzip
+          void $ deleteRecipient recipientId
+          return rcard
+        result `shouldSatisfy` isRight
+        let Right RecipientCard{..} = result
+        recipientCardName `shouldBe` cardname
+        recipientCardAddressCity `shouldBe` cardcity
+        recipientCardAddressCountry `shouldBe` cardcountry
+        recipientCardAddressLine1 `shouldBe` cardaddressOne
+        recipientCardAddressLine2 `shouldBe` cardaddressTwo
+        recipientCardAddressState `shouldBe` cardaddressState
+        recipientCardAddressZip `shouldBe` cardzip
+
+      it "Fails to add a Credit Card to a Recipient" $ do
+        result <- stripe config $ 
+          createRecipientByCard firstname lastname Nothing Individual credit em ey cvc
+        result `shouldSatisfy` isLeft
+
+  where
+    credit = CardNumber "4242424242424242"
+    debit  = CardNumber "4000056655665556"
+    em  = ExpMonth 12
+    ey  = ExpYear 2015
+    cvc = CVC "123"
+    country = Country "US"
+    routingnumber = RoutingNumber "110000000"
+    accountnumber = AccountNumber "000123456789"
+    firstname = FirstName "David"
+    lastname = LastName "Johnson"
+    cardname = Just "cardName"
+    cardcity = Just (AddressCity "Chicago")
+    cardcountry = Just (AddressCountry "US")
+    cardaddressOne = Just (AddressLine1 "123 Fake Street")
+    cardaddressTwo = Just (AddressLine2 "456 Fake Street")
+    cardaddressState = Just (AddressState "IL")
+    cardzip = Just (AddressZip "60610")
+
+
+
+
diff --git a/tests/Test/Charge.hs b/tests/Test/Charge.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Charge.hs
@@ -0,0 +1,82 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards   #-}
+module Test.Charge where
+
+import           Control.Monad
+import           Data.Either
+import           Data.Text              (Text)
+import           Test.Hspec
+import           Web.Stripe
+import           Web.Stripe.Charge
+import           Web.Stripe.Customer
+
+chargeTests :: StripeConfig -> Spec
+chargeTests config =
+  describe "Charge tests" $ do
+    chargeCustomerTest
+    retrieveChargeTest
+    updateChargeTest
+    retrieveExpandedChargeTest
+    retrieveAllChargesTest
+    captureChargeTest
+  where
+    cn  = CardNumber "4242424242424242"
+    em  = ExpMonth 12
+    ey  = ExpYear 2015
+    cvc = CVC "123"
+    chargeCustomerTest = 
+      it "Charges a customer succesfully" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+          charge <- chargeCustomer cid USD 100 Nothing
+          void $ deleteCustomer cid
+          return charge
+        result `shouldSatisfy` isRight
+    retrieveChargeTest = 
+      it "Retrieves a charge succesfully" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+          Charge { chargeId = chid } <- chargeCustomer cid USD 100 Nothing
+          result <- getCharge chid
+          void $ deleteCustomer cid
+          return result
+        result `shouldSatisfy` isRight
+    updateChargeTest =
+      it "Updates a charge succesfully" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+          Charge { chargeId = chid } <- chargeCustomer cid USD 100 Nothing
+          _ <- updateCharge chid "Cool" [("hi", "there")]
+          result <- getCharge chid
+          void $ deleteCustomer cid
+          return result
+        result `shouldSatisfy` isRight
+        let Right Charge { chargeMetaData = cmd, chargeDescription = desc } = result
+        cmd `shouldBe` [("hi", "there")]
+        desc `shouldSatisfy` (==(Just "Cool" :: Maybe Text))
+    retrieveExpandedChargeTest =
+      it "Retrieves an expanded charge succesfully" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+          Charge { chargeId = chid } <- chargeCustomer cid USD 100 Nothing
+          result <- getChargeExpandable chid ["balance_transaction", "customer", "invoice"]
+          void $ deleteCustomer cid
+          return result
+        result `shouldSatisfy` isRight
+    retrieveAllChargesTest =
+      it "Retrieves all charges" $ do
+        result <- stripe config $ getCharges Nothing Nothing Nothing
+        result `shouldSatisfy` isRight
+    captureChargeTest = 
+      it "Captures a charge - 2 Step Payment Flow" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+          Charge { chargeId = chid } <- chargeBase 100 USD Nothing (Just cid)
+                                        Nothing Nothing Nothing False 
+                                        Nothing Nothing Nothing Nothing []
+          result <- captureCharge chid Nothing Nothing
+          void $ deleteCustomer cid
+          return result
+        result `shouldSatisfy` isRight
+        let Right Charge { chargeCaptured = captured } = result
+        captured `shouldBe` True
diff --git a/tests/Test/Config.hs b/tests/Test/Config.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Config.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+module Test.Config where
+
+import qualified Data.ByteString.Char8 as B8
+import           Control.Applicative ((<$>))
+import           Web.Stripe
+import           Web.Stripe.Balance
+import           System.Exit
+import           System.Environment
+
+getConfig :: IO (Maybe StripeConfig)
+getConfig = foundKey =<< lookupEnv "STRIPEKEY"
+  where
+    foundKey Nothing = return Nothing
+    foundKey (Just str) = do
+      let config = StripeConfig (B8.pack str)
+      result <- stripe config getBalance
+      case result of
+       Left err -> print err >> exitFailure
+       Right Balance{..} ->
+         case balanceLiveMode of
+           False -> return (Just config)
+           True  -> do putStrLn "You entered your production credentials, woops :)" 
+                       exitFailure
+
+
diff --git a/tests/Test/Coupon.hs b/tests/Test/Coupon.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Coupon.hs
@@ -0,0 +1,91 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Coupon where
+
+import           Control.Monad
+import           Data.Either
+import           Test.Hspec
+import           Test.Util
+
+import           Web.Stripe
+import           Web.Stripe.Coupon
+
+couponTests :: StripeConfig -> Spec
+couponTests config = do
+  describe "Coupon tests" $ do
+    it "Succesfully create a coupon" $ do
+      couponName <- makeCouponId
+      result <- stripe config $ do
+        c@(Coupon { couponId = cid }) <-
+          createCoupon
+             (Just couponName)
+             Once
+             (Just $ AmountOff 1)
+             (Just USD)
+             Nothing
+             Nothing
+             Nothing
+             Nothing
+             []
+        void $ deleteCoupon cid
+        return c
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieve a coupon" $ do
+      couponName <- makeCouponId
+      result <- stripe config $ do
+                Coupon { couponId = cid } <- createCoupon
+                                  (Just couponName)
+                                  Once
+                                  (Just $ AmountOff 1)
+                                  (Just USD)
+                                  Nothing
+                                  Nothing
+                                  Nothing
+                                  Nothing
+                                  []
+                res <- getCoupon cid
+                void $ deleteCoupon cid
+                return res
+      result `shouldSatisfy` isRight
+    it "Succesfully delete a coupon" $ do
+      couponName <- makeCouponId
+      result <- stripe config $ do
+                Coupon { couponId = cid } <- createCoupon
+                                  (Just couponName)
+                                  Once
+                                  (Just $ AmountOff 1)
+                                  (Just USD)
+                                  Nothing
+                                  Nothing
+                                  Nothing
+                                  Nothing
+                                  []
+                deleteCoupon cid
+      result `shouldSatisfy` isRight
+    it "Succesfully update a coupon" $ do
+      couponName <- makeCouponId
+      result <- stripe config $ do
+                Coupon { couponId = cid } <- createCoupon
+                                  (Just couponName)
+                                  Once
+                                  (Just $ AmountOff 1)
+                                  (Just USD)
+                                  Nothing
+                                  Nothing
+                                  Nothing
+                                  Nothing
+                                  []
+                r <- updateCoupon cid [("hi", "there")]
+                void $ deleteCoupon cid
+                return r
+      result `shouldSatisfy` isRight
+      let Right (Coupon { couponMetaData = cmd }) = result
+      cmd `shouldBe` [("hi", "there")]
+    it "Succesfully retrieves all coupons" $ do
+      result <- stripe config $ getCoupons Nothing Nothing Nothing
+      result `shouldSatisfy` isRight
+
+
+
+
+
+
diff --git a/tests/Test/Customer.hs b/tests/Test/Customer.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Customer.hs
@@ -0,0 +1,76 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+module Test.Customer where
+
+import           Data.Either
+import           Data.Maybe
+import           Test.Hspec
+import           Web.Stripe
+import           Web.Stripe.Customer
+
+customerTests :: StripeConfig -> Spec
+customerTests config =
+  describe "Customer tests" $ do
+    it "Creates an empty customer" $ do
+      result <- stripe config $ do
+        c@Customer{..} <- createEmptyCustomer
+        _ <- deleteCustomer customerId
+        return c
+      result `shouldSatisfy` isRight
+    it "Deletes a customer" $ do
+      result <- stripe config $ do
+        c@Customer{..} <- createEmptyCustomer
+        _ <- deleteCustomer customerId
+        return c
+      result `shouldSatisfy` isRight
+    it "Gets a customer" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        customer <- getCustomer cid
+        _ <- deleteCustomer cid
+        return customer
+      result `shouldSatisfy` isRight
+    it "Gets a customer expandable" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        customer <- getCustomerExpandable cid ["default_card"]
+        _ <- deleteCustomer cid
+        return customer
+      result `shouldSatisfy` isRight
+    it "Gets customers" $ do
+      result <- stripe config $ getCustomers (Just 100) Nothing Nothing 
+      result `shouldSatisfy` isRight
+    it "Gets customers expandable" $ do
+      result <- stripe config $ getCustomersExpandable
+                 Nothing Nothing Nothing ["data.default_card"]
+      result `shouldSatisfy` isRight
+    it "Updates a customer" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        customer <- updateCustomerBase cid
+                      bal
+                      Nothing
+                      Nothing
+                      Nothing
+                      Nothing
+                      Nothing
+                      Nothing
+                      Nothing
+                      desc 
+                      email
+                      meta
+        _ <- deleteCustomer cid
+        return customer
+      result `shouldSatisfy` isRight
+      let Right Customer{..} = result
+      customerAccountBalance `shouldBe` (fromJust bal)
+      customerDescription `shouldBe` desc
+      customerEmail `shouldBe` email
+      customerMetaData `shouldBe` meta
+  where
+    bal = Just 100
+    desc = Just "hey"
+    email = Just $ Email "djohnson.m@gmail.com"
+    meta = [("hey","there")]
+    
+
diff --git a/tests/Test/Discount.hs b/tests/Test/Discount.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Discount.hs
@@ -0,0 +1,106 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Discount where
+
+import           Control.Monad (void)
+import           Data.Either
+import           Test.Hspec
+import           Test.Util
+
+import           Web.Stripe
+import           Web.Stripe.Coupon
+import           Web.Stripe.Customer
+import           Web.Stripe.Discount
+import           Web.Stripe.Plan
+import           Web.Stripe.Subscription
+
+discountTests :: StripeConfig -> Spec
+discountTests config = do
+  describe "Discount tests" $ do
+    it "Succesfully deletes a discount from a Customer" $ do
+      coupon <- makeCouponId
+      result <- stripe config $ do
+        Coupon { couponId = couponid } <-
+          createCoupon
+             (Just coupon)
+             Once
+             (Just $ AmountOff 1)
+             (Just USD)
+             Nothing
+             Nothing
+             Nothing
+             Nothing
+             []
+        Customer { customerId = customerid } <-
+          createCustomerBase
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            (Just coupon)
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            []
+        r <- deleteCustomerDiscount customerid
+        c <- getCustomer customerid
+        void $ deleteCustomer customerid
+        void $ deleteCoupon couponid
+        return (r,c)
+      result `shouldSatisfy` isRight
+      let Right (_, Customer{..}) = result
+      customerDiscount `shouldBe` Nothing
+    it "Succesfully deletes a discount from a Subscription" $ do
+      coupon <- makeCouponId
+      plan <- makePlanId
+      result <- stripe config $ do
+        Plan { planId = planid } <-
+          createPlan plan
+          0 -- free plan
+          USD
+          Month
+          "sample plan"
+          []
+        Coupon { couponId = couponid } <-
+          createCoupon
+             (Just coupon)
+             Once
+             (Just $ AmountOff 1)
+             (Just USD)
+             Nothing
+             Nothing
+             Nothing
+             Nothing
+             []
+        Customer { customerId = customerid } <-
+          createCustomerBase
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            (Just coupon)
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            Nothing
+            []
+        Subscription { subscriptionId = sid } <-
+          createSubscription customerid plan []
+        void $ updateSubscription customerid sid (Just coupon) Nothing []
+        result <- deleteSubscriptionDiscount customerid sid
+        void $ deletePlan planid
+        void $ deleteCustomer customerid
+        void $ deleteCoupon couponid
+        return result
+      result `shouldSatisfy` isRight
+
+
+
+
diff --git a/tests/Test/Dispute.hs b/tests/Test/Dispute.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Dispute.hs
@@ -0,0 +1,99 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Dispute where
+
+import           Data.Either            (isRight)
+import           Control.Monad          (void)
+import           Control.Concurrent     (threadDelay)
+import           Control.Monad.IO.Class (liftIO)
+
+import           Test.Hspec
+import           Test.Util
+
+import           Web.Stripe
+import           Web.Stripe.Dispute
+import           Web.Stripe.Charge
+import           Web.Stripe.Customer
+
+disputeTests :: StripeConfig -> Spec
+disputeTests config = do
+  describe "Dispute Tests" $ do
+    it "Creates a Dispute" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+        Charge   { chargeId = chid } <- chargeCustomer cid USD 100 Nothing
+        liftIO $ threadDelay (secs 20) -- Sleep the thread to allow the dispute to happen
+        Charge { chargeDispute = cd } <- getCharge chid
+        void $ deleteCustomer cid
+        return cd
+      result `shouldSatisfy` isRight
+      let Right (Just Dispute{..}) = result 
+      disputeStatus `shouldBe` NeedsResponse
+    it "Makes Dispute Under Review" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+        Charge   { chargeId = chid  } <- chargeCustomer cid USD 100 Nothing
+        liftIO $ threadDelay (secs 10)
+        void $ updateDispute chid evi meta
+        liftIO $ threadDelay (secs 10)
+        Charge { chargeDispute = Just dispute } <- getCharge chid
+        void $ deleteCustomer cid
+        return dispute
+      result `shouldSatisfy` isRight
+      let Right Dispute {..} = result 
+      disputeMetaData `shouldBe` meta
+      disputeEvidence `shouldBe` evi
+      disputeStatus `shouldBe` UnderReview
+    it "Wins a Dispute" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+        Charge   { chargeId = chid  } <- chargeCustomer cid USD 100 Nothing
+        liftIO $ threadDelay (secs 10)
+        void $ updateDispute chid win meta
+        liftIO $ threadDelay (secs 10)
+        Charge { chargeDispute = Just dispute } <- getCharge chid
+        void $ deleteCustomer cid
+        return dispute
+      result `shouldSatisfy` isRight
+      let Right Dispute {..} = result 
+      disputeMetaData `shouldBe` meta
+      disputeEvidence `shouldBe` win
+      disputeStatus `shouldBe` Won
+    it "Loses a Dispute" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+        Charge   { chargeId = chid  } <- chargeCustomer cid USD 100 Nothing
+        liftIO $ threadDelay (secs 10) -- Sleep to allow the thread to dispute to happen
+        void $ updateDispute chid lose meta
+        liftIO $ threadDelay (secs 10)
+        Charge { chargeDispute = Just dispute } <- getCharge chid
+        void $ deleteCustomer cid
+        return dispute
+      result `shouldSatisfy` isRight
+      let Right Dispute {..} = result 
+      disputeMetaData `shouldBe` meta
+      disputeEvidence `shouldBe` lose
+      disputeStatus `shouldBe` Lost
+    it "Closes a Dispute" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createCustomerByCard cn em ey cvc
+        Charge   { chargeId = chid  } <- chargeCustomer cid USD 100 Nothing
+        liftIO $ threadDelay (secs 10) -- Sleep to allow the thread to dispute to happen
+        dispute <- closeDispute chid
+        void $ deleteCustomer cid
+        return dispute
+      result `shouldSatisfy` isRight
+      let Right Dispute {..} = result 
+      disputeStatus `shouldBe` Lost
+  where
+    cn  = CardNumber "4000000000000259"
+    em  = ExpMonth 12
+    ey  = ExpYear 2015
+    cvc = CVC "123"
+    win  = Just $ Evidence "winning_evidence"
+    lose = Just $ Evidence "losing_evidence"
+    evi = Just $ Evidence "some evidence"
+    meta = [ ("some", "metadata") ]
+
+
+
diff --git a/tests/Test/Event.hs b/tests/Test/Event.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Event.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Event where
+
+import           Data.Either
+
+import           Test.Hspec
+
+import           Web.Stripe
+import           Web.Stripe.Event
+
+eventTests :: StripeConfig -> Spec
+eventTests config = do
+  describe "Event tests" $ do
+    it "Succesfully retrieves events" $ do
+      result <- stripe config $ getEvents Nothing Nothing Nothing
+      result `shouldSatisfy` isRight
+
+
diff --git a/tests/Test/Invoice.hs b/tests/Test/Invoice.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Invoice.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Invoice where
+
+import           Data.Either
+
+import           Control.Monad          (void)
+import           Test.Util        
+import           Test.Hspec
+
+import           Web.Stripe
+import           Web.Stripe.Invoice
+import           Web.Stripe.Plan
+import           Web.Stripe.Customer
+import           Web.Stripe.InvoiceItem
+
+invoiceTests :: StripeConfig -> Spec
+invoiceTests config = do
+  describe "Invoice tests" $ do
+    it "Create an Invoice via Invoice item on a Customer" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        InvoiceItem { } <- createInvoiceItem cid 100 USD Nothing Nothing Nothing []
+        i <- createInvoice cid meta 
+        void $ deleteCustomer cid
+        return i
+      result `shouldSatisfy` isRight
+    it "Retrieve an Invoice" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        Plan { } <- createPlan planid 20 USD Day "testplan" []
+        InvoiceItem { } <- createInvoiceItem cid 100 USD Nothing Nothing Nothing []
+        Invoice { invoiceId = Just iid } <- createInvoice cid meta 
+        getInvoice iid
+      result `shouldSatisfy` isRight
+    it "Retrieve an Invoice Expanded" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        Plan { } <- createPlan planid 20 USD Day "testplan" []
+        InvoiceItem { } <- createInvoiceItem cid 100 USD Nothing Nothing Nothing []
+        Invoice { invoiceId = Just iid } <- createInvoice cid meta 
+        getInvoiceExpandable iid ["customer", "charge"]
+      result `shouldSatisfy` isRight
+    it "Retrieve an Invoice's Line Items" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        Plan { } <- createPlan planid 20 USD Day "testplan" []
+        InvoiceItem { } <- createInvoiceItem cid 100 USD Nothing Nothing Nothing []
+        Invoice { invoiceId = Just iid } <- createInvoice cid meta 
+        getInvoiceLineItems iid Nothing Nothing Nothing
+      result `shouldSatisfy` isRight
+    it "Retrieve Invoices" $ do
+      result <- stripe config $ getInvoices Nothing Nothing Nothing 
+      result `shouldSatisfy` isRight
+    it "Retrieve Invoices Expandable" $ do
+      result <- stripe config $ getInvoicesExpandable Nothing Nothing Nothing
+                ["data.customer", "data.charge"]
+      result `shouldSatisfy` isRight
+    it "Updates an Invoice" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        Plan { } <- createPlan planid 20 USD Day "testplan" []
+        InvoiceItem { } <- createInvoiceItem cid 100 USD Nothing Nothing Nothing []
+        Invoice { invoiceId = Just iid } <- createInvoice cid meta 
+        updateInvoice iid [("some", "thing")]
+      result `shouldSatisfy` isRight
+      let Right Invoice {..} = result
+      invoiceMetaData `shouldBe` [("some", "thing")]
+    it "Retrieve an Upcoming Invoice" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        Plan { } <- createPlan planid 20 USD Day "testplan" []
+        InvoiceItem { } <- createInvoiceItem cid 100 USD Nothing Nothing Nothing []
+        getUpcomingInvoice cid
+      result `shouldSatisfy` isRight
+    it "Pay an Invoice" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createCustomerByCard credit em ey cvc
+        Plan { } <- createPlan planid 20 USD Day "testplan" []
+        InvoiceItem { } <- createInvoiceItem cid 100 USD Nothing Nothing Nothing []
+        Invoice { invoiceId = Just iid } <- createInvoice cid meta 
+        payInvoice iid
+      result `shouldSatisfy` isRight
+      let Right Invoice{..} = result 
+      invoicePaid `shouldBe` True
+  where
+    meta = [ ("some","metadata") ]
+    credit = CardNumber "4242424242424242"
+    em  = ExpMonth 12
+    ey  = ExpYear 2015
+    cvc = CVC "123"
+
diff --git a/tests/Test/InvoiceItem.hs b/tests/Test/InvoiceItem.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/InvoiceItem.hs
@@ -0,0 +1,83 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Test.InvoiceItem where
+
+import           Data.Either
+
+import           Test.Hspec
+
+import           Web.Stripe
+import           Web.Stripe.InvoiceItem
+import           Web.Stripe.Customer
+
+invoiceItemTests :: StripeConfig -> Spec
+invoiceItemTests config = do
+  describe "Invoice item tests" $ do
+    it "Succesfully creates an invoice item" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        ii <- createInvoiceItem cid 100 USD Nothing Nothing (Just "hey") []
+        _ <- deleteCustomer cid
+        return ii
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves an existing invoice item" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        InvoiceItem { invoiceItemId = iid } <-
+           createInvoiceItem cid 100 USD Nothing Nothing (Just "hey") []
+        ii <- getInvoiceItem iid
+        _ <- deleteCustomer cid
+        return ii 
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves an existing invoice item expandable" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        InvoiceItem { invoiceItemId = iid } <-
+           createInvoiceItem cid 100 USD Nothing Nothing (Just "hey") []
+        ii <- getInvoiceItemExpandable iid ["customer"]
+        _ <- deleteCustomer cid
+        return ii
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves invoice items" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        InvoiceItem {  } <-
+           createInvoiceItem cid 100 USD Nothing Nothing (Just "hey") []
+        ii <- getInvoiceItems Nothing Nothing Nothing Nothing 
+        _ <- deleteCustomer cid
+        return ii
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves invoice items with expansion" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        InvoiceItem {  } <-
+           createInvoiceItem cid 100 USD Nothing Nothing (Just "hey") []
+        ii <- getInvoiceItemsExpandable Nothing Nothing Nothing Nothing ["data.customer"]
+        _ <- deleteCustomer cid
+        return ii
+      result `shouldSatisfy` isRight
+    it "Succesfully updates an existing invoice item" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        InvoiceItem { invoiceItemId = iid } <-
+           createInvoiceItem cid 100 USD Nothing Nothing (Just "hey") []
+        ii <- updateInvoiceItem iid (Just 200) (Just "description") [("some","thing")]
+        _  <- deleteCustomer cid
+        return ii
+      result `shouldSatisfy` isRight
+      let Right InvoiceItem{..} = result
+      invoiceItemMetaData `shouldBe` [("some","thing")]
+      invoiceItemDescription `shouldBe` Just "description"
+      invoiceItemAmount `shouldBe` 200
+    it "Succesfully deletes an invoice item" $ do
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        InvoiceItem { invoiceItemId = iid } <-
+           createInvoiceItem cid 100 USD Nothing Nothing (Just "hey") []
+        result <- deleteInvoiceItem iid
+        _ <- deleteCustomer cid
+        return result
+      result `shouldSatisfy` isRight
+
+
+
diff --git a/tests/Test/Plan.hs b/tests/Test/Plan.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Plan.hs
@@ -0,0 +1,114 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Plan where
+
+import           Control.Monad (void)
+import           Data.Either   (isRight)
+import           Data.Time
+
+import           Test.Hspec
+import           Test.Util     (makePlanId)
+
+import           Web.Stripe
+import           Web.Stripe.Plan
+import           Web.Stripe.Customer
+
+planTests :: StripeConfig -> Spec
+planTests config = do
+  describe "Plan tests" $ do
+    it "Succesfully creates a Plan" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        p <- createPlan planid
+                        0 -- free plan
+                        USD
+                        Month
+                        "sample plan"
+                        []
+        void $ deletePlan planid
+        return p
+      result `shouldSatisfy` isRight
+    it "Succesfully deletes a Plan" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Plan { planId = pid } <-
+          createPlan planid
+          0 -- free plan
+          USD
+          Month
+          "sample plan"
+          []
+        deletePlan pid
+      result `shouldSatisfy` isRight
+    it "Succesfully updates a Plan" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Plan { planId = pid } <-
+          createPlan planid
+          0 -- free plan
+          USD
+          Month
+          "sample plan"
+          []
+        r <- updatePlanBase pid (Just "cookie")
+                                (Just "test")
+                                [("key","value")]
+        void $ deletePlan pid
+        return r
+      result `shouldSatisfy` isRight
+      let Right Plan { planMetaData = pm
+                     , planName = pname
+                     , planDescription = pdesc
+                     } = result
+      pm `shouldBe` [("key", "value")]
+      pname `shouldBe` "cookie"
+      pdesc `shouldBe` Just "test"
+    it "Succesfully creates a Plan with a TrialPeriod" $ do
+      planid <- makePlanId
+      today <- getCurrentTime
+      let trialPeriod = UTCTime (addDays 14 $ utctDay today) (utctDayTime today)
+      result <- stripe config $ do
+           p <- createPlan planid
+             100 -- lets charge for it
+             USD
+             Month
+             "sample 100 plan"
+             []
+           c <- createCustomerBase Nothing
+             Nothing
+             Nothing
+             Nothing
+             Nothing
+             Nothing
+             Nothing -- couponId
+             Nothing
+             (Just $ Email "test@example.com")
+             (Just planid)
+             Nothing
+             (Just $ TrialPeriod trialPeriod)
+             []
+           void $ deletePlan planid
+           void $ deleteCustomer $ customerId c
+           return (p, c)
+      result `shouldSatisfy` isRight
+
+    it "Succesfully retrieves a Plan" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Plan { planId = pid } <-
+          createPlan planid
+          0 -- free plan
+          USD
+          Month
+          "sample plan"
+          []
+        r <- getPlan pid
+        void $ deletePlan pid
+        return r
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves a list of Plans" $ do
+      result <- stripe config $ getPlans Nothing Nothing Nothing
+      result `shouldSatisfy` isRight
+
+
+
+
diff --git a/tests/Test/Raw.hs b/tests/Test/Raw.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Raw.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Raw (rawTest) where
+
+import           Data.Aeson
+import           Data.Either
+import           Data.Monoid         ((<>))
+import           Data.Text           (Text)
+import qualified Data.Text.Encoding  as T
+import           Network.Http.Client
+import           Test.Hspec
+import           Web.Stripe
+
+rawTest :: StripeConfig -> Spec
+rawTest config = do
+  describe "Raw tests" $ do
+    it "Succesfully retrieves account information" $ do
+      result <- (stripeRaw config req) :: IO (Either StripeError Value)
+      result `shouldSatisfy` isRight
+    it "Succesfully encodes x-www-form-urlencoded data" $ do
+      let pid = "encoded"
+      -- Add form data to the request with special characters
+      result <- (stripeRaw config (req2 pid)) :: IO (Either StripeError Value)
+      result `shouldSatisfy` isRight
+      del <- (stripeRaw config (delReq2 pid)) :: IO (Either StripeError Value)
+      del `shouldSatisfy` isRight
+  where
+    req :: StripeRequest
+    req = StripeRequest GET "events" []
+    req2 :: Text -> StripeRequest
+    req2 pid = StripeRequest POST "plans" [ ("amount", "2000")
+                                          , ("interval", "month")
+                                          , ("name","<Acme & Co. Gold Plan+>" )
+                                          , ("currency","usd" )
+                                          , ("id", T.encodeUtf8 pid)
+                                          ]
+    delReq2 :: Text -> StripeRequest
+    delReq2 pid = StripeRequest DELETE ("plans/" <> pid) []
diff --git a/tests/Test/Recipient.hs b/tests/Test/Recipient.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Recipient.hs
@@ -0,0 +1,116 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+module Test.Recipient where
+
+import           Data.Either
+import           Test.Hspec
+import           Control.Monad
+
+import           Web.Stripe
+import           Web.Stripe.Recipient
+
+recipientTests :: StripeConfig -> Spec
+recipientTests config = do
+  describe "Recipient tests" $ do
+    it "Succesfully creates an Individual Recipient" $ do
+      result <- stripe config $ do
+        recipient@Recipient { recipientId = rid } <- createRecipient
+          firstName
+          lastName
+          initial
+          Individual
+        void $ deleteRecipient rid
+        return recipient
+      result `shouldSatisfy` isRight
+      let Right Recipient {..} = result
+      recipientType `shouldBe` Individual                            
+    it "Succesfully creates a Corporation Recipient" $ do
+      result <- stripe config $ do
+        recipient@Recipient { recipientId = rid } <-
+           createRecipient
+             firstName
+             lastName
+             initial
+             Corporation
+        void $ deleteRecipient rid
+        return recipient
+      result `shouldSatisfy` isRight
+      let Right Recipient {..} = result
+      recipientType `shouldBe` Corporation
+    it "Succesfully retrieves a Recipient" $ do
+      result <- stripe config $ do
+        Recipient { recipientId = rid } <-
+          createRecipient
+            firstName
+            lastName
+            initial
+            Corporation
+        recipient <- getRecipient rid
+        void $ deleteRecipient rid
+        return recipient
+      result `shouldSatisfy` isRight
+      let Right Recipient {..} = result
+      recipientType `shouldBe` Corporation
+    it "Succesfully retrieves a Recipient" $ do
+      result <- stripe config $ do
+        Recipient { recipientId = rid } <-
+          createRecipient
+            firstName
+            lastName
+            initial
+            Corporation
+        recipient <- getRecipient rid
+        void $ deleteRecipient rid
+        return recipient
+      result `shouldSatisfy` isRight
+      let Right Recipient {..} = result
+      recipientType `shouldBe` Corporation
+    it "Succesfully updates a Recipient" $ do
+      result <- stripe config $ do
+        Recipient { recipientId = rid } <-
+          createRecipient
+            firstName
+            lastName
+            initial
+            Corporation
+        recipient <- updateRecipientBase rid
+                     (Just firstName)
+                     (Just lastName)
+                     initial
+                     taxid
+                     country
+                     routingnumber
+                     accountnumber
+                     Nothing Nothing Nothing Nothing Nothing
+                     Nothing email description meta
+        void $ deleteRecipient rid
+        return recipient
+      result `shouldSatisfy` isRight
+      let Right Recipient {..} = result
+      recipientType `shouldBe` Corporation
+      recipientName `shouldBe` "david M johnson"
+      recipientDescription `shouldBe` description
+      recipientEmail `shouldBe` email
+    it "Succesfully deletes a Recipient" $ do
+      result <- stripe config $ do
+        Recipient { recipientId = rid } <-
+          createRecipient
+            firstName
+            lastName
+            initial
+            Corporation
+        deleteRecipient rid
+      result `shouldSatisfy` isRight
+
+
+  where firstName = FirstName "david"
+        lastName  = LastName "johnson"
+        initial   = Just 'M'
+        meta      = [("this", "thing")]
+        email     = Just $ Email "djohnson.m@gmail.com"
+        country   = Just $ Country "US"
+        description = Just "description"
+        routingnumber = Just $ RoutingNumber "110000000"
+        accountnumber = Just $ AccountNumber "000123456789"
+        taxid = Just "000000000"
+
diff --git a/tests/Test/Refund.hs b/tests/Test/Refund.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Refund.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Refund where
+
+import           Control.Monad
+import           Data.Either
+
+import           Test.Hspec
+
+import           Web.Stripe
+import           Web.Stripe.Charge
+import           Web.Stripe.Customer
+import           Web.Stripe.Refund
+
+------------------------------------------------------------------------------
+-- | Card Info
+cn :: CardNumber
+cn  = CardNumber "4242424242424242"
+
+em :: ExpMonth
+em  = ExpMonth 12
+
+ey :: ExpYear
+ey  = ExpYear 2015
+
+cvc :: CVC
+cvc = CVC "123"
+
+------------------------------------------------------------------------------
+-- | Refund Tests
+refundTests :: StripeConfig -> Spec
+refundTests config = do
+    describe "Refund Tests" $ do
+      it "Creates a refund succesfully" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid }  <- createCustomerByCard cn em ey cvc
+          Charge   { chargeId   = chid } <- chargeCustomer cid USD 100 Nothing
+          refund <- createRefund chid []
+          void $ deleteCustomer cid
+          return refund
+        result `shouldSatisfy` isRight
+      it "Retrieves a refund succesfully" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid  } <- createCustomerByCard cn em ey cvc
+          Charge   { chargeId   = chid } <- chargeCustomer cid USD 100 Nothing
+          Refund   { refundId   = rid  } <- createRefund chid []
+          void $ deleteCustomer cid
+          getRefund chid rid
+        result `shouldSatisfy` isRight
+      it "Retrieves a refund succesfully with expansion" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid  } <- createCustomerByCard cn em ey cvc
+          Charge   { chargeId   = chid } <- chargeCustomer cid USD 100 Nothing
+          Refund   { refundId   = rid  } <- createRefund chid []
+          r <- getRefundExpandable chid rid  ["balance_transaction"]
+          void $ deleteCustomer cid 
+          return r
+        result `shouldSatisfy` isRight
+      it "Updates a refund succesfully" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid  } <- createCustomerByCard cn em ey cvc
+          Charge   { chargeId   = chid } <- chargeCustomer cid USD 100 Nothing
+          Refund   { refundId   = rid  } <- createRefund chid []
+          ref <- updateRefund chid rid [("hello","there")]
+          void $ deleteCustomer cid
+          return ref
+        result `shouldSatisfy` isRight
+        let Right Refund{..} = result
+        refundMetaData `shouldBe` [("hello","there")]
+      it "Retrieves all refunds for a Charge" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid  } <- createCustomerByCard cn em ey cvc
+          Charge   { chargeId   = chid } <- chargeCustomer cid USD 100 Nothing
+          Refund { } <- createRefund chid []
+          r <- getRefunds chid Nothing Nothing Nothing
+          void $ deleteCustomer cid
+          return r
+        result `shouldSatisfy` isRight
+        let Right StripeList {..} = result
+        length list `shouldBe` 1
+      it "Retrieves all refunds for a Charge with expansion" $ do
+        result <- stripe config $ do
+          Customer { customerId = cid  } <- createCustomerByCard cn em ey cvc
+          Charge   { chargeId   = chid } <- chargeCustomer cid USD 100 Nothing
+          Refund { } <- createRefund chid []
+          r <- getRefundsExpandable chid Nothing Nothing Nothing ["data.balance_transaction"]
+          void $ deleteCustomer cid
+          return r
+        result `shouldSatisfy` isRight
+        let Right StripeList {..} = result
+        length list `shouldBe` 1
+
+
+
+
+
diff --git a/tests/Test/Subscription.hs b/tests/Test/Subscription.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Subscription.hs
@@ -0,0 +1,157 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Subscription where
+
+import           Data.Either
+import           Control.Monad
+import           Data.Maybe
+
+import           Test.Hspec
+import           Test.Util
+
+import           Web.Stripe
+import           Web.Stripe.Subscription
+import           Web.Stripe.Customer
+import           Web.Stripe.Plan
+import           Web.Stripe.Coupon
+
+subscriptionTests :: StripeConfig -> Spec
+subscriptionTests config = do
+  describe "Subscription tests" $ do
+    it "Succesfully creates a Subscription" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        void $ createPlan planid
+                        0 -- free plan
+                        USD
+                        Month
+                        "sample plan"
+                        []
+        sub <- createSubscription cid planid []
+        void $ deletePlan planid
+        void $ deleteCustomer cid
+        return sub
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves a Subscription" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        void $ createPlan planid
+                        0 -- free plan
+                        USD
+                        Month
+                        "sample plan"
+                        []
+        Subscription { subscriptionId = sid } <- createSubscription cid planid []
+        sub <- getSubscription cid sid
+        void $ deletePlan planid
+        void $ deleteCustomer cid
+        return sub
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves a Subscription expanded" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        void $ createPlan planid
+                        0 -- free plan
+                        USD
+                        Month
+                        "sample plan"
+                        []
+        Subscription { subscriptionId = sid } <- createSubscription cid planid []
+        sub <- getSubscriptionExpandable cid sid ["customer"]
+        void $ deletePlan planid
+        void $ deleteCustomer cid
+        return sub
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves a Customer's Subscriptions expanded" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        void $ createPlan planid
+                        0 -- free plan
+                        USD
+                        Month
+                        "sample plan"
+                        []
+        void $ createSubscription cid planid []
+        sub <- getSubscriptionsExpandable cid Nothing Nothing Nothing ["data.customer"]
+        void $ deletePlan planid
+        void $ deleteCustomer cid
+        return sub
+      result `shouldSatisfy` isRight
+    it "Succesfully retrieves a Customer's Subscriptions" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        void $ createPlan planid
+                        0 -- free plan
+                        USD
+                        Month
+                        "sample plan"
+                        []
+        void $ createSubscription cid planid []
+        sub <- getSubscriptions cid Nothing Nothing Nothing 
+        void $ deletePlan planid
+        void $ deleteCustomer cid
+        return sub
+      result `shouldSatisfy` isRight
+    it "Succesfully updates a Customer's Subscriptions" $ do
+      planid <- makePlanId
+      secondPlanid <- makePlanId
+      couponid <- makeCouponId
+      result <- stripe config $ do
+        Coupon { } <-
+          createCoupon
+             (Just couponid)
+             Once
+             (Just $ AmountOff 1)
+             (Just USD)
+             Nothing
+             Nothing
+             Nothing
+             Nothing
+             []
+        Customer { customerId = cid } <- createEmptyCustomer
+        void $ createPlan planid
+                        0 -- free plan
+                        USD
+                        Month
+                        "sample plan"
+                        []
+        void $ createPlan secondPlanid
+                        0 -- free plan
+                        USD
+                        Year
+                        "second sample plan"
+                        []
+        Subscription { subscriptionId = sid } <- createSubscription cid planid []
+        _ <- updateSubscription cid sid (Just couponid) Nothing [("hi","there")]
+        sub <- updateSubscription cid sid (Just couponid) (Just secondPlanid) [("hi","there")]
+        void $ deletePlan planid
+        void $ deletePlan secondPlanid
+        void $ deleteCustomer cid
+        return sub
+      result `shouldSatisfy` isRight
+      let Right Subscription {..} = result
+      subscriptionMetaData `shouldBe` [("hi", "there")]
+      subscriptionDiscount `shouldSatisfy` isJust
+    it "Succesfully cancels a Customer's Subscription" $ do
+      planid <- makePlanId
+      result <- stripe config $ do
+        Customer { customerId = cid } <- createEmptyCustomer
+        void $ createPlan planid
+                        0 -- free plan
+                        USD
+                        Month
+                        "sample plan"
+                        []
+        Subscription { subscriptionId = sid } <- createSubscription cid planid []
+        sub <- cancelSubscription cid sid False
+        void $ deletePlan planid
+        void $ deleteCustomer cid
+        return sub
+      result `shouldSatisfy` isRight
+      let Right Subscription {..} = result
+      subscriptionStatus `shouldBe` Canceled
diff --git a/tests/Test/Token.hs b/tests/Test/Token.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Token.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+module Test.Token where
+
+import           Data.Either
+import           Test.Hspec
+import           Web.Stripe
+import           Web.Stripe.Token
+
+tokenTests :: StripeConfig -> Spec
+tokenTests config = do
+  describe "Token tests" $ do
+    it "Can create a Card Token" $ do
+      result <- stripe config $ createCardToken cn em ey cvc
+      result `shouldSatisfy` isRight
+    it "Can create a Bank Account Token" $ do
+      result <- stripe config $ createBankAccountToken
+                                  (Country "US")
+                                  (RoutingNumber "110000000")
+                                  (AccountNumber "000123456789")
+      result `shouldSatisfy` isRight
+    it "Can retrieve an Existing Card Token" $ do
+      result <- stripe config $ do
+        Token { tokenId = tkid } <- createCardToken cn em ey cvc
+        getCardToken tkid
+      result `shouldSatisfy` isRight
+    it "Can retrieve an Existing Bank Account Token" $ do
+      result <- stripe config $ do
+        Token { tokenId = tkid } <- createBankAccountToken
+                 (Country "US")
+                 (RoutingNumber "110000000")
+                 (AccountNumber "000123456789")
+        getBankAccountToken tkid
+      result `shouldSatisfy` isRight
+  where
+    cn  = CardNumber "4242424242424242"
+    em  = ExpMonth 12
+    ey  = ExpYear 2015
+    cvc = CVC "123"
+
+
+        
+        
+
diff --git a/tests/Test/Transfer.hs b/tests/Test/Transfer.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Transfer.hs
@@ -0,0 +1,117 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Test.Transfer where
+
+import           Data.Either
+import           Control.Monad
+import           Test.Hspec
+
+import           Web.Stripe
+import           Web.Stripe.Recipient
+import           Web.Stripe.Transfer
+
+transferTests :: StripeConfig -> Spec
+transferTests config = do
+  describe "Transfer tests" $ do
+    it "Create a new transfer" $ do
+      result <- stripe config $ do
+        Recipient { recipientId = rid } <-
+          createRecipientByBank
+            firstname
+            lastname
+            Nothing
+            Individual
+            country
+            routingnumber
+            accountnumber
+        transfer <- createTransfer rid (100 :: Amount) USD []
+        void $ deleteRecipient rid
+        return transfer
+      result `shouldSatisfy` isRight
+    it "Retrieves a transfer" $ do
+      result <- stripe config $ do
+        Recipient { recipientId = rid } <-
+          createRecipientByBank
+            firstname
+            lastname
+            Nothing
+            Individual
+            country
+            routingnumber
+            accountnumber
+        Transfer { transferId = tid }
+           <- createTransfer rid (100 :: Amount) USD []
+        t <- getTransfer tid
+        void $ deleteRecipient rid
+        return t
+      result `shouldSatisfy` isRight
+    it "Retrieves a transfer expandable" $ do
+      result <- stripe config $ do
+        Recipient { recipientId = rid } <-
+          createRecipientByBank
+            firstname
+            lastname
+            Nothing
+            Individual
+            country
+            routingnumber
+            accountnumber
+        Transfer { transferId = tid }
+           <- createTransfer rid (100 :: Amount) USD []
+        t <- getTransferExpandable tid ["recipient", "balance_transaction"]
+        void $ deleteRecipient rid
+        return t
+      result `shouldSatisfy` isRight
+    it "Retrieves transfers" $ do
+      result <- stripe config $ getTransfers Nothing Nothing Nothing 
+      result `shouldSatisfy` isRight
+    it "Retrieves transfers expandable" $ do
+      result <- stripe config $ getTransfersExpandable Nothing Nothing Nothing
+                  [ "data.recipient"
+                  , "data.balance_transaction"
+                  ]
+      result `shouldSatisfy` isRight
+    it "Updates a transfer" $ do
+      result <- stripe config $ do
+        Recipient { recipientId = rid } <-
+          createRecipientByBank
+            firstname
+            lastname
+            Nothing
+            Individual
+            country
+            routingnumber
+            accountnumber
+        Transfer { transferId = tid }
+           <- createTransfer rid (100 :: Amount) USD []
+        t <- updateTransfer tid (Just "hey there") [("hey", "there")]
+        void $ deleteRecipient rid
+        return t
+      result `shouldSatisfy` isRight
+      let Right Transfer {..} = result
+      transferMetaData `shouldBe` [("hey", "there")]   
+      transferDescription `shouldBe` Just "hey there"
+    it "Can't Cancel a committed transfer" $ do
+      result <- stripe config $ do
+        Recipient { recipientId = rid } <-
+          createRecipientByBank
+            firstname
+            lastname
+            Nothing
+            Individual
+            country
+            routingnumber
+            accountnumber
+        Transfer { transferId = tid }
+           <- createTransfer rid (100 :: Amount) USD []
+        t <- cancelTransfer tid 
+        void $ deleteRecipient rid
+        return t
+      result `shouldSatisfy` isLeft
+  where
+    country       = Country "US"
+    routingnumber = RoutingNumber "110000000"
+    accountnumber = AccountNumber "000123456789"
+    firstname     = FirstName "David"
+    lastname      = LastName "Johnson"
+
diff --git a/tests/Test/Util.hs b/tests/Test/Util.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test/Util.hs
@@ -0,0 +1,36 @@
+module Test.Util
+       ( -- * Helpers
+         makePlanId
+       , makeCouponId
+       , secs
+       ) where
+
+import           System.Random
+import           Control.Applicative
+import qualified Data.Text as T
+import           Data.Text    (Text)
+import           Control.Monad
+
+import           Web.Stripe.Plan
+import           Web.Stripe.Coupon
+
+------------------------------------------------------------------------------
+-- | `PlanId` creation helper
+makePlanId :: IO PlanId
+makePlanId = PlanId <$> makeGuid
+
+------------------------------------------------------------------------------
+-- | `CouponId` creation helper
+makeCouponId :: IO CouponId
+makeCouponId = CouponId <$> makeGuid
+
+------------------------------------------------------------------------------
+-- | Guid Creation Helper
+makeGuid :: IO Text
+makeGuid = T.pack <$> replicateM 10 (randomRIO ('a', 'z'))
+
+------------------------------------------------------------------------------
+-- | Seconds
+secs :: Int -> Int
+secs = (*1000000)
+
