diff --git a/PaymentServer.cabal b/PaymentServer.cabal
index c80b5951c0f6ad2e78b087a9cff2c9441d4ebaa1..32a86dbf00eca5d150f454aa9f02c6f8b97b77f0 100644
--- a/PaymentServer.cabal
+++ b/PaymentServer.cabal
@@ -73,9 +73,14 @@ test-suite PaymentServer-tests
   main-is:             Spec.hs
   other-modules:       Persistence
                      , Metrics
+                     , Stripe
+                     , FakeStripe
   build-depends:       base
                      , bytestring
                      , text
+                     , transformers
+                     , raw-strings-qq
+                     , time
                      , tasty
                      , tasty-hunit
                      , directory
@@ -84,6 +89,8 @@ test-suite PaymentServer-tests
                      , http-types
                      , wai
                      , wai-extra
+                     , warp
+                     , http-types
                      , servant-server
                      , prometheus-client
                      , stripe-core
diff --git a/nix/PaymentServer.nix b/nix/PaymentServer.nix
index a8df27a4643c47274a384d63fc4d6c9d8e99a530..d4e81b551156a4757acea10d7f0b4cea41900f63 100644
--- a/nix/PaymentServer.nix
+++ b/nix/PaymentServer.nix
@@ -57,10 +57,10 @@ in { system, compiler, flags, pkgs, hsPkgs, pkgconfPkgs, ... }:
       "library" = {
         depends = [
           (hsPkgs."base" or (buildDepError "base"))
-          (hsPkgs."bytestring" or (buildDepError "bytestring"))
-          (hsPkgs."utf8-string" or (buildDepError "utf8-string"))
           (hsPkgs."optparse-applicative" or (buildDepError "optparse-applicative"))
           (hsPkgs."aeson" or (buildDepError "aeson"))
+          (hsPkgs."bytestring" or (buildDepError "bytestring"))
+          (hsPkgs."utf8-string" or (buildDepError "utf8-string"))
           (hsPkgs."servant" or (buildDepError "servant"))
           (hsPkgs."servant-server" or (buildDepError "servant-server"))
           (hsPkgs."http-types" or (buildDepError "http-types"))
@@ -70,8 +70,8 @@ in { system, compiler, flags, pkgs, hsPkgs, pkgconfPkgs, ... }:
           (hsPkgs."data-default" or (buildDepError "data-default"))
           (hsPkgs."warp" or (buildDepError "warp"))
           (hsPkgs."warp-tls" or (buildDepError "warp-tls"))
-          (hsPkgs."stripe-core" or (buildDepError "stripe-core"))
           (hsPkgs."stripe-haskell" or (buildDepError "stripe-haskell"))
+          (hsPkgs."stripe-core" or (buildDepError "stripe-core"))
           (hsPkgs."text" or (buildDepError "text"))
           (hsPkgs."containers" or (buildDepError "containers"))
           (hsPkgs."cryptonite" or (buildDepError "cryptonite"))
@@ -105,6 +105,9 @@ in { system, compiler, flags, pkgs, hsPkgs, pkgconfPkgs, ... }:
             (hsPkgs."base" or (buildDepError "base"))
             (hsPkgs."bytestring" or (buildDepError "bytestring"))
             (hsPkgs."text" or (buildDepError "text"))
+            (hsPkgs."transformers" or (buildDepError "transformers"))
+            (hsPkgs."raw-strings-qq" or (buildDepError "raw-strings-qq"))
+            (hsPkgs."time" or (buildDepError "time"))
             (hsPkgs."tasty" or (buildDepError "tasty"))
             (hsPkgs."tasty-hunit" or (buildDepError "tasty-hunit"))
             (hsPkgs."directory" or (buildDepError "directory"))
@@ -113,6 +116,8 @@ in { system, compiler, flags, pkgs, hsPkgs, pkgconfPkgs, ... }:
             (hsPkgs."http-types" or (buildDepError "http-types"))
             (hsPkgs."wai" or (buildDepError "wai"))
             (hsPkgs."wai-extra" or (buildDepError "wai-extra"))
+            (hsPkgs."warp" or (buildDepError "warp"))
+            (hsPkgs."http-types" or (buildDepError "http-types"))
             (hsPkgs."servant-server" or (buildDepError "servant-server"))
             (hsPkgs."prometheus-client" or (buildDepError "prometheus-client"))
             (hsPkgs."stripe-core" or (buildDepError "stripe-core"))
@@ -121,4 +126,4 @@ in { system, compiler, flags, pkgs, hsPkgs, pkgconfPkgs, ... }:
           };
         };
       };
