/* eslint-disable n8n-nodes-base/node-param-description-excess-final-period */
import type {
	IDataObject,
	IHookFunctions,
	IWebhookFunctions,
	INodeType,
	INodeTypeDescription,
	IWebhookResponseData,
	JsonObject,
	NodeParameterValue,
} from 'n8n-workflow';
import { NodeApiError, NodeConnectionTypes } from 'n8n-workflow';

import { stripeApiRequest } from './helpers';
import { verifySignature } from './StripeTriggerHelpers';

export class StripeTrigger implements INodeType {
	description: INodeTypeDescription = {
		displayName: 'Stripe Trigger',
		name: 'stripeTrigger',
		icon: 'file:stripe.svg',
		group: ['trigger'],
		version: 1,
		description: 'Handle Stripe events via webhooks',
		defaults: {
			name: 'Stripe Trigger',
		},
		inputs: [],
		outputs: [NodeConnectionTypes.Main],
		credentials: [
			{
				name: 'stripeApi',
				required: true,
			},
		],
		webhooks: [
			{
				name: 'default',
				httpMethod: 'POST',
				responseMode: 'onReceived',
				path: 'webhook',
			},
		],
		properties: [
			{
				displayName: 'Events',
				name: 'events',
				type: 'multiOptions',
				required: true,
				default: [],
				description: 'The event to listen to',
				// eslint-disable-next-line n8n-nodes-base/node-param-multi-options-type-unsorted-items
				options: [
					{
						name: '*',
						value: '*',
						description: 'Any time any event is triggered (Wildcard Event)',
					},
					{
						name: 'Account Updated',
						value: 'account.updated',
						description: 'Occurs whenever an account status or property has changed',
					},
					{
						name: 'Account Application.authorized',
						value: 'account.application.authorized',
						description:
							'Occurs whenever a user authorizes an application. Sent to the related application only.',
					},
					{
						name: 'Account Application.deauthorized',
						value: 'account.application.deauthorized',
						description:
							'Occurs whenever a user deauthorizes an application. Sent to the related application only.',
					},
					{
						name: 'Account External_account.created',
						value: 'account.external_account.created',
						description: 'Occurs whenever an external account is created.',
					},
					{
						name: 'Account External_account.deleted',
						value: 'account.external_account.deleted',
						description: 'Occurs whenever an external account is deleted.',
					},
					{
						name: 'Account External_account.updated',
						value: 'account.external_account.updated',
						description: 'Occurs whenever an external account is updated.',
					},
					{
						name: 'Application Fee.created',
						value: 'application_fee.created',
						description: 'Occurs whenever an application fee is created on a charge.',
					},
					{
						name: 'Application Fee.refunded',
						value: 'application_fee.refunded',
						description:
							'Occurs whenever an application fee is refunded, whether from refunding a charge or from refunding the application fee directly. This includes partial refunds.',
					},
					{
						name: 'Application Fee.refund.updated',
						value: 'application_fee.refund.updated',
						description: 'Occurs whenever an application fee refund is updated.',
					},
					{
						name: 'Balance Available',
						value: 'balance.available',
						description:
							'Occurs whenever your Stripe balance has been updated (e.g., when a charge is available to be paid out). By default, Stripe automatically transfers funds in your balance to your bank account on a daily basis.',
					},
					{
						name: 'Capability Updated',
						value: 'capability.updated',
						description: 'Occurs whenever a capability has new requirements or a new status.',
					},
					{
						name: 'Charge Captured',
						value: 'charge.captured',
						description: 'Occurs whenever a previously uncaptured charge is captured.',
					},
					{
						name: 'Charge Expired',
						value: 'charge.expired',
						description: 'Occurs whenever an uncaptured charge expires.',
					},
					{
						name: 'Charge Failed',
						value: 'charge.failed',
						description: 'Occurs whenever a failed charge attempt occurs.',
					},
					{
						name: 'Charge Pending',
						value: 'charge.pending',
						description: 'Occurs whenever a pending charge is created.',
					},
					{
						name: 'Charge Refunded',
						value: 'charge.refunded',
						description: 'Occurs whenever a charge is refunded, including partial refunds.',
					},
					{
						name: 'Charge Succeeded',
						value: 'charge.succeeded',
						description: 'Occurs whenever a new charge is created and is successful.',
					},
					{
						name: 'Charge Updated',
						value: 'charge.updated',
						description: 'Occurs whenever a charge description or metadata is updated.',
					},
					{
						name: 'Charge Dispute.closed',
						value: 'charge.dispute.closed',
						description:
							'Occurs when a dispute is closed and the dispute status changes to lost, warning_closed, or won.',
					},
					{
						name: 'Charge Dispute.created',
						value: 'charge.dispute.created',
						description: 'Occurs whenever a customer disputes a charge with their bank.',
					},
					{
						name: 'Charge Dispute.funds_reinstated',
						value: 'charge.dispute.funds_reinstated',
						description:
							'Occurs when funds are reinstated to your account after a dispute is closed. This includes partially refunded payments.',
					},
					{
						name: 'Charge Dispute.funds_withdrawn',
						value: 'charge.dispute.funds_withdrawn',
						description: 'Occurs when funds are removed from your account due to a dispute.',
					},
					{
						name: 'Charge Dispute.updated',
						value: 'charge.dispute.updated',
						description: 'Occurs when the dispute is updated (usually with evidence).',
					},
					{
						name: 'Charge Refund.updated',
						value: 'charge.refund.updated',
						description: 'Occurs whenever a refund is updated, on selected payment methods.',
					},
					{
						name: 'Checkout Session.completed',
						value: 'checkout.session.completed',
						description: 'Occurs when a Checkout Session has been successfully completed.',
					},
					{
						name: 'Coupon Created',
						value: 'coupon.created',
						description: 'Occurs whenever a coupon is created.',
					},
					{
						name: 'Coupon Deleted',
						value: 'coupon.deleted',
						description: 'Occurs whenever a coupon is deleted.',
					},
					{
						name: 'Coupon Updated',
						value: 'coupon.updated',
						description: 'Occurs whenever a coupon is updated.',
					},
					{
						name: 'Credit Note.created',
						value: 'credit_note.created',
						description: 'Occurs whenever a credit note is created.',
					},
					{
						name: 'Credit Note.updated',
						value: 'credit_note.updated',
						description: 'Occurs whenever a credit note is updated.',
					},
					{
						name: 'Credit Note.voided',
						value: 'credit_note.voided',
						description: 'Occurs whenever a credit note is voided.',
					},
					{
						name: 'Customer Created',
						value: 'customer.created',
						description: 'Occurs whenever a new customer is created.',
					},
					{
						name: 'Customer Deleted',
						value: 'customer.deleted',
						description: 'Occurs whenever a customer is deleted.',
					},
					{
						name: 'Customer Updated',
						value: 'customer.updated',
						description: 'Occurs whenever any property of a customer changes.',
					},
					{
						name: 'Customer Discount.created',
						value: 'customer.discount.created',
						description: 'Occurs whenever a coupon is attached to a customer.',
					},
					{
						name: 'Customer Discount.deleted',
						value: 'customer.discount.deleted',
						description: 'Occurs whenever a coupon is removed from a customer.',
					},
					{
						name: 'Customer Discount.updated',
						value: 'customer.discount.updated',
						description: 'Occurs whenever a customer is switched from one coupon to another.',
					},
					{
						name: 'Customer Source.created',
						value: 'customer.source.created',
						description: 'Occurs whenever a new source is created for a customer.',
					},
					{
						name: 'Customer Source.deleted',
						value: 'customer.source.deleted',
						description: 'Occurs whenever a source is removed from a customer.',
					},
					{
						name: 'Customer Source.expiring',
						value: 'customer.source.expiring',
						description: 'Occurs whenever a card or source will expire at the end of the month.',
					},
					{
						name: 'Customer Source.updated',
						value: 'customer.source.updated',
						description: "Occurs whenever a source's details are changed.",
					},
					{
						name: 'Customer Subscription.created',
						value: 'customer.subscription.created',
						description: 'Occurs whenever a customer is signed up for a new plan.',
					},
					{
						name: 'Customer Subscription.deleted',
						value: 'customer.subscription.deleted',
						description: "Occurs whenever a customer's subscription ends.",
					},
					{
						name: 'Customer Subscription.trial_will_end',
						value: 'customer.subscription.trial_will_end',
						description:
							"Occurs three days before a subscription's trial period is scheduled to end, or when a trial is ended immediately (using trial_end=now).",
					},
					{
						name: 'Customer Subscription.updated',
						value: 'customer.subscription.updated',
						description:
							'Occurs whenever a subscription changes (e.g., switching from one plan to another, or changing the status from trial to active).',
					},
					{
						name: 'Customer Tax_id.created',
						value: 'customer.tax_id.created',
						description: 'Occurs whenever a tax ID is created for a customer.',
					},
					{
						name: 'Customer Tax_id.deleted',
						value: 'customer.tax_id.deleted',
						description: 'Occurs whenever a tax ID is deleted from a customer.',
					},
					{
						name: 'Customer Tax_id.updated',
						value: 'customer.tax_id.updated',
						description: "Occurs whenever a customer's tax ID is updated.",
					},
					{
						name: 'File Created',
						value: 'file.created',
						description:
							'Occurs whenever a new Stripe-generated file is available for your account.',
					},
					{
						name: 'Invoice Created',
						value: 'invoice.created',
						description:
							'Occurs whenever a new invoice is created. To learn how webhooks can be used with this event, and how they can affect it, see Using Webhooks with Subscriptions.',
					},
					{
						name: 'Invoice Deleted',
						value: 'invoice.deleted',
						description: 'Occurs whenever a draft invoice is deleted.',
					},
					{
						name: 'Invoice Finalized',
						value: 'invoice.finalized',
						description:
							'Occurs whenever a draft invoice is finalized and updated to be an open invoice.',
					},
					{
						name: 'Invoice Marked_uncollectible',
						value: 'invoice.marked_uncollectible',
						description: 'Occurs whenever an invoice is marked uncollectible.',
					},
					{
						name: 'Invoice Payment_action_required',
						value: 'invoice.payment_action_required',
						description:
							'Occurs whenever an invoice payment attempt requires further user action to complete.',
					},
					{
						name: 'Invoice Payment_failed',
						value: 'invoice.payment_failed',
						description:
							'Occurs whenever an invoice payment attempt fails, due either to a declined payment or to the lack of a stored payment method.',
					},
					{
						name: 'Invoice Payment_succeeded',
						value: 'invoice.payment_succeeded',
						description: 'Occurs whenever an invoice payment attempt succeeds.',
					},
					{
						name: 'Invoice Sent',
						value: 'invoice.sent',
						description: 'Occurs whenever an invoice email is sent out.',
					},
					{
						name: 'Invoice Upcoming',
						value: 'invoice.upcoming',
						description:
							'Occurs X number of days before a subscription is scheduled to create an invoice that is automatically charged—where X is determined by your subscriptions settings. Note: The received Invoice object will not have an invoice ID.',
					},
					{
						name: 'Invoice Updated',
						value: 'invoice.updated',
						description: 'Occurs whenever an invoice changes (e.g., the invoice amount).',
					},
					{
						name: 'Invoice Voided',
						value: 'invoice.voided',
						description: 'Occurs whenever an invoice is voided.',
					},
					{
						name: 'Invoiceitem Created',
						value: 'invoiceitem.created',
						description: 'Occurs whenever an invoice item is created.',
					},
					{
						name: 'Invoiceitem Deleted',
						value: 'invoiceitem.deleted',
						description: 'Occurs whenever an invoice item is deleted.',
					},
					{
						name: 'Invoiceitem Updated',
						value: 'invoiceitem.updated',
						description: 'Occurs whenever an invoice item is updated.',
					},
					{
						name: 'Issuing Authorization.created',
						value: 'issuing_authorization.created',
						description: 'Occurs whenever an authorization is created.',
					},
					{
						name: 'Issuing Authorization.request',
						value: 'issuing_authorization.request',
						description:
							'Represents a synchronous request for authorization, see Using your integration to handle authorization requests.',
					},
					{
						name: 'Issuing Authorization.updated',
						value: 'issuing_authorization.updated',
						description: 'Occurs whenever an authorization is updated.',
					},
					{
						name: 'Issuing Card.created',
						value: 'issuing_card.created',
						description: 'Occurs whenever a card is created.',
					},
					{
						name: 'Issuing Card.updated',
						value: 'issuing_card.updated',
						description: 'Occurs whenever a card is updated.',
					},
					{
						name: 'Issuing Cardholder.created',
						value: 'issuing_cardholder.created',
						description: 'Occurs whenever a cardholder is created.',
					},
					{
						name: 'Issuing Cardholder.updated',
						value: 'issuing_cardholder.updated',
						description: 'Occurs whenever a cardholder is updated.',
					},
					{
						name: 'Issuing Dispute.created',
						value: 'issuing_dispute.created',
						description: 'Occurs whenever a dispute is created.',
					},
					{
						name: 'Issuing Dispute.updated',
						value: 'issuing_dispute.updated',
						description: 'Occurs whenever a dispute is updated.',
					},
					{
						name: 'Issuing Settlement.created',
						value: 'issuing_settlement.created',
						description: 'Occurs whenever an issuing settlement is created.',
					},
					{
						name: 'Issuing Settlement.updated',
						value: 'issuing_settlement.updated',
						description: 'Occurs whenever an issuing settlement is updated.',
					},
					{
						name: 'Issuing Transaction.created',
						value: 'issuing_transaction.created',
						description: 'Occurs whenever an issuing transaction is created.',
					},
					{
						name: 'Issuing Transaction.updated',
						value: 'issuing_transaction.updated',
						description: 'Occurs whenever an issuing transaction is updated.',
					},
					{
						name: 'Order Created',
						value: 'order.created',
						description: 'Occurs whenever an order is created.',
					},
					{
						name: 'Order Payment_failed',
						value: 'order.payment_failed',
						description: 'Occurs whenever an order payment attempt fails.',
					},
					{
						name: 'Order Payment_succeeded',
						value: 'order.payment_succeeded',
						description: 'Occurs whenever an order payment attempt succeeds.',
					},
					{
						name: 'Order Updated',
						value: 'order.updated',
						description: 'Occurs whenever an order is updated.',
					},
					{
						name: 'Order Return.created',
						value: 'order_return.created',
						description: 'Occurs whenever an order return is created.',
					},
					{
						name: 'Payment Intent.amount_capturable_updated',
						value: 'payment_intent.amount_capturable_updated',
						description:
							'Occurs when a PaymentIntent has funds to be captured. Check the amount_capturable property on the PaymentIntent to determine the amount that can be captured. You may capture the PaymentIntent with an amount_to_capture value up to the specified amount. Learn more about capturing PaymentIntents.',
					},
					{
						name: 'Payment Intent.canceled',
						value: 'payment_intent.canceled',
						description: 'Occurs when a PaymentIntent is canceled.',
					},
					{
						name: 'Payment Intent.created',
						value: 'payment_intent.created',
						description: 'Occurs when a new PaymentIntent is created.',
					},
					{
						name: 'Payment Intent.payment_failed',
						value: 'payment_intent.payment_failed',
						description:
							'Occurs when a PaymentIntent has failed the attempt to create a source or a payment.',
					},
					{
						name: 'Payment Intent.succeeded',
						value: 'payment_intent.succeeded',
						description: 'Occurs when a PaymentIntent has been successfully fulfilled.',
					},
					{
						name: 'Payment Intent.requires_action',
						value: 'payment_intent.requires_action',
						description: 'Occurs when a PaymentIntent requires an action.',
					},
					{
						name: 'Payment Method.attached',
						value: 'payment_method.attached',
						description: 'Occurs whenever a new payment method is attached to a customer.',
					},
					{
						name: 'Payment Method.card_automatically_updated',
						value: 'payment_method.card_automatically_updated',
						description:
							"Occurs whenever a card payment method's details are automatically updated by the network.",
					},
					{
						name: 'Payment Method.detached',
						value: 'payment_method.detached',
						description: 'Occurs whenever a payment method is detached from a customer.',
					},
					{
						name: 'Payment Method.updated',
						value: 'payment_method.updated',
						description:
							'Occurs whenever a payment method is updated via the PaymentMethod update API.',
					},
					{
						name: 'Payout Canceled',
						value: 'payout.canceled',
						description: 'Occurs whenever a payout is canceled.',
					},
					{
						name: 'Payout Created',
						value: 'payout.created',
						description: 'Occurs whenever a payout is created.',
					},
					{
						name: 'Payout Failed',
						value: 'payout.failed',
						description: 'Occurs whenever a payout attempt fails.',
					},
					{
						name: 'Payout Paid',
						value: 'payout.paid',
						description:
							'Occurs whenever a payout is expected to be available in the destination account. If the payout fails, a payout.failed notification is also sent, at a later time.',
					},
					{
						name: 'Payout Updated',
						value: 'payout.updated',
						description: 'Occurs whenever a payout is updated.',
					},
					{
						name: 'Person Created',
						value: 'person.created',
						description: 'Occurs whenever a person associated with an account is created.',
					},
					{
						name: 'Person Deleted',
						value: 'person.deleted',
						description: 'Occurs whenever a person associated with an account is deleted.',
					},
					{
						name: 'Person Updated',
						value: 'person.updated',
						description: 'Occurs whenever a person associated with an account is updated.',
					},
					{
						name: 'Plan Created',
						value: 'plan.created',
						description: 'Occurs whenever a plan is created.',
					},
					{
						name: 'Plan Deleted',
						value: 'plan.deleted',
						description: 'Occurs whenever a plan is deleted.',
					},
					{
						name: 'Plan Updated',
						value: 'plan.updated',
						description: 'Occurs whenever a plan is updated.',
					},
					{
						name: 'Product Created',
						value: 'product.created',
						description: 'Occurs whenever a product is created.',
					},
					{
						name: 'Product Deleted',
						value: 'product.deleted',
						description: 'Occurs whenever a product is deleted.',
					},
					{
						name: 'Product Updated',
						value: 'product.updated',
						description: 'Occurs whenever a product is updated.',
					},
					{
						name: 'Radar Early_fraud_warning.created',
						value: 'radar.early_fraud_warning.created',
						description: 'Occurs whenever an early fraud warning is created.',
					},
					{
						name: 'Radar Early_fraud_warning.updated',
						value: 'radar.early_fraud_warning.updated',
						description: 'Occurs whenever an early fraud warning is updated.',
					},
					{
						name: 'Recipient Created',
						value: 'recipient.created',
						description: 'Occurs whenever a recipient is created.',
					},
					{
						name: 'Recipient Deleted',
						value: 'recipient.deleted',
						description: 'Occurs whenever a recipient is deleted.',
					},
					{
						name: 'Recipient Updated',
						value: 'recipient.updated',
						description: 'Occurs whenever a recipient is updated.',
					},
					{
						name: 'Reporting Report_run.failed',
						value: 'reporting.report_run.failed',
						description: 'Occurs whenever a requested **ReportRun** failed to complete.',
					},
					{
						name: 'Reporting Report_run.succeeded',
						value: 'reporting.report_run.succeeded',
						description: 'Occurs whenever a requested **ReportRun** completed succesfully.',
					},
					{
						name: 'Reporting Report_type.updated',
						value: 'reporting.report_type.updated',
						description:
							"Occurs whenever a **ReportType** is updated (typically to indicate that a new day's data has come available).",
					},
					{
						name: 'Review Closed',
						value: 'review.closed',
						description:
							"Occurs whenever a review is closed. The review's reason field indicates why: approved, disputed, refunded, or refunded_as_fraud.",
					},
					{
						name: 'Review Opened',
						value: 'review.opened',
						description: 'Occurs whenever a review is opened.',
					},
					{
						name: 'Setup Intent.canceled',
						value: 'setup_intent.canceled',
						description: 'Occurs when a SetupIntent is canceled.',
					},
					{
						name: 'Setup Intent.created',
						value: 'setup_intent.created',
						description: 'Occurs when a new SetupIntent is created.',
					},
					{
						name: 'Setup Intent.setup_failed',
						value: 'setup_intent.setup_failed',
						description:
							'Occurs when a SetupIntent has failed the attempt to setup a payment method.',
					},
					{
						name: 'Setup Intent.succeeded',
						value: 'setup_intent.succeeded',
						description: 'Occurs when an SetupIntent has successfully setup a payment method.',
					},
					{
						name: 'Sigma Scheduled_query_run.created',
						value: 'sigma.scheduled_query_run.created',
						description: 'Occurs whenever a Sigma scheduled query run finishes.',
					},
					{
						name: 'Sku Created',
						value: 'sku.created',
						description: 'Occurs whenever a SKU is created.',
					},
					{
						name: 'Sku Deleted',
						value: 'sku.deleted',
						description: 'Occurs whenever a SKU is deleted.',
					},
					{
						name: 'Sku Updated',
						value: 'sku.updated',
						description: 'Occurs whenever a SKU is updated.',
					},
					{
						name: 'Source Canceled',
						value: 'source.canceled',
						description: 'Occurs whenever a source is canceled.',
					},
					{
						name: 'Source Chargeable',
						value: 'source.chargeable',
						description: 'Occurs whenever a source transitions to chargeable.',
					},
					{
						name: 'Source Failed',
						value: 'source.failed',
						description: 'Occurs whenever a source fails.',
					},
					{
						name: 'Source Mandate_notification',
						value: 'source.mandate_notification',
						description: 'Occurs whenever a source mandate notification method is set to manual.',
					},
					{
						name: 'Source Refund_attributes_required',
						value: 'source.refund_attributes_required',
						description:
							'Occurs whenever the refund attributes are required on a receiver source to process a refund or a mispayment.',
					},
					{
						name: 'Source Transaction.created',
						value: 'source.transaction.created',
						description: 'Occurs whenever a source transaction is created.',
					},
					{
						name: 'Source Transaction.updated',
						value: 'source.transaction.updated',
						description: 'Occurs whenever a source transaction is updated.',
					},
					{
						name: 'Subscription Schedule.aborted',
						value: 'subscription_schedule.aborted',
						description:
							'Occurs whenever a subscription schedule is canceled due to the underlying subscription being canceled because of delinquency.',
					},
					{
						name: 'Subscription Schedule.canceled',
						value: 'subscription_schedule.canceled',
						description: 'Occurs whenever a subscription schedule is canceled.',
					},
					{
						name: 'Subscription Schedule.completed',
						value: 'subscription_schedule.completed',
						description: 'Occurs whenever a new subscription schedule is completed.',
					},
					{
						name: 'Subscription Schedule.created',
						value: 'subscription_schedule.created',
						description: 'Occurs whenever a new subscription schedule is created.',
					},
					{
						name: 'Subscription Schedule.expiring',
						value: 'subscription_schedule.expiring',
						description: 'Occurs 7 days before a subscription schedule will expire.',
					},
					{
						name: 'Subscription Schedule.released',
						value: 'subscription_schedule.released',
						description: 'Occurs whenever a new subscription schedule is released.',
					},
					{
						name: 'Subscription Schedule.updated',
						value: 'subscription_schedule.updated',
						description: 'Occurs whenever a subscription schedule is updated.',
					},
					{
						name: 'Tax Rate.created',
						value: 'tax_rate.created',
						description: 'Occurs whenever a new tax rate is created.',
					},
					{
						name: 'Tax Rate.updated',
						value: 'tax_rate.updated',
						description: 'Occurs whenever a tax rate is updated.',
					},
					{
						name: 'Topup Canceled',
						value: 'topup.canceled',
						description: 'Occurs whenever a top-up is canceled.',
					},
					{
						name: 'Topup Created',
						value: 'topup.created',
						description: 'Occurs whenever a top-up is created.',
					},
					{
						name: 'Topup Failed',
						value: 'topup.failed',
						description: 'Occurs whenever a top-up fails.',
					},
					{
						name: 'Topup Reversed',
						value: 'topup.reversed',
						description: 'Occurs whenever a top-up is reversed.',
					},
					{
						name: 'Topup Succeeded',
						value: 'topup.succeeded',
						description: 'Occurs whenever a top-up succeeds.',
					},
					{
						name: 'Transfer Created',
						value: 'transfer.created',
						description: 'Occurs whenever a transfer is created.',
					},
					{
						name: 'Transfer Failed',
						value: 'transfer.failed',
						description: 'Occurs whenever a transfer failed.',
					},
					{
						name: 'Transfer Paid',
						value: 'transfer.paid',
						description:
							'Occurs after a transfer is paid. For Instant Payouts, the event will be sent on the next business day, although the funds should be received well beforehand.',
					},
					{
						name: 'Transfer Reversed',
						value: 'transfer.reversed',
						description: 'Occurs whenever a transfer is reversed, including partial reversals.',
					},
					{
						name: 'Transfer Updated',
						value: 'transfer.updated',
						description: "Occurs whenever a transfer's description or metadata is updated.",
					},
				],
			},
			{
				displayName: 'API Version',
				name: 'apiVersion',
				type: 'string',
				placeholder: '2025-05-28.basil',
				default: '',
				description:
					'The API version to use for requests. It controls the format and structure of the incoming event payloads that Stripe sends to your webhook. If empty, Stripe will use the default API version set in your account at the time, which may lead to event processing issues if the API version changes in the future.',
			},
		],
	};

