1
1
mirror of https://github.com/n8n-io/n8n.git synced 2024-10-05 17:17:45 +03:00

payout resource done

This commit is contained in:
Ricardo Espinoza 2019-11-26 11:59:27 -05:00
parent 08c95f989c
commit eaa33e0a8d
4 changed files with 150 additions and 57 deletions

View File

@ -14,49 +14,18 @@ import {
export async function paypalApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, endpoint: string, method: string, body: any = {}, query?: IDataObject, uri?: string): Promise<any> { // tslint:disable-line:no-any
const credentials = this.getCredentials('paypalApi');
let tokenInfo;
if (credentials === undefined) {
throw new Error('No credentials got returned!');
}
// @ts-ignore
const env = {
'sanbox': 'https://api.sandbox.paypal.com',
'live': 'https://api.paypal.com'
}[credentials.env as string];
const data = new Buffer(`${credentials.clientId}:${credentials.secret}`).toString(BINARY_ENCODING);
let headerWithAuthentication = Object.assign({},
{ Authorization: `Basic ${data}`, 'Content-Type': 'application/x-www-form-urlencoded' });
let options: OptionsWithUri = {
headers: headerWithAuthentication,
method,
qs: query,
uri: `${env}/v1/oauth2/token`,
body,
json: true
};
try {
tokenInfo = await this.helpers.request!(options);
} catch (error) {
const errorMessage = error.response.body.message || error.response.body.Message;
if (errorMessage !== undefined) {
throw errorMessage;
}
throw error.response.body;
}
headerWithAuthentication = Object.assign({ },
const env = getEnviroment(credentials!.env as string);
const tokenInfo = await getAccessToken.call(this);
const headerWithAuthentication = Object.assign({ },
{ Authorization: `Bearer ${tokenInfo.access_token}`, 'Content-Type': 'application/json' });
options = {
const options = {
headers: headerWithAuthentication,
method,
qs: query,
qs: query || {},
uri: uri || `${env}/v1${endpoint}`,
body,
json: true
};
try {
return await this.helpers.request!(options);
} catch (error) {
@ -69,35 +38,74 @@ export async function paypalApiRequest(this: IHookFunctions | IExecuteFunctions
}
}
function getEnviroment(env: string): string {
// @ts-ignore
return {
'sanbox': 'https://api.sandbox.paypal.com',
'live': 'https://api.paypal.com'
}[env];
}
async function getAccessToken(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions): Promise<any> { // tslint:disable-line:no-any
const credentials = this.getCredentials('paypalApi');
if (credentials === undefined) {
throw new Error('No credentials got returned!');
}
const env = getEnviroment(credentials!.env as string);
const data = Buffer.from(`${credentials!.clientId}:${credentials!.secret}`).toString(BINARY_ENCODING);
const headerWithAuthentication = Object.assign({},
{ Authorization: `Basic ${data}`, 'Content-Type': 'application/x-www-form-urlencoded' });
const options: OptionsWithUri = {
headers: headerWithAuthentication,
method: 'POST',
form: {
grant_type: 'client_credentials',
},
uri: `${env}/v1/oauth2/token`,
json: true
};
try {
return await this.helpers.request!(options);
} catch (error) {
const errorMessage = error.response.body.message || error.response.body.Message;
if (errorMessage !== undefined) {
throw errorMessage;
}
throw error.response.body;
}
}
/**
* Make an API request to paginated intercom endpoint
* Make an API request to paginated paypal endpoint
* and return all results
*/
export async function intercomApiRequestAllItems(this: IHookFunctions | IExecuteFunctions, propertyName: string, endpoint: string, method: string, body: any = {}, query: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
export async function paypalApiRequestAllItems(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, propertyName: string, endpoint: string, method: string, body: any = {}, query?: IDataObject, uri?: string): Promise<any> { // tslint:disable-line:no-any
const returnData: IDataObject[] = [];
let responseData;
query.per_page = 60;
let uri: string | undefined;
query!.page_size = 1000;
do {
responseData = await paypalApiRequest.call(this, endpoint, method, body, query, uri);
uri = responseData.pages.next;
uri = getNext(responseData.links);
returnData.push.apply(returnData, responseData[propertyName]);
} while (
responseData.pages !== undefined &&
responseData.pages.next !== undefined &&
responseData.pages.next !== null
getNext(responseData.links) !== undefined
);
return returnData;
}
function getNext(links: IDataObject[]): string | undefined {
for (const link of links) {
if (link.rel === 'next') {
return link.href as string;
}
}
return undefined;
}
export function validateJSON(json: string | undefined): any { // tslint:disable-line:no-any
let result;

View File

@ -21,8 +21,18 @@ export const payoutOpeations = [
{
name: 'Get',
value: 'get',
description: 'Show payout item details',
},
{
name: 'Get All',
value: 'getAll',
description: 'Show payout batch details',
},
{
name: 'Delete',
value: 'delete',
description: 'Cancels an unclaimed payout item, by ID.',
},
],
default: 'create',
description: 'The operation to perform.',
@ -276,7 +286,7 @@ export const payoutFields = [
},
/* -------------------------------------------------------------------------- */
/* payout:get */
/* payout:getAll */
/* -------------------------------------------------------------------------- */
{
@ -290,7 +300,7 @@ export const payoutFields = [
'payout',
],
operation: [
'get',
'getAll',
],
},
},
@ -300,14 +310,14 @@ export const payoutFields = [
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
required: false,
default: false,
displayOptions: {
show: {
resource: [
'payout',
],
operation: [
'get',
'getAll',
],
},
},
@ -328,7 +338,7 @@ export const payoutFields = [
'payout',
],
operation: [
'get',
'getAll',
],
returnAll: [
false,
@ -337,4 +347,47 @@ export const payoutFields = [
},
description: 'If all results should be returned or only up to a given limit.',
},
/* -------------------------------------------------------------------------- */
/* payout:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Payout Item Id',
name: 'payoutItemId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: [
'payout',
],
operation: [
'get',
],
},
},
description: 'The ID of the payout item for which to show details.',
},
/* -------------------------------------------------------------------------- */
/* payout:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Payout Item Id',
name: 'payoutItemId',
type: 'string',
required: true,
displayOptions: {
show: {
resource: [
'payout',
],
operation: [
'delete',
],
},
},
description: 'The ID of the payout item to cancel.',
},
] as INodeProperties[];

View File

@ -13,7 +13,7 @@ export enum RecipientWallet {
export interface IAmount {
currency?: string;
value?: string;
value?: number;
}
export interface ISenderBatchHeader {

View File

@ -22,6 +22,7 @@ import {
import {
validateJSON,
paypalApiRequest,
paypalApiRequestAllItems
} from './GenericFunctions';
export class PayPal implements INodeType {
@ -69,8 +70,8 @@ export class PayPal implements INodeType {
const items = this.getInputData();
const returnData: IDataObject[] = [];
const length = items.length as unknown as number;
let qs: IDataObject;
let responseData;
let qs: IDataObject = {};
for (let i = 0; i < length; i++) {
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;
@ -100,10 +101,10 @@ export class PayPal implements INodeType {
const payoutItem: IItem = {};
const amount: IAmount = {};
amount.currency = o.currency as string;
amount.value = o.receiverValue as string;
amount.value = parseFloat(o.amount as string);
payoutItem.amount = amount;
payoutItem.note = o.note as string || '';
payoutItem.receiver = o.receiver as string;
payoutItem.receiver = o.receiverValue as string;
payoutItem.recipient_type = o.recipientType as RecipientType;
payoutItem.recipient_wallet = o.recipientWallet as RecipientWallet;
payoutItem.sender_item_id = o.senderItemId as string || '';
@ -111,14 +112,45 @@ export class PayPal implements INodeType {
});
body.items = payoutItems;
} else {
throw new Error('You must have at least one item.')
throw new Error('You must have at least one item.');
}
} else {
const itemsJson = validateJSON(this.getNodeParameter('itemsJson', i) as string);
body.items = itemsJson;
}
try {
responseData = await paypalApiRequest.call(this, '/payouts', 'POST', body);
responseData = await paypalApiRequest.call(this, '/payments/payouts', 'POST', body);
} catch (err) {
throw new Error(`Paypal Error: ${JSON.stringify(err)}`);
}
}
if (operation === 'get') {
const payoutItemId = this.getNodeParameter('payoutItemId', i) as string;
try {
responseData = await paypalApiRequest.call(this,`/payments/payouts-item/${payoutItemId}`, 'GET', {}, qs);
} catch (err) {
throw new Error(`Paypal Error: ${JSON.stringify(err)}`);
}
}
if (operation === 'getAll') {
const payoutBatchId = this.getNodeParameter('payoutBatchId', i) as string;
const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
try {
if (returnAll === true) {
responseData = await paypalApiRequestAllItems.call(this, 'items', `/payments/payouts/${payoutBatchId}`, 'GET', {}, qs);
} else {
qs.page_size = this.getNodeParameter('limit', i) as number;
responseData = await paypalApiRequest.call(this,`/payments/payouts/${payoutBatchId}`, 'GET', {}, qs);
responseData = responseData.items;
}
} catch (err) {
throw new Error(`Paypal Error: ${JSON.stringify(err)}`);
}
}
if (operation === 'delete') {
const payoutItemId = this.getNodeParameter('payoutItemId', i) as string;
try {
responseData = await paypalApiRequest.call(this,`/payments/payouts-item/${payoutItemId}/cancel`, 'POST', {}, qs);
} catch (err) {
throw new Error(`Paypal Error: ${JSON.stringify(err)}`);
}
@ -130,6 +162,6 @@ export class PayPal implements INodeType {
returnData.push(responseData as IDataObject);
}
}
return [this.helpers.returnJsonArray({})];
return [this.helpers.returnJsonArray(returnData)];
}
}