Skip to content
This repository has been archived by the owner on May 12, 2020. It is now read-only.

Commit

Permalink
Merge branch 'subscription_apis'
Browse files Browse the repository at this point in the history
Add subscription api support to sdks. Resolves #3 and closes #38.
  • Loading branch information
avidas committed Jul 16, 2014
2 parents 18ec527 + f962367 commit bb989f1
Show file tree
Hide file tree
Showing 21 changed files with 1,100 additions and 279 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,14 @@ To write an app using the SDK
// Logout url
paypal_sdk.openid_connect.logout_url("Replace with tokeninfo.id_token");
```
* For creating [Subscription Payments](https://developer.paypal.com/docs/integration/direct/create-billing-plan/), check out the [samples](/samples/subscription) for creating planned sets of future recurring payments at periodic intervals.

* To create [Future Payments](https://developer.paypal.com/docs/integration/mobile/make-future-payment/), check out this [sample](/samples/payment/create_future_payment.js) for executing future payments for a customer who has granted consent on a mobile device.

* For [Invoicing](https://developer.paypal.com/webapps/developer/docs/api/#invoicing), check out the [samples](/samples/invoice/) to see how you can use the node sdk to create, send and manage invoices.

## Running Samples
Instructions for running samples are located in the [sample directory] (https://github.com/Runnable/rest-api-sdk-nodejs/tree/master/samples). Try these samples in a live sandbox environment:
Instructions for running samples are located in the [sample directory](https://github.com/Runnable/rest-api-sdk-nodejs/tree/master/samples). Try these samples in a live sandbox environment:

<a href="https://runnable.com/paypal" target="_blank"><img src="https://runnable.com/external/styles/assets/runnablebtn.png" style="width:67px;height:25px;"></a>

Expand Down
77 changes: 71 additions & 6 deletions lib/paypal-rest-sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var uuid = require('node-uuid');

module.exports = function () {

var sdk_version = '0.9.3';
var sdk_version = '0.10.0';
var user_agent = 'PayPalSDK/rest-sdk-nodejs ' + sdk_version + ' (node ' + process.version + '-' + process.arch + '-' + process.platform + ')';
var default_options = {
'mode': 'sandbox',
Expand Down Expand Up @@ -73,7 +73,9 @@ module.exports = function () {
}

function configure(options) {
default_options = merge(default_options, options);
if (options !== undefined && typeof options === 'object') {
default_options = merge(default_options, options);
}
}

function generate_token(config, cb) {
Expand Down Expand Up @@ -235,21 +237,25 @@ module.exports = function () {
res.on('end', function () {
var err = null;

response.httpStatusCode = res.statusCode;

try {

//Set response to be parsed JSON object if data received is json
//expect that content-type header has application/json when it
//returns data
if (res.headers['content-type'] === "application/json") {
response = JSON.parse(response);
}
//Set response to an empty object if no data was received
if (response === '') {
response = {};
}
response.httpStatusCode = res.statusCode;

//TURN NODE_ENV to development to get access to paypal-debug-id
//for questions to merchant technical services. Similar convention
//to express.js
if (res.headers['paypal-debug-id'] !== undefined && process.env.NODE_ENV === 'development') {
console.log(res.headers['paypal-debug-id']);
}

} catch (e) {
err = new Error('Invalid JSON Response Received');
err.error = {
Expand Down Expand Up @@ -385,6 +391,7 @@ module.exports = function () {
configure: function (options) {
configure(options);
},
configuration: default_options,
generate_token: function (config, cb) {
generate_token(config, cb);
},
Expand All @@ -396,6 +403,10 @@ module.exports = function () {
executeHttp('GET', '/v1/payments/payment/' + payment_id, {}, config, cb);
},
list: function (data, config, cb) {
if (typeof data === 'function') {
config = data;
data = {};
}
executeHttp('GET', '/v1/payments/payment', data, config, cb);
},
execute: function (payment_id, data, config, cb) {
Expand Down Expand Up @@ -437,6 +448,60 @@ module.exports = function () {
executeHttp('GET', '/v1/payments/capture/' + capture_id, {}, config, cb);
}
},
billing_plan: {
create: function (data, config, cb) {
executeHttp('POST', '/v1/payments/billing-plans/', data, config, cb);
},
get: function (plan_id, config, cb) {
executeHttp('GET', '/v1/payments/billing-plans/' + plan_id, {}, config, cb);
},
list: function (data, config, cb) {
if (typeof data === 'function') {
config = data;
data = {};
}
executeHttp('GET', '/v1/payments/billing-plans', data, config, cb);
},
update: function (plan_id, data, config, cb) {
executeHttp('PATCH', '/v1/payments/billing-plans/' + plan_id, data, config, cb);
}
},
billing_agreement: {
create: function (data, config, cb) {
executeHttp('POST', '/v1/payments/billing-agreements', data, config, cb);
},
get: function (agreement_id, config, cb) {
executeHttp('GET', '/v1/payments/billing-agreements/' + agreement_id, {}, config, cb);
},
update: function (agreement_id, data, config, cb) {
executeHttp('PATCH', '/v1/payments/billing-agreements/' + agreement_id, data, config, cb);
},
execute: function (payment_token, data, config, cb) {
executeHttp('POST', '/v1/payments/billing-agreements/' + payment_token + '/agreement-execute', data, config, cb);
},
suspend: function (agreement_id, data, config, cb) {
executeHttp('POST', '/v1/payments/billing-agreements/' + agreement_id + '/suspend', data, config, cb);
},
cancel: function (agreement_id, data, config, cb) {
executeHttp('POST', '/v1/payments/billing-agreements/' + agreement_id + '/cancel', data, config, cb);
},
reactivate: function (agreement_id, data, config, cb) {
executeHttp('POST', '/v1/payments/billing-agreements/' + agreement_id + '/re-activate', data, config, cb);
},
bill_balance: function (agreement_id, data, config, cb) {
executeHttp('POST', '/v1/payments/billing-agreements/' + agreement_id + '/bill-balance', data, config, cb);
},
set_balance: function (agreement_id, data, config, cb) {
executeHttp('POST', '/v1/payments/billing-agreements/' + agreement_id + '/set-balance', data, config, cb);
},
search_transactions: function (agreement_id, start_date, end_date, config, cb) {
var date_range = {
"start-date": start_date,
"end-date": end_date
};
executeHttp('GET', '/v1/payments/billing-agreements/' + agreement_id + '/transaction', date_range, config, cb);
}
},
credit_card: {
create: function (data, config, cb) {
executeHttp('POST', '/v1/vault/credit-card/', data, config, cb);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"author": "PayPal <DL-PP-NODEJS-SDK@ebay.com> (https://developer.paypal.com/)",
"name": "paypal-rest-sdk",
"description": "SDK for PayPal REST APIs",
"version": "0.9.3",
"version": "0.10.0",
"homepage": "https://github.com/paypal/rest-api-sdk-nodejs",
"keywords": [
"paypal",
Expand Down
30 changes: 30 additions & 0 deletions samples/subscription/billing_agreements/cancel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* Copyright 2014 PayPal */
"use strict";

var paypal_api = require('../../../');
require('../../configure');

var billingAgreementId = "I-08413VDRU6DE";

var cancel_note = {
"note": "Canceling the agreement"
};

paypal_api.billing_agreement.cancel(billingAgreementId, cancel_note, function (error, response) {
if (error) {
console.log(error);
throw error;
} else {
console.log("Cancel Billing Agreement Response");
console.log(response);

paypal_api.billing_plan.get(billingAgreementId, function (error, billingPlan) {
if (error) {
console.log(error.response);
throw error;
} else {
console.log(billingPlan.state);
}
});
}
});
160 changes: 160 additions & 0 deletions samples/subscription/billing_agreements/create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/* Copyright 2014 PayPal
Create a billing plan, activate it and use it to create a billing Agreement.
*/
"use strict";

var paypal_api = require('../../../');
require('../../configure');
var url = require('url');

var billingPlanAttributes = {
"description": "Create Plan for Regular",
"merchant_preferences": {
"auto_bill_amount": "yes",
"cancel_url": "http://www.cancel.com",
"initial_fail_amount_action": "continue",
"max_fail_attempts": "1",
"return_url": "http://www.success.com",
"setup_fee": {
"currency": "USD",
"value": "25"
}
},
"name": "Testing1-Regular1",
"payment_definitions": [
{
"amount": {
"currency": "USD",
"value": "100"
},
"charge_models": [
{
"amount": {
"currency": "USD",
"value": "10.60"
},
"type": "SHIPPING"
},
{
"amount": {
"currency": "USD",
"value": "20"
},
"type": "TAX"
}
],
"cycles": "0",
"frequency": "MONTH",
"frequency_interval": "1",
"name": "Regular 1",
"type": "REGULAR"
},
{
"amount": {
"currency": "USD",
"value": "20"
},
"charge_models": [
{
"amount": {
"currency": "USD",
"value": "10.60"
},
"type": "SHIPPING"
},
{
"amount": {
"currency": "USD",
"value": "20"
},
"type": "TAX"
}
],
"cycles": "4",
"frequency": "MONTH",
"frequency_interval": "1",
"name": "Trial 1",
"type": "TRIAL"
}
],
"type": "INFINITE"
};

var billingPlanUpdateAttributes = [
{
"op": "replace",
"path": "/",
"value": {
"state": "ACTIVE"
}
}
];

var billingAgreementAttributes = {
"name": "Fast Speed Agreement",
"description": "Agreement for Fast Speed Plan",
"start_date": "2015-02-19T00:37:04Z",
"plan": {
"id": "P-0NJ10521L3680291SOAQIVTQ"
},
"payer": {
"payment_method": "paypal"
},
"shipping_address": {
"line1": "StayBr111idge Suites",
"line2": "Cro12ok Street",
"city": "San Jose",
"state": "CA",
"postal_code": "95112",
"country_code": "US"
}
};

// Create the billing plan
paypal_api.billing_plan.create(billingPlanAttributes, function (error, billingPlan) {
if (error) {
console.log(error);
throw error;
} else {
console.log("Create Billing Plan Response");
console.log(billingPlan);

// Activate the plan by changing status to Active
paypal_api.billing_plan.update(billingPlan.id, billingPlanUpdateAttributes, function (error, response) {
if (error) {
console.log(error);
throw error;
} else {
console.log("Billing Plan state changed to " + billingPlan.state);
billingAgreementAttributes.plan.id = billingPlan.id;

// Use activated billing plan to create agreement
paypal_api.billing_agreement.create(billingAgreementAttributes, function (error, billingAgreement) {
if (error) {
console.log(error);
throw error;
} else {
console.log("Create Billing Agreement Response");
//console.log(billingAgreement);
for (var index = 0; index < billingAgreement.links.length; index++) {
if (billingAgreement.links[index].rel === 'approval_url') {
var approval_url = billingAgreement.links[index].href;
console.log("For approving subscription via Paypal, first redirect user to");
console.log(approval_url);

console.log("Payment token is");
console.log(url.parse(approval_url, true).query.token);
// See billing_agreements/execute.js to see example for executing agreement
// after you have payment token
}
}
}
});
}
});
}
});


27 changes: 27 additions & 0 deletions samples/subscription/billing_agreements/execute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* Copyright 2014 PayPal
Execute a billing agreement after it has been created. See
billing_agreements/create.js to see a sample for creating an
agreement.
*/
"use strict";

var paypal_api = require('../../../');
require('../../configure');

var paymentToken = '';

//Retrieve payment token appended as a parameter to the redirect_url specified in
//billing plan was created. It could also be saved in the user session
paymentToken = 'EC-2V0782854X675410W';

paypal_api.billing_agreement.execute(paymentToken, {}, function (error, billingAgreement) {
if (error) {
console.log(error);
throw error;
} else {
console.log("Billing Agreement Execute Response");
console.log(JSON.stringify(billingAgreement));
}
});
17 changes: 17 additions & 0 deletions samples/subscription/billing_agreements/get.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* Copyright 2014 PayPal */
"use strict";

var paypal_api = require('../../../');
require('../../configure');

var billingAgreementId = "I-08413VDRU6DE";

paypal_api.billing_agreement.get(billingAgreementId, function (error, billingAgreement) {
if (error) {
console.log(error);
throw error;
} else {
console.log("Get Billing Agreement");
console.log(JSON.stringify(billingAgreement));
}
});

0 comments on commit bb989f1

Please sign in to comment.