module Network.PayPal.NVP (
Service,
sandbox,
live,
submit,
prepareRequest,
processResponse
) where
import Network.PayPal.Types as PayPal
import Control.Applicative
import Control.Arrow
import Control.Failure
import Control.Monad
import Control.Monad.Trans
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString.Lazy as L
import Data.Monoid
import Network.HTTP.Enumerator as HTTP
import Network.HTTP.Types as HTTP
import Web.Encodings (decodeUrlPairs)
import System.IO.Unsafe
import Data.Enumerator (Iteratee (..), run_)
import Data.Enumerator.List (consume)
import qualified Network.Wai as W
data Service = Service (HTTP.Request IO) (HTTP.Request IO)
sandbox :: Service
sandbox = Service
(unsafePerformIO $ parseUrl "https://api-3t.sandbox.paypal.com/nvp")
(unsafePerformIO $ parseUrl "https://api.sandbox.paypal.com/nvp")
live :: Service
live = Service
(unsafePerformIO $ parseUrl "https://api-3t.paypal.com/nvp")
(unsafePerformIO $ parseUrl "https://api.paypal.com/nvp")
submit :: (Failure HttpException m, MonadIO m, PayPalRequest req) =>
Service
-> Credentials
-> req
-> m (Either Response (PayPal.Status (PayPalResponse req)))
submit service cred req = do
mgr <- liftIO newManager
run_ $ httpRedirect (prepareRequest service cred req) (processResponse req) mgr
prepareRequest :: (Monad m, PayPalRequest req) =>
Service
-> Credentials
-> req
-> HTTP.Request m
prepareRequest (Service url _) (Credentials user pwd (Signature sig) version) req =
urlEncodedBody vars url
where
vars =
[("USER", user),
("PWD", pwd),
("VERSION", version),
("SIGNATURE", sig)] ++ toVariables req
processResponse :: (PayPalRequest req, Monad m) =>
req
-> HTTP.Status
-> ResponseHeaders
-> Iteratee B.ByteString m (Either Response (PayPal.Status (PayPalResponse req)))
processResponse req (Status statusCode _) headers = do
body <- L.fromChunks <$> consume
return $ case statusCode of
200 -> Right . decodeResponseChecking
. map (textify *** textify)
. decodeUrlPairs $ body
_ -> Left $ Response statusCode headers body
where
textify = mconcat . L.toChunks