Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

v1.1.0: API tunnel + better API result validation

  • Loading branch information...
commit fc734216d508f6cfa92fcd7ba8e115476b5acdeb 1 parent c87dcab
J authored
11 README.md
View
@@ -231,11 +231,14 @@ Feel free to go wild if you are missing any features in this package. Just make
make test
-
-Roadmap
+Changelog
============
-* Separate method that tunnels all API requests to make testing easier
-* Test for data["ACK"] === Success @ createSubscription() + authenticate() to make error checking easier
+
+**v1.1.0:**
+
+* The class does now validates API results to keep you from writing `if (response["ACK"] === "Success")` to manually validate every API action.
+
+* Every API action is now tunneled through the `makeAPIrequest()`-method to make it easy to debug/unit test the class when integrating with your own code.
License
12 examples/express.coffee
View
@@ -87,8 +87,7 @@ app.get "/purchase/success", (req, res) ->
paypal.createSubscription token, payerid, params, (error, data) ->
- if !error and data["ACK"] is "Success"
-
+ if !error
# We've just turned our user into a subscribing customer. Chapeau!
# Show some links so that we can fetch some data about the subscription
# or to cancel the subscription.
@@ -118,11 +117,10 @@ app.get "/subscription/:pid/info", (req, res) ->
# Fetch subscription data based upon given PROFILEID
paypal.getSubscription pid, (error, data) ->
- if !error and data["ACK"] isnt "Failure"
- res.send "<pre>" + JSON.stringify(data, null, 4) + "</pre>"
- else
- # PayPal's API can be down or more probably, you provided an invalid PROFILEID.
- res.send "Your subscription doesn't exist or something just went wrong"
+ return res.json data if !error
+
+ res.send "Your subscription doesn't exist or we couldn't reach PayPal's API right now"
+
app.get "/subscription/:pid/cancel", (req, res) ->
94 lib/Paypal.coffee
View
@@ -90,8 +90,6 @@ class Paypal
SURVEYENABLE: 0
}, opts)
-
-
@makeAPIrequest @getParams(opts), (err, response) ->
return callback err, null, null if err
@@ -99,26 +97,6 @@ class Paypal
callback null, response, self.checkoutUrl + response["TOKEN"]
- ###
-
- request.post @endpointUrl, {form: params}, (e, r, b) ->
-
- # 1: Check if we got a network error or such
- if e
- return callback e, null, null
-
- # 2: Check if PayPal's API didn't return HTTP 200
- # If so, parse the error message and return it.
- else if r.statusCode isnt 200
- return callback querystring.parse(b), null, null
-
- # 3: No networks error and HTTP returned 200
- # Parse the data and return it to the callback
- else
- b = querystring.parse(b)
- callback null, b, self.checkoutUrl + b["TOKEN"]
- ###
-
# Creates a recurring payment profile for your customer by invoking the
# "CreateRecurringPaymentsProfile" method in the PayPal API.
#
@@ -168,34 +146,13 @@ class Paypal
# Format the date
opts["PROFILESTARTDATE"] = @_formatDate(opts["PROFILESTARTDATE"])
- #params = @getParams(opts)
-
@makeAPIrequest @getParams(opts), (err, response) ->
+
return callback err, null if err
- return callback err ? true, null unless response["ACK"] is "Success"
-
- callback null, response
-
-
- ###
- request.post @endpointUrl, {form: params}, (e, r, b) ->
-
- # 1: Check if we got a network error or such
- if e
- return callback e, null
-
- # 2: The API call didn't return HTTP 200, so parse the error
- # and invoke the callback and pass it.
- else if r.statusCode isnt 200
- return callback querystring.parse(b) ? r.statusCode, null
-
- # 3: No networks error and HTTP returned 200, so invoke our
- # callback and return the data.
- else
- callback null, querystring.parse(b)
- ###
+ return callback err ? true, null if response["ACK"] isnt "Success"
+ callback err, response
# Returns subscription information for an already created subscription by
# invoking the "GetRecurringPaymentsProfileDetails" method in the PayPal API.
@@ -221,22 +178,13 @@ class Paypal
PROFILEID: id
)
- # Do the API request
- request.post @endpointUrl, {form: params}, (e, r, b) ->
+ @makeAPIrequest params, (err, response) ->
+
+ return callback err, null if err
- # 1: Check if we got a network error or such
- if e
- return callback e, null
+ return callback err ? true, null if response["ACK"] isnt "Success"
- # 2: The API call didn't return HTTP 200, so parse the error
- # and invoke the callback and pass it.
- else if r.statusCode isnt 200
- return callback querystring.parse(b), null
-
- # 3: No networks error and HTTP returned 200, so invoke our
- # callback and return the data.
- else
- callback null, querystring.parse(b)
+ callback err, response
# Modifies the state of an existing subscription by invoking the
# ManageRecurringPaymentsProfileStatus on the PayPal API.
@@ -271,26 +219,17 @@ class Paypal
params["NOTE"] = note if typeof note is "string"
- # Do the API request
- request.post @endpointUrl, {form: params}, (e, r, b) ->
+ @makeAPIrequest params, (err, response) ->
+
+ return callback err, null if err
- # 1: Check if we got a network error or such
- if e
- return callback e, null
+ return callback err ? true, null if response["ACK"] isnt "Success"
- # 2: The API call didn't return HTTP 200, so parse the error
- # and invoke the callback and pass it.
- else if r.statusCode isnt 200
- return callback querystring.parse(b), null
-
- # 3: No networks error and HTTP returned 200, so invoke our
- # callback and return the data.
- else
- callback null, querystring.parse(b)
+ callback err, response
# Performs the actual API request to the PayPal API endpoint.
#
- # Mock this function to test this class when integrating with your
+ # Mock this function to test this class when integrating with your
# own code
#
makeAPIrequest: (params, callback) ->
@@ -305,12 +244,9 @@ class Paypal
if response.statusCode isnt 200
return callback querystring.parse(body) ? response.statusCode, null
- # Sailing smoothly. Parse body and return.
+ # Sailing smoothly. Parse query-string formatted body and return.
callback null, querystring.parse(body)
-
-
-
# Merges two objects passed as arguments.
# Note that any property in the object passed as second argument will
# overwrite any property in the object passed as first argument
3  package.json
View
@@ -2,7 +2,7 @@
"name": "paypal-recurring",
"description": "makes creating recurring payments with node.js a bit easier",
"author": "Jay Bryant <jaybryant@tormail.org>",
- "version": "1.0.0",
+ "version": "1.1.0",
"repository": "git://github.com/jaybryant/paypal-recurring",
"license": "MIT",
"main": "index",
@@ -15,7 +15,6 @@
"chai": "*",
"coffeelint": "*",
"express": "*",
- "longjohn": "*",
"mocha": "*",
"sinon": "*"
}
8 test/test.coffee
View
@@ -358,14 +358,14 @@ describe "getSubscription()", ->
it "Handles a correct/successful request properly", (done) ->
- sinon.stub request, "post", -> arguments[2](false, {statusCode: 200}, "QUERY=STRING")
+ sinon.stub request, "post", -> arguments[2](false, {statusCode: 200}, "ACK=Success")
checkoutUrl = @p.checkoutUrl
@p.getSubscription "profileid", (error, data) ->
assert.isNull error
assert.ok data
- assert.deepEqual data, QUERY: "STRING"
+ assert.deepEqual data, ACK: "Success"
done()
describe "modifySubscription()", ->
@@ -418,14 +418,14 @@ describe "modifySubscription()", ->
it "Handles a correct/successful request properly", (done) ->
- sinon.stub request, "post", -> arguments[2](false, {statusCode: 200}, "QUERY=STRING")
+ sinon.stub request, "post", -> arguments[2](false, {statusCode: 200}, "ACK=Success")
checkoutUrl = @p.checkoutUrl
@p.modifySubscription "profileid", (error, data) ->
assert.isNull error
assert.ok data
- assert.deepEqual data, QUERY: "STRING"
+ assert.deepEqual data, ACK: "Success"
done()
describe "Uses correct params", ->
Please sign in to comment.
Something went wrong with that request. Please try again.