	webhookMethods = {
		default: {
			async checkExists(this: IHookFunctions): Promise<boolean> {
				const webhookData = this.getWorkflowStaticData('node');

				if (webhookData.webhookId === undefined) {
					// No webhook id is set so no webhook can exist
					return false;
				}

				// Webhook got created before so check if it still exists
				const endpoint = `/webhook_endpoints/${webhookData.webhookId}`;

				try {
					await stripeApiRequest.call(this, 'GET', endpoint, {});
				} catch (error) {
					if (error.httpCode === '404' || error.message.includes('resource_missing')) {
						// Webhook does not exist
						delete webhookData.webhookId;
						delete webhookData.webhookEvents;
						delete webhookData.webhookSecret;

						return false;
					}

					// Some error occured
					throw error;
				}

				// If it did not error then the webhook exists
				return true;
			},
			async create(this: IHookFunctions): Promise<boolean> {
				const webhookUrl = this.getNodeWebhookUrl('default');

				const webhookDescription = `Created by n8n for workflow ID: ${this.getWorkflow().id}`;

				const events = this.getNodeParameter('events', []);

				const endpoint = '/webhook_endpoints';

				interface StripeWebhookBody {
					url: string | undefined;
					description: string;
					enabled_events: object | NodeParameterValue;
					api_version?: string;
					[key: string]: any;
				}

				const body: StripeWebhookBody = {
					url: webhookUrl,
					description: webhookDescription,
					enabled_events: events,
				};

				const apiVersion = this.getNodeParameter('apiVersion', '');
				if (apiVersion && apiVersion !== '') {
					body.api_version = apiVersion as string;
				}

				const responseData = await stripeApiRequest.call(this, 'POST', endpoint, body);

				if (
					responseData.id === undefined ||
					responseData.secret === undefined ||
					responseData.status !== 'enabled'
				) {
					// Required data is missing so was not successful
					throw new NodeApiError(this.getNode(), responseData as JsonObject, {
						message: 'Stripe webhook creation response did not contain the expected data.',
					});
				}

				const webhookData = this.getWorkflowStaticData('node');
				webhookData.webhookId = responseData.id as string;
				webhookData.webhookEvents = responseData.enabled_events as string[];
				webhookData.webhookSecret = responseData.secret as string;

				return true;
			},
			async delete(this: IHookFunctions): Promise<boolean> {
				const webhookData = this.getWorkflowStaticData('node');

				if (webhookData.webhookId !== undefined) {
					const endpoint = `/webhook_endpoints/${webhookData.webhookId}`;
					const body = {};

					try {
						await stripeApiRequest.call(this, 'DELETE', endpoint, body);
					} catch (error) {
						return false;
					}

					// Remove from the static workflow data so that it is clear
					// that no webhooks are registered anymore
					delete webhookData.webhookId;
					delete webhookData.webhookEvents;
					delete webhookData.webhookSecret;
				}

				return true;
			},
		},
	};

	async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
		const bodyData = this.getBodyData();
		const req = this.getRequestObject();

		if (!(await verifySignature.call(this))) {
			const res = this.getResponseObject();
			res.status(401).send('Unauthorized').end();
			return {
				noWebhookResponse: true,
			};
		}

		const events = this.getNodeParameter('events', []) as string[];
		const eventType = bodyData.type as string | undefined;

		if (eventType === undefined || (!events.includes('*') && !events.includes(eventType))) {
			// If not eventType is defined or when one is defined but we are not
			// listening to it do not start the workflow.
			return {};
		}

		return {
			workflowData: [this.helpers.returnJsonArray(req.body as IDataObject)],
		};
	}
}
