module Network.IAP.Verifier
(
IAPSettings(..)
, defaultIAPSettings
, sandboxIAPSettings
, Result(..)
, IAPException(..)
, verify
) where
import Control.Exception
import Control.Monad.IO.Class
import Data.Aeson hiding (Result)
import Data.Aeson.TH
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as LBS
import qualified Data.Conduit as C
import qualified Data.Text.Encoding as T
import Data.Typeable
import Network.HTTP.Conduit
data IAPSettings = IAPSettings { verifyUrl :: String
}
deriving (Show)
defaultIAPSettings :: IAPSettings
defaultIAPSettings =
IAPSettings { verifyUrl = "https://buy.itunes.apple.com/verifyReceipt"
}
sandboxIAPSettings :: IAPSettings
sandboxIAPSettings =
defaultIAPSettings { verifyUrl = "https://sandbox.itunes.apple.com/verifyReceipt"
}
data Result = Result { status :: Int
}
deriving (Show)
$(deriveJSON defaultOptions ''Result)
data IAPException = UnknownJSONException { unUnknownJSONException :: BS.ByteString }
| NoResponseException
deriving (Show, Eq, Typeable)
instance Exception IAPException
verify :: IAPSettings -> BS.ByteString -> IO Result
verify settings receipt = do
requestRaw <- parseUrl (verifyUrl settings)
let payload = encode $ object ["receipt-data" .= (T.decodeUtf8 $
receipt)]
request = requestRaw { requestBody = RequestBodyLBS payload
, method = "POST"
}
withManager $ \manager -> do
response <- http request manager
responseBody response C.$$+- do
value <- C.await
case value of
Just x -> case decode . LBS.fromStrict $ x of
Just result -> return result
Nothing -> liftIO . throwIO $ UnknownJSONException x
Nothing -> liftIO . throwIO $ NoResponseException