module Web.MangoPay.Accounts where
import Web.MangoPay.Monad
import Web.MangoPay.Types
import Web.MangoPay.Users
import Data.Text
import Data.Text.Encoding (encodeUtf8)
import Data.Typeable (Typeable)
import Data.Aeson
import Data.Aeson.Types
import Data.Maybe (fromMaybe)
import Data.Time.Clock.POSIX (POSIXTime)
import Control.Applicative
import qualified Data.ByteString as BS
import Data.CountryCodes (CountryCode)
createAccount :: (MPUsableMonad m) => BankAccount -> AccessToken -> MangoPayT m BankAccount
createAccount ba = createGeneric path ba
where path = BS.concat ["/users/",encodeUtf8 uid,"/bankaccounts/",encodeUtf8 $ typeName $ baDetails ba]
uid = fromMaybe (error "no user provided for account") $ baUserId ba
fetchAccount :: (MPUsableMonad m) => AnyUserID -> BankAccountID -> AccessToken -> MangoPayT m BankAccount
fetchAccount uid = fetchGeneric path
where path = Data.Text.concat ["/users/",uid,"/bankaccounts/"]
listAccounts :: (MPUsableMonad m) => AnyUserID -> Maybe Pagination -> AccessToken -> MangoPayT m (PagedList BankAccount)
listAccounts uid = genericList ["/users/",uid,"/bankaccounts/"]
data BankAccountDetails=IBAN {
atIBAN :: Text
,atBIC :: Text
} | GB {
atAccountNumber :: Text
,atSortCode :: Text
} | US {
atAccountNumber :: Text
,atABA :: Text
} | CA {
atAccountNumber :: Text
,atBankName :: Text
,atInstitutionNumber :: Text
,atBranchCode :: Text
} | Other {
atAccountNumber :: Text
,atBIC :: Text
,atCountry :: CountryCode
} deriving (Show,Read,Eq,Ord,Typeable)
instance FromJSON BankAccountDetails where
parseJSON (Object v) =do
typ<-v .: "Type"
case typ of
"IBAN"->IBAN <$>
v .: "IBAN" <*>
v .: "BIC"
"GB"->GB <$>
v .: "AccountNumber" <*>
v .: "SortCode"
"US"->US <$>
v .: "AccountNumber" <*>
v .: "ABA"
"CA"->CA <$>
v .: "AccountNumber" <*>
v .: "BankName" <*>
v .: "InstitutionNumber" <*>
v .: "BranchCode"
"OTHER"->Other <$>
v .: "AccountNumber" <*>
v .: "BIC" <*>
v .: "Country"
_->fail $ "BankAccountDetails: unknown type:" ++ typ
parseJSON _=fail "BankAccountDetails"
typeName :: BankAccountDetails -> Text
typeName (IBAN {})="IBAN"
typeName (GB {})="GB"
typeName (US {})="US"
typeName (CA {})="CA"
typeName (Other {})="OTHER"
toJSONPairs :: BankAccountDetails -> [Pair]
toJSONPairs (IBAN iban bic)=["IBAN" .= iban,"BIC" .= bic]
toJSONPairs (GB nb sc)=["AccountNumber" .= nb,"SortCode" .= sc]
toJSONPairs (US nb aba)=["AccountNumber" .= nb,"ABA" .= aba]
toJSONPairs (CA nb bn inb bc)=["AccountNumber" .= nb,"BankName" .= bn,"InstitutionNumber" .= inb, "BranchCode" .= bc]
toJSONPairs (Other nb bic c)=["AccountNumber" .= nb,"BIC" .= bic,"Country" .= c]
type BankAccountID = Text
data BankAccount = BankAccount {
baId :: Maybe BankAccountID
,baCreationDate :: Maybe POSIXTime
,baUserId :: Maybe AnyUserID
,baTag :: Maybe Text
,baDetails :: BankAccountDetails
,baOwnerName :: Text
,baOwnerAddress :: Maybe Text
} deriving (Show,Eq,Ord,Typeable)
instance ToJSON BankAccount where
toJSON ba=object $ ["OwnerName" .= baOwnerName ba,"Type" .= typeName (baDetails ba)
,"OwnerAddress" .= baOwnerAddress ba, "UserId" .= baUserId ba, "Tag" .= baTag ba]
++ toJSONPairs (baDetails ba)
instance FromJSON BankAccount where
parseJSON o@(Object v) =
BankAccount <$>
v .:? "Id" <*>
v .:? "CreationDate" <*>
v .:? "UserId" <*>
v .:? "Tag" <*>
parseJSON o <*>
v .: "OwnerName" <*>
v .:? "OwnerAddress"
parseJSON _=fail "BankAccount"
data PaymentType = CARD | BANK_WIRE | AUTOMATIC_DEBIT | DIRECT_DEBIT
deriving (Show,Read,Eq,Ord,Bounded,Enum,Typeable)
instance ToJSON PaymentType where
toJSON =toJSON . show
instance FromJSON PaymentType where
parseJSON (String s)
| ((a,_):_)<-reads $ unpack s=pure a
parseJSON _ =fail "PaymentType"