-    } // rec { src = (pkgs.lib).mkDefault ../.; }
+    } // rec { src = (pkgs.lib).mkDefault .././.; }
\ No newline at end of file
diff --git a/src/PaymentServer/Processors/Stripe.hs b/src/PaymentServer/Processors/Stripe.hs
index dca6457c5acc3364a4136c6539448068655d0435..2c4c7f89419d9c873e52a3a7008659ffbddfd717 100644
--- a/src/PaymentServer/Processors/Stripe.hs
+++ b/src/PaymentServer/Processors/Stripe.hs
@@ -5,8 +5,11 @@
 
 module PaymentServer.Processors.Stripe
   ( StripeAPI
+  , Charges(Charges)
+  , Acknowledgement(Ok)
   , stripeServer
   , getVoucher
+  , charge
   ) where
 
 import Control.Monad.IO.Class
@@ -50,7 +53,7 @@ import Web.Stripe.Error
 import Web.Stripe.Types
   ( Charge(Charge, chargeId)
   , MetaData(MetaData)
-  , Currency
+  , Currency(USD)
   )
 import Web.Stripe.Charge
   ( createCharge
@@ -74,7 +77,7 @@ import PaymentServer.Persistence
   , ProcessorResult
   )
 
-data Acknowledgement = Ok
+data Acknowledgement = Ok deriving (Eq, Show)
 
 instance ToJSON Acknowledgement where
   toJSON Ok = object
