Skip to content

Instantly share code, notes, and snippets.

@bluepnume
Created June 15, 2017 18:14
Show Gist options
  • Save bluepnume/3d0c8284e270c5b80926c981e9462655 to your computer and use it in GitHub Desktop.
Save bluepnume/3d0c8284e270c5b80926c981e9462655 to your computer and use it in GitHub Desktop.
'use strict';
const request = require('request-promise');
const ENV = 'sandbox';
const CLIENT_ID = 'AZDxjDScFpQtjWTOUtWKbyN_bDt4OgqaF4eYXlewfBP4-8aqX3PiV8e1GWU6liB2CUXlkA59kJXE7M6R';
const PAYPAL_URL = (ENV === 'sandbox')
? 'https://www.sandbox.paypal.com'
: 'https://www.paypal.com';
const PAYPAL_API = (ENV === 'sandbox')
? 'https://api.sandbox.paypal.com'
: 'https://api.paypal.com';
const AUTH_API = `${PAYPAL_API}/v1/oauth2/token`;
const PAYMENT_API = `${PAYPAL_API}/v1/payments/payment`;
const EXPERIENCE_API = `${PAYPAL_API}/v1/payment-experience/web-profiles`;
const CHECKOUT_URL = `${PAYPAL_URL}/checkoutnow`;
function createAccessToken(clientID) {
if (!clientID) {
throw new Error(`Client ID not found for env: ${env}`);
}
let basicAuth = new Buffer(`${clientID}:`).toString('base64');
return request({
method: `post`,
uri: AUTH_API,
headers: {
Authorization: `Basic ${basicAuth}`
},
form: {
grant_type: `client_credentials`
},
json: true
}).then(res => {
if (res && res.error === 'invalid_client') {
throw new Error(`Auth Api invalid ${env} client id: ${clientID}:\n\n${JSON.stringify(res, null, 4)}`);
}
if (!res || !res.access_token) {
throw new Error(`Auth Api response error:\n\n${JSON.stringify(res, null, 4)}`);
}
return res.access_token;
});
}
function createExperienceProfile(clientID, experience) {
if (!clientID) {
throw new Error(`Client ID not found for env: ${env}`);
}
experience.temporary = true;
experience.name = experience.name ? `${experience.name}_${Math.random().toString()}` : Math.random().toString();
return createAccessToken(clientID).then(accessToken => {
return request({
method: `post`,
uri: EXPERIENCE_API,
headers: {
Authorization: `Bearer ${accessToken}`
},
body: experience,
json: true
});
}).then(res => {
if (res && res.error) {
throw new Error(res.error);
}
if (!res.id) {
throw new Error(`No id in experience profile response:\n\n${JSON.stringify(res, null, 4)}`);
}
return res.id;
});
}
function createPayment(clientID, opts) {
let payment = opts.payment;
let experience = opts.experience;
if (!clientID) {
throw new Error(`Client ID not passed`);
}
if (!payment) {
throw new Error(`Expected payment details to be passed`);
}
payment.intent = payment.intent || 'sale';
payment.payer = payment.payer || {};
payment.payer.payment_method = payment.payer.payment_method || 'paypal';
return createAccessToken(clientID).then(accessToken => {
return Promise.resolve().then(() => {
if (experience) {
return createExperienceProfile(clientID, experience);
}
}).then(experienceID => {
if (experienceID) {
payment.experience_profile_id = experienceID;
}
let headers = {
Authorization: `Bearer ${accessToken}`
};
return request({
method: `post`,
uri: PAYMENT_API,
headers,
body: payment,
json: true
});
});
}).then(res => {
if (res && res.id) {
return res.id;
}
throw new Error(`Payment Api response error:\n\n${JSON.stringify(res, null, 4)}`);
});
}
createPayment(CLIENT_ID, {
payment: {
transactions: [
{
amount: { total: '0.01', currency: 'USD' }
}
],
redirect_urls: {
return_url: 'https://google.com',
cancel_url: 'https://google.com'
}
},
experience: {
input_fields: {
no_shipping: 1
}
}
}).then(paymentID => {
console.log(`${CHECKOUT_URL}?token=${paymentID}`)
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment