diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2015, Matthew Wraith
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Matthew Wraith nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/lendingclub.cabal b/lendingclub.cabal
new file mode 100644
--- /dev/null
+++ b/lendingclub.cabal
@@ -0,0 +1,44 @@
+name:                lendingclub
+version:             0.1.0.0
+synopsis:            Bindings for the LendingClub marketplace API
+description:         Bindings for the LendingClub marketplace API
+homepage:            https://www.lendingclub.com/developers/lc-api.action
+license:             BSD3
+license-file:        LICENSE
+author:              Matthew Wraith
+maintainer:          wraithm@gmail.com
+copyright:           (c) 2015 Matthew Wraith
+category:            Finance
+build-type:          Simple
+cabal-version:       >=1.10
+
+source-repository head
+  type:     git
+  location: git://github.com/WraithM/lendingclub.git
+
+library
+  exposed-modules:     
+    LendingClub, 
+    LendingClub.Account, 
+    LendingClub.Listing, 
+    LendingClub.Note, 
+    LendingClub.Authorization, 
+    LendingClub.Money, 
+    LendingClub.Commands, 
+    LendingClub.Invest, 
+    LendingClub.Internal.JSON
+
+  build-depends:       
+    base >=4.8 && <4.9, 
+    text >=1.2 && <1.3, 
+    bytestring >=0.10 && <0.11, 
+    mtl >=2.2 && <2.3,
+    aeson,
+    scientific,
+    vector,
+    io-streams,
+    HsOpenSSL,
+    http-streams,
+    blaze-builder
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/LendingClub.hs b/src/LendingClub.hs
new file mode 100644
--- /dev/null
+++ b/src/LendingClub.hs
@@ -0,0 +1,44 @@
+module LendingClub
+    (
+    -- * Commands
+      invest
+    , account
+    , allListings
+    , notes
+    , listingFromNote
+
+    -- * Account
+    , Account (..)
+
+    -- * Authorization
+    , Authorization (..)
+    , InvestorId (..)
+
+    -- * Invest
+    , InvestResponse (..)
+    , ErrorMessage (..)
+    , InvestConfirmation (..)
+    , ExecutionStatus (..)
+
+    -- * Listing
+    , Listing (..)
+    , Offer (..)
+    , Credit (..)
+    , Grade (..)
+    , SubGrade (..)
+    , Purpose (..)
+
+    -- * Note
+    , Note (..)
+
+    -- * Types
+    , Money
+    ) where
+
+import           LendingClub.Account
+import           LendingClub.Authorization
+import           LendingClub.Commands
+import           LendingClub.Invest
+import           LendingClub.Listing
+import           LendingClub.Money
+import           LendingClub.Note          hiding (loanId)
diff --git a/src/LendingClub/Account.hs b/src/LendingClub/Account.hs
new file mode 100644
--- /dev/null
+++ b/src/LendingClub/Account.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE DeriveGeneric #-}
+
+module LendingClub.Account (Account (..)) where
+
+import           Data.Aeson
+
+import           GHC.Generics
+
+import           LendingClub.Authorization
+import           LendingClub.Money
+
+-- | A data structure for holding account information for LendingClub
+data Account = Account
+    { investorId           :: InvestorId
+    , availableCash        :: Money
+    , accountTotal         :: Money
+    , accruedInterest      :: Money
+    , infundingBalance     :: Money
+    , receivedInterest     :: Money
+    , receivedPrincipal    :: Money
+    , receivedLateFees     :: Maybe Money
+    , outstandingPrincipal :: Money
+    , totalNotes           :: Int
+    , totalPortfolios      :: Int
+    } deriving (Generic, Show, Eq)
+
+instance FromJSON Account where
diff --git a/src/LendingClub/Authorization.hs b/src/LendingClub/Authorization.hs
new file mode 100644
--- /dev/null
+++ b/src/LendingClub/Authorization.hs
@@ -0,0 +1,23 @@
+module LendingClub.Authorization 
+    ( Authorization (..)
+    , InvestorId (..)
+    ) where
+
+import           Control.Applicative (pure)
+import           Control.Monad       (mzero)
+
+import           Data.Aeson
+import           Data.ByteString
+import           Data.Scientific     (toBoundedInteger)
+
+newtype Authorization = Authorization
+    { authorization :: ByteString }
+    deriving (Show, Eq)
+
+newtype InvestorId = InvestorId Int
+    deriving (Show, Eq)
+
+instance FromJSON InvestorId where
+    parseJSON (Number x) = 
+        maybe mzero (pure . InvestorId) (toBoundedInteger x)
+    parseJSON _ = mzero
diff --git a/src/LendingClub/Commands.hs b/src/LendingClub/Commands.hs
new file mode 100644
--- /dev/null
+++ b/src/LendingClub/Commands.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module LendingClub.Commands
+    ( invest
+    , account
+    , allListings
+    , notes
+    , listingFromNote
+    ) where
+
+import           Data.Aeson
+import           Data.ByteString.Char8     as C
+import           Data.Functor              ((<$>))
+import           Data.Monoid               ((<>))
+import           Data.Vector               (Vector)
+import qualified Data.Vector               as V
+
+import           GHC.Generics
+
+import           LendingClub.Account
+import           LendingClub.Authorization
+import           LendingClub.Invest
+import           LendingClub.Internal.JSON
+import           LendingClub.Listing
+import           LendingClub.Note          as N
+import           LendingClub.Money
+
+invest
+    :: Authorization
+    -> InvestorId
+    -> Money
+    -> Listing
+    -> IO InvestResponse
+invest auth i amt l = investRequest auth i (listingId l) amt
+
+newtype LCListings = LCListings
+    { loans :: Vector Listing }
+    deriving Generic
+
+instance FromJSON LCListings where
+
+allListings :: Authorization -> IO (Vector Listing)
+allListings auth = loans <$> jsonGet auth "loans/listing"
+
+account :: Authorization -> InvestorId -> IO Account
+account auth (InvestorId i) =
+    jsonGet auth ("accounts/" <> C.pack (show i) <> "/summary")
+
+newtype LCNotes = LCNotes
+    { myNotes :: Vector Note }
+    deriving Generic
+
+instance FromJSON LCNotes where
+
+notes :: Authorization -> InvestorId -> IO (Vector Note)
+notes auth (InvestorId i) =
+    myNotes <$> jsonGet auth ("accounts/" <> C.pack (show i) <> "/notes")
+
+-- | Does not talk to LendingClub's listings endpoint.
+-- This uses in-memory data to retrieve listings.
+--
+-- TODO This thing is pretty much useles... Need to access historical listings
+listingFromNote :: Authorization -> Note -> IO (Maybe Listing)
+listingFromNote auth (Note { N.loanId = lid }) = do
+    listings <- allListings auth
+    return $ V.find (\l -> listingId l == lid) listings
diff --git a/src/LendingClub/Internal/JSON.hs b/src/LendingClub/Internal/JSON.hs
new file mode 100644
--- /dev/null
+++ b/src/LendingClub/Internal/JSON.hs
@@ -0,0 +1,111 @@
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-binds #-}
+
+module LendingClub.Internal.JSON
+    ( jsonGet
+--     , csvGet
+--     , csvGetStream
+    , investRequest
+    ) where
+
+import           Blaze.ByteString.Builder  (fromLazyByteString)
+import           Network.Http.Client
+import           OpenSSL
+import           System.IO.Streams         (InputStream, write)
+
+import           Control.Monad.Reader      (liftIO)
+
+import           Data.Aeson                (FromJSON, ToJSON, encode)
+import           Data.ByteString           (ByteString)
+import qualified Data.ByteString.Char8     as C
+import           Data.Monoid               ((<>))
+
+import           GHC.Generics
+
+import           LendingClub.Authorization
+import           LendingClub.Invest
+import           LendingClub.Money
+
+-- | Make a GET request to LendingClub's JSON api, return the parsed JSON data
+jsonGet
+    :: FromJSON a
+    => Authorization -- ^ The authorization for the lending club user
+    -> ByteString -- ^ The name of the API service, relative to the API url
+    -> IO a -- ^ JSON response
+jsonGet auth url = issueRequest auth url GET "application/json" jsonHandler (Nothing :: Maybe ())
+
+{- TODO Redo for LendingClub
+-- | Make a GET request to Prosper's CSV api, return the raw CSV data
+csvGet
+    :: UserInfo -- ^ The user name and password for the prosper user
+    -> ByteString -- ^ The name of the API service, relative to the API url
+    -> Prosper ByteString -- ^ Raw CSV response
+csvGet userInfo url = issueRequest userInfo url GET "text/csv" concatHandler []
+
+-- | Make a GET request to Prosper's CSV api, return the raw CSV data
+csvGetStream
+    :: UserInfo -- ^ The user name and password for the prosper user
+    -> ByteString -- ^ The name of the API service, relative to the API url
+    -> (InputStream ByteString -> IO a)
+    -> Prosper a -- ^ Raw CSV response
+csvGetStream userInfo url handler =
+    issueRequest userInfo url GET "text/csv" (\_ is -> handler is) []
+-}
+
+data InvestRequest = InvestRequest
+    { aid    :: !Int
+    , orders :: ![Order]
+    } deriving (Generic, Show)
+
+data Order = Order
+    { loanId          :: !Int
+    , requestedAmount :: !Money
+    -- , portfolioId :: !Int -- ^ Implement later
+    } deriving (Generic, Show)
+
+instance ToJSON Order where
+instance ToJSON InvestRequest where
+
+investRequest
+    :: Authorization
+    -> InvestorId
+    -> Int -- ^ The listing id
+    -> Money -- ^ Amount
+    -> IO InvestResponse -- ^ JSON response from LendingClub
+investRequest auth (InvestorId invId) listingId amount =
+    issueRequest auth ("accounts/" <> C.pack (show invId) <> "/orders") POST "application/json" jsonHandler $
+        Just InvestRequest
+            { aid = invId
+            , orders = [Order listingId amount]
+            }
+
+apiUrl :: ByteString
+apiUrl = "api.lendingclub.com"
+
+issueRequest
+    :: (FromJSON a, ToJSON b)
+    => Authorization
+    -> ByteString
+    -> Method
+    -> ContentType
+    -> (Response -> InputStream ByteString -> IO a)
+    -> Maybe b
+    -> IO a
+issueRequest (Authorization auth) url method ct handler mBody = withOpenSSL $ do
+    ctx <- baselineContextSSL
+    con <- openConnectionSSL ctx apiUrl 443
+    req <- buildRequest $ do
+        http method $ "/api/investor/v1/" <> url
+        setHeader "Authorization" auth
+        setContentType ct
+    sendRequest con req (setBody mBody)
+    resp <- receiveResponse con handler
+    closeConnection con
+    return resp
+  where
+    setBody Nothing = emptyBody
+    setBody (Just body) = write (Just (buildJSON body))
+
+    buildJSON = fromLazyByteString . encode
diff --git a/src/LendingClub/Invest.hs b/src/LendingClub/Invest.hs
new file mode 100644
--- /dev/null
+++ b/src/LendingClub/Invest.hs
@@ -0,0 +1,87 @@
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module LendingClub.Invest 
+    ( InvestResponse (..)
+    , ErrorMessage (..)
+    , InvestConfirmation (..)
+    , ExecutionStatus (..)
+    ) where
+
+import           Control.Applicative (pure, (<|>), (<$>), (<*>))
+
+import           Data.Aeson
+import           Data.Text           (Text)
+
+import           GHC.Generics
+
+import           LendingClub.Money
+
+data InvestResponse
+    = InvestResponse
+        { orderInstructId    :: Int
+        , orderConfirmations :: [InvestConfirmation]
+        }
+    | InvestError
+        { errors :: [ErrorMessage] }
+    deriving (Show, Eq)
+
+instance FromJSON InvestResponse where
+    parseJSON (Object v) =
+        InvestResponse 
+            <$> v .: "orderInstructId" 
+            <*> v .: "orderConfirmations"
+        <|> InvestError <$> v .: "errors"
+    parseJSON _ = pure (InvestError [])
+    
+data ErrorMessage = ErrorMessage
+    { field   :: Text
+    , code    :: Text
+    , message :: Text
+    } deriving (Generic, Show, Eq)
+
+instance FromJSON ErrorMessage where
+
+data InvestConfirmation = InvestConfirmation
+    { loanId          :: Int
+    , requestedAmount :: Money
+    , investedAmount  :: Money
+    , executionStatus :: [ExecutionStatus]
+    } deriving (Generic, Show, Eq)
+
+instance FromJSON InvestConfirmation where
+
+data ExecutionStatus
+    = OrderFulfilled
+    | LoanAmountExceeded
+    | NotAnInfundingLoan
+    | RequestedAmountLow
+    | RequestedAmountRounded
+    | AugmentedByMerge
+    | ElimByMerge
+    | InsufficientCash
+    | NotAnInvestor
+    | NotAValidInvestment
+    | NoteAddedToPortfolio
+    | NotAValidPortfolio
+    | ErrorAddingNoteToPortfolio
+    | SystemBusy
+    | UnknownError
+    deriving (Show, Eq)
+
+instance FromJSON ExecutionStatus where
+    parseJSON (String "ORDER_FULFILLED") = pure OrderFulfilled
+    parseJSON (String "LOAN_AMNT_EXCEEDED") = pure LoanAmountExceeded
+    parseJSON (String "NOT_AN_INFUNDING_LOAN") = pure NotAnInfundingLoan
+    parseJSON (String "REQUESTED_AMNT_LOW") = pure RequestedAmountLow
+    parseJSON (String "REQUESTED_AMNT_ROUNDED") = pure RequestedAmountRounded
+    parseJSON (String "AUGMENTED_BY_MERGE") = pure AugmentedByMerge
+    parseJSON (String "ELIM_BY_MERGE") = pure ElimByMerge
+    parseJSON (String "INSUFFICIENT_CASH") = pure InsufficientCash
+    parseJSON (String "NOT_AN_INVESTOR") = pure NotAnInvestor
+    parseJSON (String "NOT_A_VALID_INVESTMENT") = pure NotAValidInvestment
+    parseJSON (String "NOTE_ADDED_TO_PORTFOLIO") = pure NoteAddedToPortfolio
+    parseJSON (String "NOT_A_VALID_PORTFOLIO") = pure NotAValidPortfolio
+    parseJSON (String "ERROR_ADDING_NOTE_TO_PORTFOLIO") = pure ErrorAddingNoteToPortfolio
+    parseJSON (String "SYSTEM_BUSY") = pure SystemBusy
+    parseJSON _ = pure UnknownError
diff --git a/src/LendingClub/Listing.hs b/src/LendingClub/Listing.hs
new file mode 100644
--- /dev/null
+++ b/src/LendingClub/Listing.hs
@@ -0,0 +1,206 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE OverloadedStrings  #-}
+
+module LendingClub.Listing
+    ( Listing (..)
+    , Offer (..)
+    , Credit (..)
+    , Grade (..)
+    , SubGrade (..)
+    , Purpose (..)
+    ) where
+
+import           Control.Applicative
+import           Control.Monad       (mzero)
+
+import           Data.Aeson
+import           Data.Typeable
+
+import           GHC.Generics
+
+import           LendingClub.Money
+
+data Listing = Listing
+    { listingId    :: !Int
+
+    , listingGrade :: !Grade -- ^ analogous to ProsperRating
+    , subGrade     :: !SubGrade -- ^ maybe analogous to score?
+    , purpose      :: !Purpose -- ^ "purpose" in the API
+
+    -- Market data
+    , fundedAmount :: !Money
+
+    , offer        :: !Offer -- ^ Contract data
+    , credit       :: !Credit -- ^ Credit data
+    } deriving Show
+
+-- | Two listings are equivalent if their serial numbers are equal
+instance Eq Listing where
+    (Listing { listingId = id1 }) == (Listing { listingId = id2 }) =
+        id1 == id2
+
+-- | Data related to the listing's offer and contract terms
+data Offer = Offer
+    { requestAmount :: !Money
+    , rate          :: !Double -- ^ Interest rate for the borrower
+    , termInMonths  :: !Int -- ^ Integer number of months
+    } deriving Show
+--     estimatedLossRate :: Double -- Maybe Money?
+--     estimatedReturn :: Double -- Maybe Money?
+--     startDate       :: Date -- Add dates later
+--     creationDate    :: Date
+--     verificationStage :: Maybe Int -- Don't know what VerificationStage is...
+--     Add WholeLoanStartDate and WholeLoanEndDate
+
+-- | Data related to the credibility of the listing
+data Credit = Credit
+    { fico                     :: !Int
+    , bankcardUtilization      :: !Double
+    , isHomeowner              :: !Bool
+    , debtToIncome             :: !Double
+    , monthsEmployed           :: !(Maybe Int)
+    , currentDelinquencies     :: !(Maybe Int)
+    , amountDelinquent         :: !(Maybe Money)
+    , openCreditLines          :: !(Maybe Int)
+    , totOpenRevolvingAccts    :: !(Maybe Int)
+    , revolvingBalance         :: !(Maybe Money)
+    , revolvingAvailableCredit :: !(Maybe Int) -- ^ Percent
+    } deriving Show
+--     firstCreditLine :: Date
+--     creditLinesLast7Years :: Int
+--     inquiriesLast6Months :: Int
+--     delinquenciesLast7Years :: Int -- These are maybe too specific to Prosper
+--     publicRecordsLast10Years :: Int
+--     oldestTradeOpenDate :: Date
+
+-- TODO Need to compare nullables to Prosper's nullables
+instance FromJSON Listing where
+    parseJSON (Object v) = Listing
+            <$> v .: "id"
+
+            -- Lending club specific data
+            <*> v .: "grade"
+            <*> v .: "subGrade"
+            <*> v .: "purpose"
+
+            -- Market data
+            <*> v .: "fundedAmount"
+
+            <*> (Offer
+            <$> v .: "loanAmount"
+            <*> v .: "intRate" -- Interest Rate, might not be the same as "borrower rate"
+            <*> v .: "term")
+
+            <*> (Credit
+            <$> v .: "ficoRangeLow" -- Choose the low-end of the FICO range
+            <*> v .: "bcUtil"
+            <*> (lcHomeowner <$> v .: "homeOwnership")
+            <*> v .: "dti"
+            <*> v .:? "empLength"
+            <*> v .:? "accNowDelinq"
+            <*> v .:? "delinqAmnt"
+            <*> v .:? "openAcc" -- TODO check if "open credit lines" is the same as in Prosper
+            <*> v .:? "numRevAccts"
+            <*> v .:? "revolBal"
+            <*> v .:? "revolUtil" -- TODO check if this is the same as in Prosper
+            )
+    parseJSON _ = mzero
+
+data Homeownership
+    = RENT
+    | OWN
+    | MORTGAGE
+    | OTHER
+    deriving (Show, Eq, Typeable, Generic)
+
+instance FromJSON Homeownership where
+
+lcHomeowner :: Homeownership -> Bool
+lcHomeowner OWN = True
+lcHomeowner MORTGAGE = True -- TODO This is debatable... We should think about this
+lcHomeowner _ = False
+
+data Grade
+    = G
+    | F
+    | E
+    | D
+    | C
+    | B
+    | A
+    deriving (Show, Eq, Ord, Typeable, Generic, Read, Enum)
+
+instance FromJSON Grade where
+instance ToJSON Grade where
+
+data SubGrade
+    = G5
+    | G4
+    | G3
+    | G2
+    | G1
+    | F5
+    | F4
+    | F3
+    | F2
+    | F1
+    | E5
+    | E4
+    | E3
+    | E2
+    | E1
+    | D5
+    | D4
+    | D3
+    | D2
+    | D1
+    | C5
+    | C4
+    | C3
+    | C2
+    | C1
+    | B5
+    | B4
+    | B3
+    | B2
+    | B1
+    | A5
+    | A4
+    | A3
+    | A2
+    | A1
+    deriving (Show, Eq, Ord, Typeable, Generic, Read, Enum)
+
+instance FromJSON SubGrade where
+
+data Purpose
+    = DebtConsolidation
+    | Medical
+    | HomeImprovement
+    | RenewableEnergy
+    | SmallBusiness
+    | Wedding
+    | Vacation
+    | Moving
+    | House
+    | Car
+    | MajorPurchase
+    | CreditCard
+    | Other
+    deriving (Show, Eq, Read)
+
+instance FromJSON Purpose where
+    parseJSON (String "debt_consolidation") = pure DebtConsolidation
+    parseJSON (String "medical") = pure Medical
+    parseJSON (String "home_improvement") = pure HomeImprovement
+    parseJSON (String "renewable_energy") = pure RenewableEnergy
+    parseJSON (String "small_business") = pure SmallBusiness
+    parseJSON (String "wedding") = pure Wedding
+    parseJSON (String "vacation") = pure Vacation
+    parseJSON (String "moving") = pure Moving
+    parseJSON (String "house") = pure House
+    parseJSON (String "car") = pure Car
+    parseJSON (String "major_purchase") = pure MajorPurchase
+    parseJSON (String "credit_card") = pure CreditCard
+    parseJSON _ = pure Other
diff --git a/src/LendingClub/Money.hs b/src/LendingClub/Money.hs
new file mode 100644
--- /dev/null
+++ b/src/LendingClub/Money.hs
@@ -0,0 +1,3 @@
+module LendingClub.Money where
+
+type Money = Double
diff --git a/src/LendingClub/Note.hs b/src/LendingClub/Note.hs
new file mode 100644
--- /dev/null
+++ b/src/LendingClub/Note.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE DeriveGeneric #-}
+
+module LendingClub.Note (Note (..)) where
+
+import           Data.Aeson
+import           Data.Text           (Text)
+
+import           GHC.Generics
+
+import           LendingClub.Listing (Grade (..))
+import           LendingClub.Money
+
+data Note = Note
+    { loanId           :: Int
+    , noteId           :: Int
+    , orderId          :: Int
+    , interestRate     :: Double
+    , loanLength       :: Int -- Term
+    , loanStatus       :: Text -- Check if should be an ADT
+    , grade            :: Grade
+    , loanAmount       :: Money
+    , noteAmount       :: Money
+    , paymentsReceived :: Money
+    } deriving (Generic, Show, Eq)
+    -- , issueDate :: Time
+    -- , orderDate :: Time
+    -- , loanStatusDate :: Time
+
+instance FromJSON Note where
