UNPKG

n8n-nodes-iyzico-unofficial

Version:

N8N community node for Iyzico payment system integration

554 lines (553 loc) 22.8 kB
"use strict"; 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;