module Web.Payments.Cielo.Types where
import Control.Exception
import Control.Monad.Except
import Control.Monad.Reader
import Data.Aeson
import Data.Aeson.Types
import qualified Data.ByteString.Lazy as BL
import Data.Convertible
import Data.Default
import Data.Monoid ((<>))
import Data.Text (Text)
import Network.HTTP.Client
import Web.Payments.Cielo.Types.DeriveJSON
type MonadCielo m = ( MonadIO m
, MonadReader CieloConfig m
, MonadError CieloError m
)
type CieloM a = ReaderT CieloConfig (ExceptT CieloError IO) a
data CieloConfig = CieloConfig { cieloConfigMerchant :: Merchant
, cieloConfigEnvironment :: Environment
}
data CieloError
= CieloJSONError String SomeException BL.ByteString
| CieloInvalidError String HttpException (Maybe Value)
| CieloNotFoundError String HttpException
| CieloHttpException String HttpException (Maybe Value)
deriving(Show)
instance Exception CieloError where
data Merchant = Merchant { merchantId :: Text
, merchantKey :: Text
}
deriving(Read, Show, Eq)
data Environment = Environment { environmentApiUrl :: Text
, environmentApiQueryUrl :: Text
}
deriving(Read, Show, Eq)
instance Default Environment where
def = sandboxEnv
productionEnv :: Environment
productionEnv = Environment "https://api.cieloecommerce.cielo.com.br"
"https://apiquery.cieloecommerce.cielo.com.br"
sandboxEnv :: Environment
sandboxEnv = Environment "https://apisandbox.cieloecommerce.cielo.com.br"
"https://apiquerysandbox.cieloecommerce.cielo.com.br"
data PaymentProvider = PaymentProviderBradesco
| PaymentProviderBancoDoBrasil
| PaymentProviderSimulado
deriving(Read, Show, Eq)
deriveJSON ''PaymentProvider
data PaymentType = PaymentTypeCreditCard
| PaymentTypeDebitCard
| PaymentTypeElectronicTransfer
| PaymentTypeBoleto
deriving(Read, Show, Eq)
instance Default PaymentType where
def = PaymentTypeCreditCard
deriveJSON ''PaymentType
data Currency = CurrencyBRL
| CurrencyUSD
| CurrencyMXN
| CurrencyCOP
| CurrencyCLP
| CurrencyARS
| CurrencyPEN
| CurrencyEUR
| CurrencyPYN
| CurrencyUYU
| CurrencyVEB
| CurrencyVEF
| CurrencyGBP
deriving(Read, Show, Eq)
instance Default Currency where
def = CurrencyBRL
deriveJSON ''Currency
data Interval = IntervalMonthly
| IntervalBimonthly
| IntervalQuarterly
| IntervalSemiAnnual
| IntervalAnnual
deriving(Read, Show, Eq)
instance Default Interval where
def = IntervalMonthly
instance ToJSON Interval where
toJSON IntervalMonthly = "Monthly"
toJSON IntervalBimonthly = "Bimonthly"
toJSON IntervalQuarterly = "Quarterly"
toJSON IntervalSemiAnnual = "SemiAnnual"
toJSON IntervalAnnual = "Annual"
instance FromJSON Interval where
parseJSON (String m) = case m of
"Monthly" -> return IntervalMonthly
"Bimonthly" -> return IntervalBimonthly
"Quarterly" -> return IntervalQuarterly
"SemiAnnual" -> return IntervalSemiAnnual
"Annual" -> return IntervalAnnual
str -> fail ("Failed to parse Interval " <> convert str)
parseJSON (Number m) = case m of
1 -> return IntervalMonthly
2 -> return IntervalBimonthly
4 -> return IntervalQuarterly
6 -> return IntervalSemiAnnual
12 -> return IntervalAnnual
n -> fail ("Failed to parse Interval " <> show n)
parseJSON invalid = typeMismatch "Interval" invalid
data RecurrentPayment = RecurrentPayment { recurrentPaymentAuthorizeNow :: Maybe Bool
, recurrentPaymentEndDate :: Maybe Text
, recurrentPaymentStartDate :: Maybe Text
, recurrentPaymentInterval :: Maybe Interval
, recurrentPaymentRecurrentPaymentId :: Maybe Text
}
deriving(Read, Show, Eq)
instance Default RecurrentPayment where
def = RecurrentPayment { recurrentPaymentAuthorizeNow = Just True
, recurrentPaymentEndDate = Nothing
, recurrentPaymentStartDate = Nothing
, recurrentPaymentInterval = Just IntervalMonthly
, recurrentPaymentRecurrentPaymentId = Nothing
}
deriveJSON ''RecurrentPayment
data Address = Address { addressStreet :: Maybe Text
, addressNumber :: Maybe Text
, addressComplement :: Maybe Text
, addressZipCode :: Maybe Text
, addressCity :: Maybe Text
, addressState :: Maybe Text
, addressCountry :: Maybe Text
}
deriving(Read, Show, Eq)
instance Default Address where
def = Address Nothing Nothing Nothing Nothing Nothing Nothing Nothing
deriveJSON ''Address
data CreditCard = CreditCard { creditCardCardNumber :: Text
, creditCardHolder :: Text
, creditCardExpirationDate :: Text
, creditCardSecurityCode :: Maybe Text
, creditCardSaveCard :: Maybe Bool
, creditCardBrand :: Text
, creditCardCardToken :: Maybe Text
}
deriving(Read, Show, Eq)
instance Default CreditCard where
def = CreditCard "" "" "" Nothing Nothing "" Nothing
deriveJSON ''CreditCard
data Customer = Customer { customerName :: Text
, customerEmail :: Maybe Text
, customerBirthDate :: Maybe Text
, customerIdentity :: Maybe Text
, customerIdentityType :: Maybe Text
, customerAddress :: Maybe Address
, customerDeliveryAddress :: Maybe Address
}
deriving(Read, Show, Eq)
instance Default Customer where
def = Customer "" Nothing Nothing Nothing Nothing Nothing Nothing
deriveJSON ''Customer
data Payment = Payment { paymentServiceTaxAmount :: Maybe Int
, paymentInstallments :: Maybe Int
, paymentInterest :: Maybe Value
, paymentCreditCard :: Maybe CreditCard
, paymentType :: Maybe PaymentType
, paymentAmount :: Maybe Int
, paymentCapture :: Maybe Bool
, paymentAuthenticate :: Maybe Bool
, paymentRecurrent :: Maybe Bool
, paymentRecurrentPayment :: Maybe RecurrentPayment
, paymentTid :: Maybe Text
, paymentProofOfSale :: Maybe Text
, paymentAuthorizationCode :: Maybe Text
, paymentSoftDescriptor :: Maybe Text
, paymentReturnUrl :: Maybe Text
, paymentProvider :: Maybe PaymentProvider
, paymentPaymentId :: Maybe Text
, paymentReceivedDate :: Maybe Text
, paymentCapturedAmount :: Maybe Int
, paymentCapturedDate :: Maybe Text
, paymentCurrency :: Maybe Currency
, paymentCountry :: Maybe Text
, paymentReturnCode :: Maybe Text
, paymentReturnMessage :: Maybe Text
, paymentStatus :: Maybe Int
, paymentLinks :: Maybe [Value]
, paymentExtraDataCollection :: Maybe [Value]
, paymentExpirationDate :: Maybe Text
, paymentUrl :: Maybe Text
, paymentNumber :: Maybe Text
, paymentBarCodeNumber :: Maybe Text
, paymentDigitableLine :: Maybe Text
, paymentAddress :: Maybe Text
}
deriving(Read, Show, Eq)
instance Default Payment where
def = Payment { paymentServiceTaxAmount = Just 0
, paymentInstallments = Just 1
, paymentInterest = Just Null
, paymentCapture = Nothing
, paymentAuthenticate = Nothing
, paymentRecurrent = Nothing
, paymentRecurrentPayment = Nothing
, paymentCreditCard = Just def
, paymentTid = Nothing
, paymentProofOfSale = Nothing
, paymentAuthorizationCode = Nothing
, paymentSoftDescriptor = Nothing
, paymentReturnUrl = Nothing
, paymentProvider = Nothing
, paymentPaymentId = Nothing
, paymentType = Just def
, paymentAmount = Just 0
, paymentReceivedDate = Nothing
, paymentCapturedAmount = Nothing
, paymentCapturedDate = Nothing
, paymentCurrency = Nothing
, paymentCountry = Nothing
, paymentReturnCode = Nothing
, paymentReturnMessage = Nothing
, paymentStatus = Nothing
, paymentLinks = Nothing
, paymentExtraDataCollection = Nothing
, paymentExpirationDate = Nothing
, paymentUrl = Nothing
, paymentNumber = Nothing
, paymentBarCodeNumber = Nothing
, paymentDigitableLine = Nothing
, paymentAddress = Nothing
}
deriveJSON ''Payment
data Sale = Sale { saleMerchantOrderId :: Text
, saleCustomer :: Customer
, salePayment :: Payment
}
deriving(Read, Show, Eq)
deriveJSON ''Sale
data SaleUpdate = SaleUpdate { saleUpdateStatus :: Int
, saleUpdateReturnCode :: Text
, saleUpdateReturnMessage :: Text
, saleUpdateLinks :: [Value]
}
deriving(Read, Show, Eq)
deriveJSON ''SaleUpdate
data RecurrentPaymentQuery
= RecurrentPaymentQuery { recurrentPaymentQueryRecurrentPayment :: RecurrentPayment
, recurrentPaymentQueryCustomer :: Customer
}
deriving(Read, Show, Eq)
deriveJSON ''RecurrentPaymentQuery
data SalesByMerchantOrderQuery
= SalesByMerchantOrderQuery { salesByMerchantOrderQueryPayments :: [Payment]
}
deriving(Read, Show, Eq)
deriveJSON ''SalesByMerchantOrderQuery