module Web.Stripe.Card
( Card(..)
, RequestCard(..)
, CardChecks(..)
, CardCheckResult(..)
, rCardKV
) where
import Control.Applicative ((<$>), (<*>))
import Control.Monad (mzero)
import Data.Aeson (FromJSON (..), Value (..), (.:), (.:?))
import qualified Data.ByteString as B
import qualified Data.Text as T
import Web.Stripe.Utils (optionalArgs, showByteString,
textToByteString)
data Card = Card
{ cardType :: T.Text
, cardCountry :: Maybe T.Text
, cardLastFour :: T.Text
, cardExpMonth :: Int
, cardExpYear :: Int
, cardFingerprint :: T.Text
, cardChecks :: CardChecks
} deriving Show
data RequestCard = RequestCard
{ rCardNumber :: T.Text
, rCardExpMonth :: Int
, rCardExpYear :: Int
, rCardCVC :: Maybe T.Text
, rCardFullName :: Maybe T.Text
, rCardAddrLineOne :: Maybe T.Text
, rCardAddrLineTwo :: Maybe T.Text
, rCardCity :: Maybe T.Text
, rCardAddrZip :: Maybe T.Text
, rCardAddrState :: Maybe T.Text
, rCardAddrCountry :: Maybe T.Text
} deriving Show
data CardChecks = CardChecks
{ checkCVC :: CardCheckResult
, checkAddrLineOne :: CardCheckResult
, checkZip :: CardCheckResult
} deriving Show
data CardCheckResult = NotProvided | NotChecked | Passed | Failed
deriving (Show, Eq)
rCardKV :: RequestCard -> [(B.ByteString, B.ByteString)]
rCardKV rc = fd ++ optionalArgs md
where
fd = [ ("card[number]", textToByteString $ rCardNumber rc)
, ("card[exp_month]", showByteString $ rCardExpMonth rc)
, ("card[exp_year]", showByteString $ rCardExpYear rc)
]
md = [ ("card[cvc]", textToByteString <$> rCardCVC rc)
, ("card[name]", textToByteString <$> rCardFullName rc)
, ("card[address_line1]", textToByteString <$> rCardAddrLineOne rc)
, ("card[address_line2]", textToByteString <$> rCardAddrLineTwo rc)
, ("card[address_city]", textToByteString <$> rCardCity rc)
, ("card[address_zip]", textToByteString <$> rCardAddrZip rc)
, ("card[address_state]", textToByteString <$> rCardAddrState rc)
, ("card[address_country]", textToByteString <$> rCardAddrCountry rc)
]
instance FromJSON Card where
parseJSON (Object v) = Card
<$> v .: "type"
<*> v .:? "country"
<*> v .: "last4"
<*> v .: "exp_month"
<*> v .: "exp_year"
<*> v .: "fingerprint"
<*> (CardChecks
<$> v .: "cvc_check"
<*> v .: "address_line1_check"
<*> v .: "address_zip_check"
)
parseJSON _ = mzero
instance FromJSON CardCheckResult where
parseJSON Null = return NotProvided
parseJSON (String s)
| s == "unchecked" = return NotChecked
| s == "pass" = return Passed
parseJSON _ = return Failed