mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
🔀 Merge branch 'RicardoE105-feature/paypal-node'
This commit is contained in:
commit
6214ce57ec
40
packages/nodes-base/credentials/PayPalApi.credentials.ts
Normal file
40
packages/nodes-base/credentials/PayPalApi.credentials.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import {
|
||||||
|
ICredentialType,
|
||||||
|
NodePropertyTypes,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
|
||||||
|
export class PayPalApi implements ICredentialType {
|
||||||
|
name = 'payPalApi';
|
||||||
|
displayName = 'PayPal API';
|
||||||
|
properties = [
|
||||||
|
{
|
||||||
|
displayName: 'Client ID',
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'string' as NodePropertyTypes,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Secret',
|
||||||
|
name: 'secret',
|
||||||
|
type: 'string' as NodePropertyTypes,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Enviroment',
|
||||||
|
name: 'env',
|
||||||
|
type: 'options' as NodePropertyTypes,
|
||||||
|
default: 'live',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Sanbox',
|
||||||
|
value: 'sanbox'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Live',
|
||||||
|
value: 'live'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
119
packages/nodes-base/nodes/PayPal/GenericFunctions.ts
Normal file
119
packages/nodes-base/nodes/PayPal/GenericFunctions.ts
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
import { OptionsWithUri } from 'request';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
IHookFunctions,
|
||||||
|
ILoadOptionsFunctions,
|
||||||
|
IExecuteSingleFunctions,
|
||||||
|
BINARY_ENCODING
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
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');
|
||||||
|
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' });
|
||||||
|
const options = {
|
||||||
|
headers: headerWithAuthentication,
|
||||||
|
method,
|
||||||
|
qs: query || {},
|
||||||
|
uri: uri || `${env}/v1${endpoint}`,
|
||||||
|
body,
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 paypal endpoint
|
||||||
|
* and return all results
|
||||||
|
*/
|
||||||
|
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!.page_size = 1000;
|
||||||
|
|
||||||
|
do {
|
||||||
|
responseData = await payPalApiRequest.call(this, endpoint, method, body, query, uri);
|
||||||
|
uri = getNext(responseData.links);
|
||||||
|
returnData.push.apply(returnData, responseData[propertyName]);
|
||||||
|
} while (
|
||||||
|
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;
|
||||||
|
try {
|
||||||
|
result = JSON.parse(json!);
|
||||||
|
} catch (exception) {
|
||||||
|
result = '';
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
178
packages/nodes-base/nodes/PayPal/PayPal.node.ts
Normal file
178
packages/nodes-base/nodes/PayPal/PayPal.node.ts
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
INodeTypeDescription,
|
||||||
|
INodeExecutionData,
|
||||||
|
INodeType,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
import {
|
||||||
|
payoutOperations,
|
||||||
|
payoutItemOperations,
|
||||||
|
payoutFields,
|
||||||
|
payoutItemFields,
|
||||||
|
} from './PaymentDescription';
|
||||||
|
import {
|
||||||
|
IPaymentBatch,
|
||||||
|
ISenderBatchHeader,
|
||||||
|
IItem, IAmount,
|
||||||
|
RecipientType,
|
||||||
|
RecipientWallet,
|
||||||
|
} from './PaymentInteface';
|
||||||
|
import {
|
||||||
|
validateJSON,
|
||||||
|
payPalApiRequest,
|
||||||
|
payPalApiRequestAllItems
|
||||||
|
} from './GenericFunctions';
|
||||||
|
|
||||||
|
export class PayPal implements INodeType {
|
||||||
|
description: INodeTypeDescription = {
|
||||||
|
displayName: 'PayPal',
|
||||||
|
name: 'payPal',
|
||||||
|
icon: 'file:paypal.png',
|
||||||
|
group: ['output'],
|
||||||
|
version: 1,
|
||||||
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||||
|
description: 'Consume PayPal API',
|
||||||
|
defaults: {
|
||||||
|
name: 'PayPal',
|
||||||
|
color: '#356ae6',
|
||||||
|
},
|
||||||
|
inputs: ['main'],
|
||||||
|
outputs: ['main'],
|
||||||
|
credentials: [
|
||||||
|
{
|
||||||
|
name: 'payPalApi',
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
displayName: 'Resource',
|
||||||
|
name: 'resource',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Payout',
|
||||||
|
value: 'payout',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Payout Item',
|
||||||
|
value: 'payoutItem',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'payout',
|
||||||
|
description: 'Resource to consume.',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Payout
|
||||||
|
...payoutOperations,
|
||||||
|
...payoutItemOperations,
|
||||||
|
...payoutFields,
|
||||||
|
...payoutItemFields,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
|
const items = this.getInputData();
|
||||||
|
const returnData: IDataObject[] = [];
|
||||||
|
const length = items.length as unknown as number;
|
||||||
|
let responseData;
|
||||||
|
const qs: IDataObject = {};
|
||||||
|
|
||||||
|
const resource = this.getNodeParameter('resource', 0) as string;
|
||||||
|
const operation = this.getNodeParameter('operation', 0) as string;
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
if (resource === 'payout') {
|
||||||
|
if (operation === 'create') {
|
||||||
|
const body: IPaymentBatch = {};
|
||||||
|
const header: ISenderBatchHeader = {};
|
||||||
|
const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean;
|
||||||
|
const senderBatchId = this.getNodeParameter('senderBatchId', i) as string;
|
||||||
|
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||||
|
header.sender_batch_id = senderBatchId;
|
||||||
|
if (additionalFields.emailSubject) {
|
||||||
|
header.email_subject = additionalFields.emailSubject as string;
|
||||||
|
}
|
||||||
|
if (additionalFields.emailMessage) {
|
||||||
|
header.email_message = additionalFields.emailMessage as string;
|
||||||
|
}
|
||||||
|
if (additionalFields.note) {
|
||||||
|
header.note = additionalFields.note as string;
|
||||||
|
}
|
||||||
|
body.sender_batch_header = header;
|
||||||
|
if (!jsonActive) {
|
||||||
|
const payoutItems: IItem[] = [];
|
||||||
|
const itemsValues = (this.getNodeParameter('itemsUi', i) as IDataObject).itemsValues as IDataObject[];
|
||||||
|
if (itemsValues && itemsValues.length > 0) {
|
||||||
|
itemsValues.forEach(o => {
|
||||||
|
const payoutItem: IItem = {};
|
||||||
|
const amount: IAmount = {};
|
||||||
|
amount.currency = o.currency as string;
|
||||||
|
amount.value = parseFloat(o.amount as string);
|
||||||
|
payoutItem.amount = amount;
|
||||||
|
payoutItem.note = o.note 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 || '';
|
||||||
|
payoutItems.push(payoutItem);
|
||||||
|
});
|
||||||
|
body.items = payoutItems;
|
||||||
|
} else {
|
||||||
|
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, '/payments/payouts', 'POST', body);
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`PayPal Error: ${JSON.stringify(err)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (operation === 'get') {
|
||||||
|
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)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (resource === 'payoutItem') {
|
||||||
|
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 === 'cancel') {
|
||||||
|
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)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Array.isArray(responseData)) {
|
||||||
|
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||||
|
} else {
|
||||||
|
returnData.push(responseData as IDataObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [this.helpers.returnJsonArray(returnData)];
|
||||||
|
}
|
||||||
|
}
|
419
packages/nodes-base/nodes/PayPal/PaymentDescription.ts
Normal file
419
packages/nodes-base/nodes/PayPal/PaymentDescription.ts
Normal file
|
@ -0,0 +1,419 @@
|
||||||
|
import { INodeProperties } from "n8n-workflow";
|
||||||
|
|
||||||
|
export const payoutOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payout',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Create',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create a batch payout',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get',
|
||||||
|
value: 'get',
|
||||||
|
description: 'Show batch payout details',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'create',
|
||||||
|
description: 'The operation to perform.',
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const payoutFields = [
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* payout:create */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
{
|
||||||
|
displayName: 'Sender Batch ID',
|
||||||
|
name: 'senderBatchId',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payout',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'A sender-specified ID number. Tracks the payout in an accounting system.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'JSON Parameters',
|
||||||
|
name: 'jsonParameters',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payout'
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Items',
|
||||||
|
name: 'itemsUi',
|
||||||
|
placeholder: 'Add Item',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payout',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
jsonParameters: [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'itemsValues',
|
||||||
|
displayName: 'Item',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Recipient Type',
|
||||||
|
name: 'recipientType',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Phone',
|
||||||
|
value: 'phone',
|
||||||
|
description: 'The unencrypted phone number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Email',
|
||||||
|
value: 'email',
|
||||||
|
description: 'The unencrypted email.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PayPal ID',
|
||||||
|
value: 'paypalId',
|
||||||
|
description: 'The encrypted PayPal account number.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'email',
|
||||||
|
description: 'The ID type that identifies the recipient of the payment.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Receiver Value',
|
||||||
|
name: 'receiverValue',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
description: 'The receiver of the payment. Corresponds to the recipient_type value<br />in the request. Max length: 127 characters.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Currency',
|
||||||
|
name: 'currency',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Australian dollar',
|
||||||
|
value: 'AUD'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Brazilian real',
|
||||||
|
value: 'BRL'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Canadian dollar',
|
||||||
|
value: 'CAD'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Czech koruna',
|
||||||
|
value: 'CZK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Danish krone',
|
||||||
|
value: 'DKK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Euro',
|
||||||
|
value: 'EUR'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'United States dollar',
|
||||||
|
value: 'USD'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
default: 'USD',
|
||||||
|
description: 'Currency',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Amount',
|
||||||
|
name: 'amount',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
description: 'The value, which might be',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Note',
|
||||||
|
name: 'note',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
description: 'The sender-specified note for notifications. Supports up to<br />4000 ASCII characters and 1000 non-ASCII characters.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Sender Item ID',
|
||||||
|
name: 'senderItemId',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'The sender-specified ID number. Tracks the payout in an accounting system.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Recipient Wallet',
|
||||||
|
name: 'recipientWallet',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'PayPal',
|
||||||
|
value: 'paypal',
|
||||||
|
description: 'PayPal Wallet',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Venmo',
|
||||||
|
value: 'venmo',
|
||||||
|
description: 'Venmo Wallet',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'paypal',
|
||||||
|
description: 'The recipient wallet',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Items',
|
||||||
|
name: 'itemsJson',
|
||||||
|
type: 'json',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
description: 'An array of individual payout items.',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payout'
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
jsonParameters: [
|
||||||
|
true,
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Additional Fields',
|
||||||
|
name: 'additionalFields',
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
default: {},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payout',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Email Subject',
|
||||||
|
name: 'emailSubject',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'The subject line for the email that PayPal sends when payment<br />for a payout item completes. The subject line is the same for all<br />recipients. Max length: 255 characters.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Email Message',
|
||||||
|
name: 'emailMessage',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'The email message that PayPal sends when the payout item completes.<br />The message is the same for all recipients.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Note',
|
||||||
|
name: 'note',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'The payouts and item-level notes are concatenated in the email.<br />Max length: 1000 characters.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* payout:get */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
{
|
||||||
|
displayName: 'Payout Batch Id',
|
||||||
|
name: 'payoutBatchId',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payout',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'The ID of the payout for which to show details.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payout',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'If all results should be returned or only up to a given limit.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
typeOptions: {
|
||||||
|
maxValue: 1000,
|
||||||
|
minValue: 1
|
||||||
|
},
|
||||||
|
default: 100,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payout',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'If all results should be returned or only up to a given limit.',
|
||||||
|
},
|
||||||
|
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
|
||||||
|
export const payoutItemOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payoutItem',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Cancel',
|
||||||
|
value: 'cancel',
|
||||||
|
description: 'Cancels an unclaimed payout item',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get',
|
||||||
|
value: 'get',
|
||||||
|
description: 'Show payout item details',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'get',
|
||||||
|
description: 'The operation to perform.',
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const payoutItemFields = [
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* payoutItem:get */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
{
|
||||||
|
displayName: 'Payout Item Id',
|
||||||
|
name: 'payoutItemId',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payoutItem',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'The ID of the payout item for which to show details.',
|
||||||
|
},
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* payoutItem:cancel */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
{
|
||||||
|
displayName: 'Payout Item Id',
|
||||||
|
name: 'payoutItemId',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'payoutItem',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'cancel',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'The ID of the payout item to cancel.',
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
38
packages/nodes-base/nodes/PayPal/PaymentInteface.ts
Normal file
38
packages/nodes-base/nodes/PayPal/PaymentInteface.ts
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import { IDataObject } from "n8n-workflow";
|
||||||
|
|
||||||
|
export enum RecipientType {
|
||||||
|
email = 'EMAIL',
|
||||||
|
phone = 'PHONE',
|
||||||
|
paypalId = 'PAYPAL_ID',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum RecipientWallet {
|
||||||
|
paypal = 'PAYPAL',
|
||||||
|
venmo = 'VENMO',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IAmount {
|
||||||
|
currency?: string;
|
||||||
|
value?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISenderBatchHeader {
|
||||||
|
sender_batch_id?: string;
|
||||||
|
email_subject?: string;
|
||||||
|
email_message?: string;
|
||||||
|
note?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IItem {
|
||||||
|
recipient_type?: RecipientType;
|
||||||
|
amount?: IAmount;
|
||||||
|
note?: string;
|
||||||
|
receiver?: string;
|
||||||
|
sender_item_id?: string;
|
||||||
|
recipient_wallet?: RecipientWallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPaymentBatch {
|
||||||
|
sender_batch_header?: ISenderBatchHeader;
|
||||||
|
items?: IItem[];
|
||||||
|
}
|
BIN
packages/nodes-base/nodes/PayPal/paypal.png
Normal file
BIN
packages/nodes-base/nodes/PayPal/paypal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
|
@ -53,6 +53,7 @@
|
||||||
"dist/credentials/OpenWeatherMapApi.credentials.js",
|
"dist/credentials/OpenWeatherMapApi.credentials.js",
|
||||||
"dist/credentials/PipedriveApi.credentials.js",
|
"dist/credentials/PipedriveApi.credentials.js",
|
||||||
"dist/credentials/Postgres.credentials.js",
|
"dist/credentials/Postgres.credentials.js",
|
||||||
|
"dist/credentials/PayPalApi.credentials.js",
|
||||||
"dist/credentials/Redis.credentials.js",
|
"dist/credentials/Redis.credentials.js",
|
||||||
"dist/credentials/RocketchatApi.credentials.js",
|
"dist/credentials/RocketchatApi.credentials.js",
|
||||||
"dist/credentials/SlackApi.credentials.js",
|
"dist/credentials/SlackApi.credentials.js",
|
||||||
|
@ -115,6 +116,7 @@
|
||||||
"dist/nodes/Pipedrive/Pipedrive.node.js",
|
"dist/nodes/Pipedrive/Pipedrive.node.js",
|
||||||
"dist/nodes/Pipedrive/PipedriveTrigger.node.js",
|
"dist/nodes/Pipedrive/PipedriveTrigger.node.js",
|
||||||
"dist/nodes/Postgres/Postgres.node.js",
|
"dist/nodes/Postgres/Postgres.node.js",
|
||||||
|
"dist/nodes/PayPal/PayPal.node.js",
|
||||||
"dist/nodes/Rocketchat/Rocketchat.node.js",
|
"dist/nodes/Rocketchat/Rocketchat.node.js",
|
||||||
"dist/nodes/ReadBinaryFile.node.js",
|
"dist/nodes/ReadBinaryFile.node.js",
|
||||||
"dist/nodes/ReadBinaryFiles.node.js",
|
"dist/nodes/ReadBinaryFiles.node.js",
|
||||||
|
|
Loading…
Reference in a new issue