@@ -149,8 +152,8 @@ withSuccessFailureMetrics attemptCount successCount op = do
 -- | call the stripe Charge API (with token, voucher in metadata, amount, currency etc
 -- and if the Charge is okay, then set the voucher as "paid" in the database.
 charge :: VoucherDatabase d => StripeConfig -> d -> Charges -> Handler Acknowledgement
-charge stripeConfig d (Charges token voucher amount currency) = do
-  result <- liftIO ((payForVoucher d voucher (completeStripeCharge currency)) :: IO ProcessorResult)
+charge stripeConfig d (Charges token voucher 650 USD) = do
+  result <- liftIO ((payForVoucher d voucher (completeStripeCharge USD)) :: IO ProcessorResult)
   case result of
     Left AlreadyPaid ->
       throwError voucherAlreadyPaid
@@ -171,7 +174,7 @@ charge stripeConfig d (Charges token voucher amount currency) = do
             return . Right $ chargeId
           where
           charge =
-            createCharge (Amount amount) currency
+            createCharge (Amount 650) currency
             -&- tokenId
             -&- MetaData [("Voucher", voucher)]
 
@@ -199,13 +202,18 @@ charge stripeConfig d (Charges token voucher amount currency) = do
       stripeChargeFailed  = jsonErr 400 "Stripe charge didn't succeed"
       voucherAlreadyPaid  = jsonErr 400 "Payment for voucher already supplied"
 
-      jsonErr httpCode reason = ServerError
-        { errHTTPCode = httpCode
-        , errReasonPhrase = ""
-        , errBody = encode $ Failure reason
-        , errHeaders = [("content-type", "application/json")]
-        }
-
+-- The wrong currency
+charge _ _ (Charges _ _ 650 _) = throwError (jsonErr 400 "Unsupported currency")
+-- The wrong amount
+charge _ _ (Charges _ _ _ USD) = throwError (jsonErr 400 "Incorrect charge amount")
+
+jsonErr :: Int -> Text -> ServerError
+jsonErr httpCode reason = ServerError
+  { errHTTPCode = httpCode
+  , errReasonPhrase = ""
+  , errBody = encode $ Failure reason
+  , errHeaders = [("content-type", "application/json")]
+  }
 
 data Failure = Failure Text
   deriving (Show, Eq)
diff --git a/test/FakeStripe.hs b/test/FakeStripe.hs
new file mode 100644
index 0000000000000000000000000000000000000000..f1040b584d422074cd06b9e5af2fa411bc02c65f
--- /dev/null
+++ b/test/FakeStripe.hs
@@ -0,0 +1,153 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes #-}
+
+module FakeStripe
+  ( withFakeStripe
+  , chargeOkay
+  ) where
+
+import Text.RawString.QQ
+
+import Data.ByteString.Lazy
+   ( ByteString
+   )
+
+import Data.Time.Clock
+  ( UTCTime(UTCTime)
+  , secondsToDiffTime
+  )
+
+import Data.Time.Calendar
+  ( Day(ModifiedJulianDay)
+  )
+
+import Network.HTTP.Types
+  ( status200
+  )
+
+import Network.Wai
+  ( Application
+  , responseLBS
+  )
+
+import Network.Wai.Handler.Warp
+  ( testWithApplication
+  )
+
+import Web.Stripe.Client
+  ( StripeConfig(StripeConfig)
+  , StripeKey(StripeKey)
+  , Protocol(HTTP)
+  , Endpoint(Endpoint)
+  )
+
+aCharge :: ByteString
+aCharge = [r|
+{
+  "id": "ch_1Fwa4NBHXBAMm9bPFRPo6UBt",
+  "object": "charge",
+  "amount": 100,
+  "amount_captured": 0,
+  "amount_refunded": 0,
+  "application": null,
+  "application_fee": null,
+  "application_fee_amount": null,
+  "balance_transaction": "txn_1FrU7mBHXBAMm9bP9WvFFzRG",
+  "billing_details": {
+    "address": {
+      "city": "",
+      "country": "US",
+      "line1": "",
+      "line2": "",
+      "postal_code": "",
+      "state": "Select State"
+    },
+    "email": null,
+    "name": "",
+    "phone": null
+  },
+  "calculated_statement_descriptor": null,
+  "captured": false,
+  "created": 1577996099,
+  "currency": "usd",
+  "customer": null,
+  "description": null,
+  "disputed": false,
+  "failure_code": "card_declined",
+  "failure_message": "Your card was declined.",
+  "fraud_details": {
+    "stripe_report": "fraudulent"
+  },
+  "invoice": null,
+  "livemode": false,
+  "metadata": {
+    "Voucher": "EQwTqWXIjKF5MWMZmDYKJvbtiaVBlDecmk__bytPlK_l"
+  },
+  "on_behalf_of": null,
+  "order": null,
+  "outcome": {
+    "network_status": "not_sent_to_network",
+    "reason": "merchant_blacklist",
+    "risk_level": "highest",
+    "risk_score": 90,
+    "seller_message": "Stripe blocked this payment.",
+    "type": "blocked"
+  },
+  "paid": false,
+  "payment_intent": null,
+  "payment_method": "card_1Fwa4MBHXBAMm9bPyw1fke3O",
+  "payment_method_details": {
+    "card": {
+      "brand": "visa",
+      "checks": {
+        "address_line1_check": null,
+        "address_postal_code_check": null,
+        "cvc_check": "unavailable"
+      },
+      "country": "US",
+      "exp_month": 11,
+      "exp_year": 2022,
+      "fingerprint": "5COYv5EoHE9ZE82J",
+      "funding": "credit",
+      "installments": null,
+      "last4": "0019",
+      "network": "visa",
+      "three_d_secure": null,
+      "wallet": null
+    },
+    "type": "card"
+  },
+  "receipt_email": null,
+  "receipt_number": null,
+  "receipt_url": null,
+  "refunded": false,
+  "refunds": {
+    "object": "list",
+    "data": [],
+    "has_more": false,
+    "url": "/v1/charges/ch_1Fwa4NBHXBAMm9bPFRPo6UBt/refunds"
+  },
+  "review": null,
+  "shipping": null,
+  "source_transfer": null,
+  "statement_descriptor": null,
+  "statement_descriptor_suffix": null,
+  "status": "failed",
+  "transfer_data": null,
+  "transfer_group": null
+}
+|]
+
+-- Accept a charge creation and respond in the affirmative.
+chargeOkay :: Application
+chargeOkay req respond =
+  respond . responseLBS status200 [] $ aCharge
+
+-- Pass a Stripe-flavored configuration for a running Wai application to a
+-- function and evaluate the resulting IO action.
+withFakeStripe :: IO Application -> (StripeConfig -> IO a) -> IO a
+withFakeStripe app f =
+  testWithApplication app $ f . makeConfig
+  where
+    makeConfig = StripeConfig stripeKey . Just . Endpoint "127.0.0.1" HTTP
+    stripeKey = StripeKey "pk_test_aaaaaaaaaaaaaaaaaaaaaa"
diff --git a/test/Spec.hs b/test/Spec.hs
index e52ca131e7af29d3b094334ff21b853fe43701dd..d52d0af47659b4a5ecc4c65fae465d28007f6226 100644
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -12,11 +12,13 @@ import Test.Tasty
 
 import qualified Persistence
 import qualified Metrics
+import qualified Stripe
 
 tests :: TestTree
 tests = testGroup "Tests"
   [ Persistence.tests
   , Metrics.tests
+  , Stripe.tests
   ]
 
 main = defaultMain tests
diff --git a/test/Stripe.hs b/test/Stripe.hs
new file mode 100644
index 0000000000000000000000000000000000000000..49b2a3457c62d1f32a795add5e82df36bf982577
--- /dev/null
+++ b/test/Stripe.hs
@@ -0,0 +1,80 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | Tests related to PaymentServer.Processors.Stripe.
+
+module Stripe
+  ( tests
+  ) where
+
+import Test.Tasty
+  ( TestTree
+  , testGroup
+  )
+import Test.Tasty.HUnit
+  ( testCase
+  , assertEqual
+  )
+
+
+import Control.Monad.Trans.Except
+  ( runExceptT
+  )
+
+import Servant.Server
+  ( Handler(runHandler')
+  , ServerError(ServerError)
+  )
+
+import Web.Stripe.Types
+  ( Currency(USD, AED)
+  )
+
+import PaymentServer.Persistence
+  ( memory
+  )
+
+import PaymentServer.Processors.Stripe
+  ( Charges(Charges)
+  , Acknowledgement(Ok)
+  , charge
+
+  )
+
+import FakeStripe
+  ( withFakeStripe
+  , chargeOkay
+  )
+
+tests :: TestTree
+tests = testGroup "Stripe"
+  [ chargeTests
+  ]
+
+chargeTests :: TestTree
+chargeTests =
+  testGroup "Charges"
+  [ testCase "non-USD currency is rejected" $
+    withFakeStripe (return chargeOkay) $ \stripeConfig -> do
+      let amount = 650
+      let currency = AED
+      db <- memory
+      (Left (ServerError code _ _ _)) <- runExceptT . runHandler' $ charge stripeConfig db (Charges token voucher amount currency)
+      assertEqual "The result is an error" 400 code
+  , testCase "incorrect USD amount is rejected" $
+    withFakeStripe (return chargeOkay) $ \stripeConfig -> do
+      let amount = 649
+      let currency = USD
+      db <- memory
+      (Left (ServerError code _ _ _)) <- runExceptT . runHandler' $ charge stripeConfig db (Charges token voucher amount currency)
+      assertEqual "The result is an error" 400 code
+  , testCase "currect USD amount is accepted" $
+    withFakeStripe (return chargeOkay) $ \stripeConfig -> do
+      let amount = 650
+      let currency = USD
+      db <- memory
+      result <- runExceptT . runHandler' $ charge stripeConfig db (Charges token voucher amount currency)
+      assertEqual "The result is Ok" (Right Ok) result
+  ]
+  where
+    token = "foo"
+    voucher = "bar"