Getting started

If you have not yet set up Trigger.dev in your project, go to the quick start guide.

Installation

npm add @trigger.dev/stripe@latest

Authentication

The Stripe integration supports secret API Keys

import { Stripe } from "@trigger.dev/stripe";

const stripe = new Stripe({
  id: "stripe",
  apiKey: process.env.STRIPE_API_KEY!,
});

Triggers

The Stripe integration exposes a number of triggers that can be used on a job, powered by Stripe webhooks.

We recommend testing Stripe payloads using Stripe Shell, Stripe’s browser-based shell with the Stripe CLI pre-installed.

client.defineJob({
  id: "stripe-price",
  name: "Stripe Price",
  version: "0.1.0",
  trigger: stripe.onPriceCreated(),
  run: async (payload, io, ctx) => {
    console.log(ctx.event.name); // "price.created"
  },
});

As you can see above, the job will be triggered on the price.created event. If you’d like to trigger a job on multiple events, you can use the aggregate version of the trigger:

client.defineJob({
  id: "stripe-price",
  name: "Stripe Price",
  version: "0.1.0",
  trigger: stripe.onPrice(),
  run: async (payload, io, ctx) => {
    console.log(ctx.event.name); // "price.created", "price.updated", "price.deleted"
  },
});

“Aggregate” triggers also give you the ability to filter on specific events:

client.defineJob({
  id: "stripe-price",
  name: "Stripe Price",
  version: "0.1.0",
  trigger: stripe.onPrice({
    events: ["price.created", "price.updated"],
  }),
  run: async (payload, io, ctx) => {
    console.log(ctx.event.name); // "price.created", "price.updated"
  },
});

Available triggers are listed below:

Function NamePayload ObjectEventsAggregate Version
onChargeChargecharge.succeeded, charge.failed, charge.captured, charge.refunded, charge.updated✔️
onChargeSucceededChargecharge.succeededonCharge
onChargeFailedChargecharge.failedonCharge
onChargeCapturedChargecharge.capturedonCharge
onChargeRefundedChargecharge.refundedonCharge
onChargeUpdatedChargecharge.updatedonCharge
onProductProductproduct.created, product.updated, product.deleted✔️
onProductCreatedProductproduct.createdonProduct
onProductUpdatedProductproduct.updatedonProduct
onProductDeletedProductproduct.deletedonProduct
onPricePriceprice.created, price.updated, price.deleted✔️
onPriceCreatedPriceprice.createdonPrice
onPriceUpdatedPriceprice.updatedonPrice
onPriceDeletedPriceprice.deletedonPrice
onCheckoutSessionCheckoutSessioncheckout.session.completed, checkout.session.async_payment_succeeded, checkout.session.async_payment_failed, checkout.session.expired✔️
onCheckoutSessionCompletedCheckoutSessioncheckout.session.completedonCheckoutSession
onCheckoutSessionExpiredCheckoutSessioncheckout.session.expiredonCheckoutSession
onCustomerSubscriptionSubscriptioncustomer.subscription.created, customer.subscription.updated, customer.subscription.deleted, customer.subscription.paused, customer.subscription.pending_updated_applied, customer.subscription.pending_update_expired, customer.subscription.resumed✔️
onCustomerSubscriptionCreatedSubscriptioncustomer.subscription.createdonCustomerSubscription
onCustomerSubscriptionUpdatedSubscriptioncustomer.subscription.updatedonCustomerSubscription
onCustomerSubscriptionDeletedSubscriptioncustomer.subscription.deletedonCustomerSubscription
onCustomerSubscriptionPausedSubscriptioncustomer.subscription.pausedonCustomerSubscription
onCustomerSubscriptionPendingSubscriptioncustomer.subscription.pending_updated_applied, customer.subscription.pending_update_expiredonCustomerSubscription
onCustomerSubscriptionResumedSubscriptioncustomer.subscription.resumedonCustomerSubscription
onCustomerCustomercustomer.created, customer.updated, customer.deleted✔️
onCustomerCreatedCustomercustomer.createdonCustomer
onCustomerUpdatedCustomercustomer.updatedonCustomer
onCustomerDeletedCustomercustomer.deletedonCustomer
onExternalAccountCard or Bank Accountaccount.external_account.created, account.external_account.updated, account.external_account.deleted✔️
onExternalAccountCreatedCard or Bank Accountaccount.external_account.createdonExternalAccount
onExternalAccountUpdatedCard or Bank Accountaccount.external_account.updatedonExternalAccount
onExternalAccountDeletedCard or Bank Accountaccount.external_account.deletedonExternalAccount
onPersonPersonaccount.person.created, account.person.updated, account.person.deleted✔️
onPersonCreatedPersonaccount.person.createdonPerson
onPersonUpdatedPersonaccount.person.updatedonPerson
onPersonDeletedPersonaccount.person.deletedonPerson
onAccountUpdatedAccountaccount.updatedN/A
onPaymentIntentPaymentIntentpayment_intent.created, payment_intent.succeeded, payment_intent.payment_failed, payment_intent.canceled, payment_intent.processing, payment_intent.amount_capturable_updated, payment_intent.requires_action, payment_intent.partially_funded✔️
onPaymentIntentCreatedPaymentIntentpayment_intent.createdonPaymentIntent
onPaymentIntentSucceededPaymentIntentpayment_intent.succeededonPaymentIntent
onPaymentIntentPaymentFailedPaymentIntentpayment_intent.payment_failedonPaymentIntent
onPaymentIntentCanceledPaymentIntentpayment_intent.canceledonPaymentIntent
onPaymentIntentProcessingPaymentIntentpayment_intent.processingonPaymentIntent
onPaymentIntentRequiresActionPaymentIntentpayment_intent.requires_actiononPaymentIntent
onPaymentIntentAmountCapturableUpdatedPaymentIntentpayment_intent.amount_capturable_updatedonPaymentIntent
onPaymentIntentPartiallyFundedPaymentIntentpayment_intent.partially_fundedonPaymentIntent
onPayoutPayoutpayout.created, payout.updated, payout.canceled, payout.paid, payout.failed, payout.reconciliation_completed✔️
onPayoutCreatedPayoutpayout.createdonPayout
onPayoutUpdatedPayoutpayout.updatedonPayout
onPayoutCanceledPayoutpayout.canceledonPayout
onPayoutPaidPayoutpayout.paidonPayout
onPayoutFailedPayoutpayout.failedonPayout
onPayoutReconciliationCompletedPayoutpayout.reconciliation_completedonPayout
onInvoiceInvoiceinvoice.created, invoice.finalized, invoice.finalization_failed, invoice.deleted, invoice.marked_uncollectible, invoice.paid, invoice.payment_action_required, invoice.payment_failed, invoice.payment_succeeded, invoice.sent, invoice.upcoming, invoice.voided, invoiceitem.created, invoiceitem.deleted✔️
onInvoiceCreatedInvoiceinvoice.createdonInvoice
onInvoiceFinalizedInvoiceinvoice.finalizedonInvoice
onInvoiceFinalizationFailedInvoiceinvoice.finalization_failedonInvoice
onInvoiceDeletedInvoiceinvoice.deletedonInvoice
onInvoiceMarkedUncollectibleInvoiceinvoice.marked_uncollectibleonInvoice
onInvoicePaidInvoiceinvoice.paidonInvoice
onInvoicePaymentActionRequiredInvoiceinvoice.payment_action_requiredonInvoice
onInvoicePaymentFailedInvoiceinvoice.payment_failedonInvoice
onInvoicePaymentSucceededInvoiceinvoice.payment_succeededonInvoice
onInvoiceSentInvoiceinvoice.sentonInvoice
onInvoiceUpcomingInvoiceinvoice.upcomingonInvoice
onInvoiceVoidedInvoiceinvoice.voidedonInvoice
onInvoiceItemCreatedInvoiceIteminvoiceitem.createdN/A
onInvoiceItemDeletedInvoiceIteminvoiceitem.deletedN/A

