{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables, OverloadedStrings, FlexibleContexts, FlexibleInstances, PatternGuards, ConstraintKinds #-} -- | handle wallets module Web.MangoPay.Wallets where import Web.MangoPay.Monad import Web.MangoPay.Types import Web.MangoPay.Users import Data.Text import Data.Typeable (Typeable) import Data.Aeson import Data.Time.Clock.POSIX (POSIXTime) import Control.Applicative import qualified Network.HTTP.Types as HT import qualified Data.HashMap.Lazy as HM (delete) -- | create or edit a wallet storeWallet :: (MPUsableMonad m) => Wallet -> AccessToken -> MangoPayT m Wallet storeWallet w at= case wId w of Nothing-> do url<-getClientURL "/wallets" postExchange url (Just at) w Just i-> do url<-getClientURLMultiple ["/wallets/",i] let Object m=toJSON w putExchange url (Just at) (Object $ HM.delete "Currency" m) -- | fetch a wallet from its ID fetchWallet :: (MPUsableMonad m) => WalletID -> AccessToken -> MangoPayT m Wallet fetchWallet wid at=do url<-getClientURLMultiple ["/wallets/",wid] req<-getGetRequest url (Just at) ([]::HT.Query) getJSONResponse req -- | list all wallets for a given user listWallets :: (MPUsableMonad m) => AnyUserID -> Maybe Pagination -> AccessToken -> MangoPayT m (PagedList Wallet) listWallets uid mp at=do url<-getClientURLMultiple ["/users/",uid,"/wallets"] req<-getGetRequest url (Just at) (paginationAttributes mp) getJSONList req -- | create a new fund transfer createTransfer :: (MPUsableMonad m) => Transfer -> AccessToken -> MangoPayT m Transfer createTransfer t at= do url<-getClientURL "/transfers" postExchange url (Just at) t -- | fetch a transfer from its ID fetchTransfer :: (MPUsableMonad m) => TransferID -> AccessToken -> MangoPayT m Transfer fetchTransfer wid at=do url<-getClientURLMultiple ["/transfers/",wid] req<-getGetRequest url (Just at) ([]::HT.Query) getJSONResponse req -- | list transfers for a given wallet listTransactions :: (MPUsableMonad m) => WalletID -> Maybe Pagination -> AccessToken -> MangoPayT m (PagedList Transaction) listTransactions wid mp at=do url<-getClientURLMultiple ["/wallets/",wid,"/transactions"] req<-getGetRequest url (Just at) (paginationAttributes mp) getJSONList req -- | list transfer for a given user listTransactionsForUser :: (MPUsableMonad m) => AnyUserID -> Maybe Pagination -> AccessToken -> MangoPayT m (PagedList Transaction) listTransactionsForUser uid mp at=do url<-getClientURLMultiple ["/users/",uid,"/transactions"] req<-getGetRequest url (Just at) (paginationAttributes mp) getJSONList req -- | currency amount data Amount=Amount { aCurrency :: Currency ,aAmount :: Integer -- ^ all amounts should be in cents! } deriving (Show,Read,Eq,Ord,Typeable) -- | to json as per MangoPay format instance ToJSON Amount where toJSON b=object ["Currency" .= aCurrency b,"Amount" .= aAmount b] -- | from json as per MangoPay format instance FromJSON Amount where parseJSON (Object v) =Amount <$> v .: "Currency" <*> v .: "Amount" parseJSON _=fail "Amount" -- | ID of a wallet type WalletID=Text -- | a wallet data Wallet = Wallet { wId:: Maybe WalletID -- ^ The Id of the wallet ,wCreationDate :: Maybe POSIXTime -- ^ The creation date of the object ,wTag :: Maybe Text -- ^ Custom data ,wOwners :: [Text] -- ^ The owner of the wallet ,wDescription :: Text -- ^ A description of the wallet ,wCurrency :: Currency -- ^ Currency of the wallet ,wBalance :: Maybe Amount -- ^ The amount held on the wallet } deriving (Show,Eq,Ord,Typeable) -- | to json as per MangoPay format instance ToJSON Wallet where toJSON w=object ["Tag" .= wTag w,"Owners" .= wOwners w,"Description" .= wDescription w,"Currency" .= wCurrency w] -- | from json as per MangoPay format instance FromJSON Wallet where parseJSON (Object v) =Wallet <$> v .: "Id" <*> v .: "CreationDate" <*> v .:? "Tag" <*> v .: "Owners" <*> v .: "Description" <*> v .: "Currency" <*> v .: "Balance" parseJSON _=fail "Wallet" -- | ID of a transfer type TransferID=Text -- | status of a transfer data TransferStatus= Created | Succeeded | Failed deriving (Show,Read,Eq,Ord,Bounded,Enum,Typeable) -- | to json as per MangoPay format instance ToJSON TransferStatus where toJSON Created="CREATED" toJSON Succeeded="SUCCEEDED" toJSON Failed="FAILED" -- | from json as per MangoPay format instance FromJSON TransferStatus where parseJSON (String "CREATED") =pure Created parseJSON (String "SUCCEEDED") =pure Succeeded parseJSON (String "FAILED") =pure Failed parseJSON _= fail "TransferStatus" -- | transfer between wallets data Transfer = Transfer{ tId :: Maybe TransferID -- ^ Id of the transfer ,tCreationDate :: Maybe POSIXTime -- ^ The creation date of the object ,tTag :: Maybe Text -- ^ Custom data ,tAuthorId :: AnyUserID -- ^ The Id of the author ,tCreditedUserId :: Maybe AnyUserID -- ^ The Id of the user owner of the credited wallet ,tDebitedFunds :: Amount -- ^ The funds debited from the « debited wallet »DebitedFunds – Fees = CreditedFunds (amount received on wallet) ,tFees :: Amount -- ^ The fees taken on the transfer.DebitedFunds – Fees = CreditedFunds (amount received on wallet) ,tDebitedWalletID :: WalletID -- ^ The debited wallet (where the funds are held before the transfer) ,tCreditedWalletID:: WalletID -- ^ The credited wallet (where the funds will be held after the transfer) ,tCreditedFunds :: Maybe Amount -- ^ The funds credited on the « credited wallet »DebitedFunds – Fees = CreditedFunds (amount received on wallet) ,tStatus :: Maybe TransferStatus -- ^ The status of the transfer: ,tResultCode :: Maybe Text -- ^ The transaction result code ,tResultMessage :: Maybe Text -- ^ The transaction result message ,tExecutionDate :: Maybe POSIXTime -- ^ The execution date of the transfer } deriving (Show,Eq,Ord,Typeable) -- | to json as per MangoPay format instance ToJSON Transfer where toJSON t=object ["AuthorId" .= tAuthorId t,"CreditedUserId" .= tCreditedUserId t,"DebitedFunds" .= tDebitedFunds t, "Fees" .= tFees t,"DebitedWalletID" .= tDebitedWalletID t,"CreditedWalletID" .= tCreditedWalletID t, "Tag" .= tTag t] -- | from json as per MangoPay format instance FromJSON Transfer where parseJSON (Object v) =Transfer <$> v .: "Id" <*> v .: "CreationDate" <*> v .:? "Tag" <*> v .: "AuthorId" <*> v .: "CreditedUserId" <*> v .: "DebitedFunds" <*> v .: "Fees" <*> v .: "DebitedWalletId" <*> -- yes, it's ID one way, Id the other v .: "CreditedWalletId" <*> -- yes, it's ID one way, Id the other v .:? "CreditedFunds" <*> v .:? "Status" <*> v .:? "ResultCode" <*> v .:? "ResultMessage" <*> v .:? "ExecutionDate" parseJSON _=fail "Transfer" -- | type of transaction data TransactionType = PAYIN | PAYOUT | TRANSFER deriving (Show,Read,Eq,Ord,Bounded,Enum,Typeable) -- | to json as per MangoPay format instance ToJSON TransactionType where toJSON =toJSON . show -- | from json as per MangoPay format instance FromJSON TransactionType where parseJSON (String s) | ((a,_):_)<-reads $ unpack s=pure a parseJSON _ =fail "TransactionType" data TransactionNature = REGULAR -- ^ just as you created the object | REFUND -- ^ the transaction has been refunded | REPUDIATION -- ^ the transaction has been repudiated deriving (Show,Read,Eq,Ord,Bounded,Enum,Typeable) -- | to json as per MangoPay format instance ToJSON TransactionNature where toJSON =toJSON . show -- | from json as per MangoPay format instance FromJSON TransactionNature where parseJSON (String s) | ((a,_):_)<-reads $ unpack s=pure a parseJSON _ =fail "TransactionNature" type TransactionID = Text -- | any transaction data Transaction = Transaction{ txId :: Maybe TransactionID -- ^ Id of the transfer ,txCreationDate :: Maybe POSIXTime -- ^ The creation date of the object ,txTag :: Maybe Text -- ^ Custom data ,txAuthorId :: AnyUserID -- ^ The Id of the author ,txCreditedUserId :: Maybe AnyUserID -- ^ The Id of the user owner of the credited wallet ,txDebitedFunds :: Amount -- ^ The funds debited from the « debited wallet »DebitedFunds – Fees = CreditedFunds (amount received on wallet) ,txFees :: Amount -- ^ The fees taken on the transfer.DebitedFunds – Fees = CreditedFunds (amount received on wallet) ,txDebitedWalletID :: Maybe WalletID -- ^ The debited wallet (where the funds are held before the transfer) ,txCreditedWalletID:: Maybe WalletID -- ^ The credited wallet (where the funds will be held after the transfer) ,txCreditedFunds :: Maybe Amount -- ^ The funds credited on the « credited wallet »DebitedFunds – Fees = CreditedFunds (amount received on wallet) ,txStatus :: Maybe TransferStatus -- ^ The status of the transfer: ,txResultCode :: Maybe Text -- ^ The transaction result code ,txResultMessage :: Maybe Text -- ^ The transaction result message ,txExecutionDate :: Maybe POSIXTime -- ^ The execution date of the transfer ,txType :: TransactionType -- ^ The type of the transaction ,txNature :: TransactionNature -- ^ The nature of the transaction: } deriving (Show,Eq,Ord,Typeable) -- | to json as per MangoPay format instance ToJSON Transaction where toJSON t=object ["AuthorId" .= txAuthorId t,"CreditedUserId" .= txCreditedUserId t,"DebitedFunds" .= txDebitedFunds t, "Fees" .= txFees t,"DebitedWalletID" .= txDebitedWalletID t,"CreditedWalletID" .= txCreditedWalletID t, "Tag" .= txTag t,"Type" .= txType t,"Nature" .= txNature t] -- | from json as per MangoPay format instance FromJSON Transaction where parseJSON (Object v) =Transaction <$> v .: "Id" <*> v .: "CreationDate" <*> v .:? "Tag" <*> v .: "AuthorId" <*> v .: "CreditedUserId" <*> v .: "DebitedFunds" <*> v .: "Fees" <*> v .:? "DebitedWalletId" <*> -- yes, it's ID one way, Id the other v .:? "CreditedWalletId" <*> -- yes, it's ID one way, Id the other v .:? "CreditedFunds" <*> v .:? "Status" <*> v .:? "ResultCode" <*> v .:? "ResultMessage" <*> v .:? "ExecutionDate" <*> v .: "Type" <*> v .: "Nature" parseJSON _=fail "Transfer"