import { IHookFunctions, IWebhookFunctions, } from 'n8n-core'; import { IDataObject, INodeTypeDescription, INodeType, IWebhookResponseData, } from 'n8n-workflow'; import { stripeApiRequest, } from './helpers'; export class StripeTrigger implements INodeType { description: INodeTypeDescription = { displayName: 'Stripe Trigger', name: 'stripeTrigger', icon: 'file:stripe.png', group: ['trigger'], version: 1, description: 'Handle Stripe events via webhooks', defaults: { name: 'Stripe Trigger', color: '#32325d', }, inputs: [], outputs: ['main'], credentials: [ { name: 'stripeApi', required: true, } ], webhooks: [ { name: 'default', httpMethod: 'POST', reponseMode: 'onReceived', path: 'webhook', }, ], properties: [ { displayName: 'Events', name: 'events', type: 'multiOptions', required: true, default: [], description: 'The event to listen to.', 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 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." } ] } ], }; // @ts-ignore (because of request) webhookMethods = { default: { async checkExists(this: IHookFunctions): Promise { 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 (e) { if (e.message.includes('[404]:')) { // Webhook does not exist delete webhookData.webhookId; delete webhookData.webhookEvents; delete webhookData.webhookSecret; return false; } // Some error occured throw e; } // If it did not error then the webhook exists return true; }, async create(this: IHookFunctions): Promise { const webhookUrl = this.getNodeWebhookUrl('default'); const events = this.getNodeParameter('events', []); const endpoint = '/webhook_endpoints'; const body = { url: webhookUrl, enabled_events: events, }; let responseData; try { responseData = await stripeApiRequest.call(this, 'POST', endpoint, body); } catch (e) { throw e; } if (responseData.id === undefined || responseData.secret === undefined || responseData.status !== 'enabled') { // Required data is missing so was not successful throw new Error('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 { 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 (e) { return false; } // Remove from the static workflow data so that it is clear // that no webhooks are registred anymore delete webhookData.webhookId; delete webhookData.webhookEvents; delete webhookData.webhookSecret; } return true; }, }, }; async webhook(this: IWebhookFunctions): Promise { const bodyData = this.getBodyData() as IDataObject; const req = this.getRequestObject(); 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) ], }; } }