n8n-nodes-iyzico-unofficial
Version:
N8N community node for Iyzico payment system integration
554 lines (553 loc) • 22.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Iyzico = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const crypto_1 = require("crypto");
class Iyzico {
description = {
displayName: 'Iyzico',
name: 'iyzico',
icon: 'file:iyzico.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"]}}',
description: 'Interact with Iyzico iyzilink API',
defaults: {
name: 'Iyzico',
},
inputs: ["main"],
outputs: ["main"],
credentials: [
{
name: 'iyzicoApi',
required: true,
},
],
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Create Link',
value: 'createLink',
description: 'Create a new iyzilink product',
action: 'Create a new iyzilink product',
},
{
name: 'Update Link',
value: 'updateLink',
description: 'Update an existing iyzilink product',
action: 'Update an existing iyzilink product',
},
{
name: 'Delete Link',
value: 'deleteLink',
description: 'Delete an iyzilink product',
action: 'Delete an iyzilink product',
},
{
name: 'Get Link Details',
value: 'getLinkDetails',
description: 'Get details of an iyzilink product',
action: 'Get details of an iyzilink product',
},
{
name: 'List Links',
value: 'listLinks',
description: 'List iyzilink products',
action: 'List iyzilink products',
},
{
name: 'Update Status',
value: 'updateStatus',
description: 'Update the status of an iyzilink product',
action: 'Update the status of an iyzilink product',
},
],
default: 'createLink',
},
{
displayName: 'Product Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
operation: ['createLink', 'updateLink'],
},
},
default: '',
required: true,
description: 'Name of the product displayed on screen',
},
{
displayName: 'Price',
name: 'price',
type: 'string',
displayOptions: {
show: {
operation: ['createLink', 'updateLink'],
},
},
default: '',
required: true,
description: 'Product price',
},
{
displayName: 'Currency Code',
name: 'currencyCode',
type: 'options',
displayOptions: {
show: {
operation: ['createLink', 'updateLink'],
},
},
options: [
{
name: 'Turkish Lira (TRY)',
value: 'TRY',
},
{
name: 'US Dollar (USD)',
value: 'USD',
},
{
name: 'Euro (EUR)',
value: 'EUR',
},
],
default: 'TRY',
required: true,
description: 'Product currency',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
typeOptions: {
rows: 3,
},
displayOptions: {
show: {
operation: ['createLink', 'updateLink'],
},
},
default: '',
required: true,
description: 'Product description displayed on screen',
},
{
displayName: 'Encoded Image File',
name: 'encodedImageFile',
type: 'string',
typeOptions: {
rows: 3,
},
displayOptions: {
show: {
operation: ['createLink', 'updateLink'],
},
},
default: '',
required: true,
description: 'Product image converted to base64',
},
{
displayName: 'Token',
name: 'token',
type: 'string',
displayOptions: {
show: {
operation: ['updateLink', 'deleteLink', 'getLinkDetails', 'updateStatus'],
},
},
default: '',
required: true,
description: 'The token value generated by iyzico for the product',
},
{
displayName: 'Status',
name: 'status',
type: 'options',
displayOptions: {
show: {
operation: ['updateStatus'],
},
},
options: [
{
name: 'Active',
value: 'ACTIVE',
},
{
name: 'Passive',
value: 'PASSIVE',
},
],
default: 'ACTIVE',
required: true,
description: 'New status for the product',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
operation: ['createLink', 'updateLink', 'deleteLink', 'getLinkDetails', 'listLinks', 'updateStatus'],
},
},
options: [
{
displayName: 'Conversation ID',
name: 'conversationId',
type: 'string',
default: '',
description: 'A value that you can send during the request and receive in the result. Most commonly used as the merchant product number.',
},
{
displayName: 'Locale',
name: 'locale',
type: 'options',
options: [
{
name: 'Turkish',
value: 'tr',
},
{
name: 'English',
value: 'en',
},
],
default: 'tr',
description: 'Language for the response texts',
},
{
displayName: 'Installment Requested',
name: 'installmentRequested',
type: 'boolean',
displayOptions: {
show: {
'/operation': ['createLink', 'updateLink'],
},
},
default: false,
description: 'Whether installment sales are allowed',
},
{
displayName: 'Address Ignorable',
name: 'addressIgnorable',
type: 'boolean',
displayOptions: {
show: {
'/operation': ['createLink', 'updateLink'],
},
},
default: true,
description: 'Whether to request address when purchasing the product',
},
{
displayName: 'Stock Count',
name: 'stockCount',
type: 'number',
displayOptions: {
show: {
'/operation': ['createLink'],
},
},
default: 0,
description: 'Stock count',
},
{
displayName: 'Stock Enabled',
name: 'stockEnabled',
type: 'boolean',
displayOptions: {
show: {
'/operation': ['createLink'],
},
},
default: false,
description: 'Stock approval, normally the default value is FALSE',
},
],
},
{
displayName: 'Buyer Information',
name: 'buyerInformation',
type: 'collection',
placeholder: 'Add Buyer Field',
default: {},
displayOptions: {
show: {
operation: ['createLink'],
},
},
options: [
{
displayName: 'Buyer Name',
name: 'buyerName',
type: 'string',
default: '',
description: 'Buyer first name',
},
{
displayName: 'Buyer Surname',
name: 'buyerSurname',
type: 'string',
default: '',
description: 'Buyer last name',
},
{
displayName: 'Buyer Email',
name: 'buyerEmail',
type: 'string',
default: '',
description: 'Buyer email address',
},
{
displayName: 'Buyer GSM',
name: 'buyerGsmNumber',
type: 'string',
default: '',
description: 'Buyer phone number',
},
{
displayName: 'Buyer Address',
name: 'buyerAddress',
type: 'string',
default: '',
description: 'Buyer address',
},
{
displayName: 'Buyer City',
name: 'buyerCity',
type: 'string',
default: '',
description: 'Buyer city',
},
{
displayName: 'Buyer Country',
name: 'buyerCountry',
type: 'string',
default: '',
description: 'Buyer country',
},
],
},
{
displayName: 'Page',
name: 'page',
type: 'number',
displayOptions: {
show: {
operation: ['listLinks'],
},
},
default: 1,
required: true,
description: 'Page number',
},
{
displayName: 'Count',
name: 'count',
type: 'number',
displayOptions: {
show: {
operation: ['listLinks'],
},
},
default: 10,
required: true,
description: 'Number of products displayed per page',
},
],
};
async execute() {
const items = this.getInputData();
const returnData = [];
const credentials = await this.getCredentials('iyzicoApi');
const environment = credentials.environment;
const baseURL = environment === 'sandbox'
? 'https://sandbox-api.iyzipay.com'
: 'https://api.iyzipay.com';
for (let i = 0; i < items.length; i++) {
const operation = this.getNodeParameter('operation', i);
try {
const additionalFields = this.getNodeParameter('additionalFields', i, {});
let method;
let endpoint;
let body = {};
if (additionalFields.conversationId) {
body.conversationId = additionalFields.conversationId;
}
if (additionalFields.locale) {
body.locale = additionalFields.locale;
}
switch (operation) {
case 'createLink':
method = 'POST';
endpoint = '/v2/iyzilink/products';
body = {
name: this.getNodeParameter('name', i),
price: this.getNodeParameter('price', i),
currencyCode: this.getNodeParameter('currencyCode', i),
description: this.getNodeParameter('description', i),
encodedImageFile: this.getNodeParameter('encodedImageFile', i)
};
if (additionalFields.installmentRequested !== undefined) {
body.installmentRequested = additionalFields.installmentRequested.toString();
}
if (additionalFields.addressIgnorable !== undefined) {
body.addressIgnorable = additionalFields.addressIgnorable.toString();
}
if (additionalFields.stockCount !== undefined) {
body.stockCount = additionalFields.stockCount;
}
if (additionalFields.stockEnabled !== undefined) {
body.stockEnabled = additionalFields.stockEnabled;
}
const buyerInfo = this.getNodeParameter('buyerInformation', i, {});
if (Object.keys(buyerInfo).length > 0) {
Object.keys(buyerInfo).forEach(key => {
if (buyerInfo[key]) {
body[key] = buyerInfo[key];
}
});
}
break;
case 'updateLink':
method = 'PUT';
endpoint = '/v2/iyzilink/products';
body = {
name: this.getNodeParameter('name', i),
price: this.getNodeParameter('price', i),
currencyCode: this.getNodeParameter('currencyCode', i),
description: this.getNodeParameter('description', i),
encodedImageFile: this.getNodeParameter('encodedImageFile', i),
token: this.getNodeParameter('token', i)
};
if (additionalFields.installmentRequested !== undefined) {
body.installmentRequested = additionalFields.installmentRequested.toString();
}
if (additionalFields.addressIgnorable !== undefined) {
body.addressIgnorable = additionalFields.addressIgnorable.toString();
}
break;
case 'deleteLink':
method = 'DELETE';
endpoint = '/v2/iyzilink/products';
body = {
token: this.getNodeParameter('token', i)
};
if (additionalFields.conversationId) {
body.conversationId = additionalFields.conversationId;
}
if (additionalFields.locale) {
body.locale = additionalFields.locale;
}
break;
case 'getLinkDetails':
method = 'GET';
endpoint = '/v2/iyzilink/products';
body = {
token: this.getNodeParameter('token', i)
};
break;
case 'listLinks':
method = 'GET';
endpoint = '/v2/iyzilink/products';
body = {
page: this.getNodeParameter('page', i),
count: this.getNodeParameter('count', i)
};
break;
case 'updateStatus':
method = 'PATCH';
const token = this.getNodeParameter('token', i);
const status = this.getNodeParameter('status', i);
endpoint = `/v2/iyzilink/products/${token}/status/${status}`;
body = {};
if (additionalFields.conversationId) {
body.conversationId = additionalFields.conversationId;
}
if (additionalFields.locale) {
body.locale = additionalFields.locale;
}
break;
default:
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`, {
itemIndex: i,
});
}
let requestBody = '';
let queryString = '';
if (['POST', 'PUT', 'DELETE', 'PATCH'].includes(method)) {
requestBody = JSON.stringify(body);
}
else if (method === 'GET' && Object.keys(body).length > 0) {
queryString = new URLSearchParams(body).toString();
}
const randomKey = new Date().getTime() + Math.floor(Math.random() * 1000000).toString();
const payload = randomKey + endpoint + requestBody;
const encryptedData = (0, crypto_1.createHmac)('sha256', credentials.secretKey)
.update(payload)
.digest('hex');
const authorizationString = `apiKey:${credentials.apiKey}&randomKey:${randomKey}&signature:${encryptedData}`;
const base64EncodedAuthorization = Buffer.from(authorizationString).toString('base64');
const authorization = `IYZWSv2 ${base64EncodedAuthorization}`;
const options = {
method,
url: `${baseURL}${endpoint}${queryString ? `?${queryString}` : ''}`,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': authorization,
'x-iyzi-rnd': randomKey,
},
json: true,
};
if (['POST', 'PUT', 'DELETE', 'PATCH'].includes(method)) {
options.body = body;
}
const response = await this.helpers.request(options);
if (response.status !== 'success') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Iyzico API error: ${response.errorMessage || 'Unknown error'}`, {
itemIndex: i,
description: response.errorGroup || 'API Error',
});
}
returnData.push({
json: response,
pairedItem: { item: i },
});
}
catch (error) {
if (error.response?.status === 401) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Authentication failed. Please check your API Key and Secret Key. Make sure you are using the correct HMACSHA256 authentication.', {
itemIndex: i,
description: 'Invalid credentials or authentication method',
});
}
if (this.continueOnFail()) {
returnData.push({
json: {
error: error.message,
httpCode: error.response?.status,
details: error.response?.data
},
pairedItem: { item: i },
});
continue;
}
throw error;
}
}
return [returnData];
}
}
exports.Iyzico = Iyzico;