If there are any triggers missing that you’d like to see added, please open a new GitHub Issue

Filtering

All the Stripe triggers take an optional filter parameter that allows you to only run the job when the filter matches the event payload:

// Only trigger when the currency is USD
client.defineJob({
  id: "stripe-on-subscription-created",
  name: "Stripe On Subscription Created",
  version: "0.1.0",
  trigger: stripe.onCustomerSubscriptionCreated({
    filter: {
      currency: ["usd"],
    },
  }),
  run: async (payload, io, ctx) => {
    await io.logger.info("ctx", { ctx });
  },
});

Check out our Event Filter docs for more information on how to use the filter.

Tasks

You can make reliable calls to the Stripe API inside of jobs using the exposed stripe tasks:

const stripe = new Stripe({
  id: "stripe",
  apiKey: process.env["STRIPE_API_KEY"]!,
});

client.defineJob({
  id: "stripe-example-1",
  name: "Stripe Example 1",
  version: "0.1.0",
  trigger: eventTrigger({
    name: "stripe.example",
    schema: z.object({
      customerId: z.string(),
      source: z.string(),
    }),
  }),
  integrations: {
    stripe,
  },
  run: async (payload, io, ctx) => {
    await io.stripe.createCharge("create-charge", {
      amount: 100,
      currency: "usd",
      source: payload.source,
      customer: payload.customerId,
    });
  },
});

We automatically fill in the idempotencyKey for you, so we can gaurentee that the API call will only be executed once.

Available tasks are listed below:

Function NameDescription
createChargeUse the Payment Intents API to initiate a new payment instead of using this method. Confirmation of the PaymentIntent creates the Charge object used to request payment, so this method is limited to legacy integrations.
createCustomerCreates a new customer object
updateCustomerUpdates the specified customer by setting the values of the parameters passed
retrieveSubscriptionRetrieves the subscription with the given ID.
createCheckoutSessionCreates a new Checkout Session object.

If there are any tasks missing that you’d like to see added, please open a new GitHub Issue

Using the underlying Stripe client

You can use the underlying client to do anything the stripe-node client supports by using runTask on the integration:

const stripe = new Stripe({
  id: "stripe",
  apiKey: process.env["STRIPE_API_KEY"]!,
});

client.defineJob({
  id: "stripe-example-1",
  name: "Stripe Example 1",
  version: "0.1.0",
  trigger: eventTrigger({
    name: "stripe.example",
  }),
  integrations: {
    stripe,
  },
  run: async (payload, io, ctx) => {
    const price = await io.stripe.runTask(
      "create-price",
      async (client, task) => {
        return client.prices.create(
          {
            unit_amount: 2000,
            currency: "usd",
            product_data: {
              name: "T-shirt",
            },
          },
          {
            idempotencyKey: task.idempotencyKey,
          }
        );
      },
      //this is optional, it will appear on the Run page
      { name: "Create Price" }
    );
  },
});

Make sure to pass the idempotencyKey to the underlying client to ensure that the API call is only executed once. This is only needed for mutating API calls.

Example jobs

Code examples

Check out pre-built jobs using Stripe in our API section.