> For the complete documentation index, see [llms.txt](https://codemash.gitbook.io/codemash/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://codemash.gitbook.io/codemash/cloud/payments/triggers/new.md).

# Create a trigger

Create a payment trigger — pick the integrations and provider events, then the action (email, push, SMS, webhook, code, in-app event).

**Where:** Payments → Triggers → **Add New** · `/projects/<project>/payments/triggers/new`

## Before you start

* At least one [payment integration](/codemash/cloud/payments/integrations.md) whose **Webhook URL** is saved at the provider, with the events you want ticked there too. A trigger runs only for calls that reach Norbix.
* For **Send Email**: the Email module is on, with an [email template](/codemash/cloud/emails/templates.md) and an email integration (every project gets the Fake one, **Test Me**). For **Send Push Notification** / **Send SMS**: the same in that module. For **Call Webhook**: a destination in [Project → Settings → Webhooks](/codemash/cloud/project/settings/webhooks.md).
* In this example the email template `Payment received` (`tmpl_4JTWpS2OZVpQLSoQZ7EdWF`) has the subject `Payment received: @Model.Payment.Amount @Model.Payment.Currency` and a body that uses `@Model.Recipient.FirstName`, `@Model.Payment.Provider`, `@Model.Payment.EventName`, `@Model.Payment.Status` and `@Model.Payment.ProviderEventId`.

## Steps

1. Press **Add New**. Under **If this** → **Select trigger actions**, pick **When webhook call received**. The box below says *Usage: 'New\.Payment.\*'* — the payment facts the action gets.

   <figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-351bc7bea50d54a5891333ca5cc565435168d0b7%2Ftriggers-new-1.png?alt=media" alt="Add New Trigger: three event cards When order created, When order paid, When webhook call received (picked), the box When webhook call received with Usage: &#x27;New.Payment.*&#x27;, and the list For these integrations"><figcaption><p>The three event cards; <strong>When webhook call received</strong> is picked.</p></figcaption></figure>

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><strong>When order created</strong> and <strong>When order paid</strong> can be saved, but nothing in Norbix creates or pays orders today, so those triggers never run. Use <strong>When webhook call received</strong>.</p></div>
2. Under **For these integrations**, tick the integrations to listen to, here `Stripe test mode (Stripe)`. Leave all unticked to react to every payment integration, also the ones you connect later.
3. Under **For these events**, tick the provider events, here `payment_intent.succeeded`. The names are the provider's own; the list shows the events of the ticked integrations (or of every connected provider when none is ticked), each with a short description. Leave all unticked to react to every supported event.

   <figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-b09fa044b4bdb6bcc4337f80401b6b1182b54a63%2Ftriggers-new-2.png?alt=media" alt="For these integrations: Stripe test mode (Stripe) ticked, the other nine integrations not ticked"><figcaption><p>Only the Stripe integration is ticked.</p></figcaption></figure>
4. **Add activation code** (optional) adds code that runs first and can stop the trigger; it gets the payment fact as `New` (`New.status`, `New.amountMinor`, `New.currency`, `New.eventName`, …).
5. Under **... then**, open the action list and pick the action.

   <figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-5086db71548fdd202ddd11a6bf682695fcfafc6c%2Ftriggers-new-3.png?alt=media" alt="payment_intent.succeeded ticked in the Stripe event list, Add activation code, and the open action list: Run Code, Send Email, Send Push Notification, Send SMS, Call Webhook, Send In-App (Realtime / SSE)"><figcaption><p>The action list.</p></figcaption></figure>

   | Action                                                     | What it does                                                                                         |
   | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
   | **Run Code**                                               | Runs an installed marketplace function with the payment data.                                        |
   | **Send Email** / **Send Push Notification** / **Send SMS** | Sends a template to the recipients you choose; the payment facts fill the `@Model.Payment.*` tokens. |
   | **Call Webhook**                                           | POSTs a signed event to the project webhook destinations you tick.                                   |
   | **Send In-App (Realtime / SSE)**                           | Sends the event live to connected apps or AI agents.                                                 |
6. For **Send Email**, choose the recipients. The cards are **All users**, **Collection**, **Specified Users** and **Email Addresses**. For **Email Addresses**, type the address in **To: \***, here `billing@example.com`; **Single email strategy** sends each address its own email; **CC:** and **BCC:** are optional. Under **Template Details**, choose **Select template** (`Payment received`) and **Send in specific language** (leave **Each recipient's language**).

   <figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-c4d5605af8738ff8a3d8c6f5ae49b470013df050%2Ftriggers-new-4.png?alt=media" alt="Email Addresses picked, To billing@example.com, Single email strategy not ticked, CC and BCC empty, Template Details with Select template Payment received (Transactional)"><figcaption><p>Recipients and template.</p></figcaption></figure>
7. **Template Tokens** lists the tokens of the template. Give each one a value — Cloud keeps a yellow *Still missing* box until you do. `Recipient.FirstName` gets a real value (`Billing team`). For the `Payment.*` tokens type any short text (here `(amount)`, `(currency)`, …): the token picker has no payment values, and when the trigger runs Norbix adds the real values of the event to the email (`Payment.Amount` `20.00`, `Payment.Currency` `USD` for the test payment below).

   <figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-625d7f0e679fee2a923fde2d7fe9f109ca58f75b%2Ftriggers-new-5.png?alt=media" alt="Template Tokens: Payment.Amount (amount), Payment.Currency (currency), Recipient.FirstName Billing team, Payment.Provider (provider), Payment.EventName (event), Payment.Status (status), Payment.ProviderEventId (event id)"><figcaption><p>Every token has a value.</p></figcaption></figure>

   | Payment token                               | Example value from a Stripe test payment                            |
   | ------------------------------------------- | ------------------------------------------------------------------- |
   | `Payment.Provider`                          | `Stripe`                                                            |
   | `Payment.EventName`                         | `payment_intent.succeeded`                                          |
   | `Payment.ProviderEventId`                   | `evt_3UNbcLE3nllmwuCI1UR1GUEe`                                      |
   | `Payment.Status`                            | `Succeeded`                                                         |
   | `Payment.Amount` / `Payment.AmountMinor`    | `20.00` / `2000`                                                    |
   | `Payment.Currency`                          | `USD`                                                               |
   | `Payment.IntegrationId`                     | `int_5Fg01ggCM3kAfgeSD1NMwV`                                        |
   | `Payment.OccurredOn` / `Payment.ReceivedOn` | `2026-10-06T16:53:29Z` / `2026-10-06T16:53:30Z`                     |
   | `Payment.ExternalIds.<name>`                | `Payment.ExternalIds.paymentIntent` = `pi_3UNbcLE3nllmwuCI17RpYQpO` |
8. Under **Advanced settings**, **Send email on behalf of** sets who speaks in the message (`@Model.Initiator.User`; empty = you); **Select email provider** is set to the project default (**Test Me (Fake)** here).
9. Fill the trigger's own fields and press **Save**:

   | Field                    | Required | What it does                                             | Example                                                           |
   | ------------------------ | -------- | -------------------------------------------------------- | ----------------------------------------------------------------- |
   | Order                    | no       | Shown on the form, but not saved today — leave it empty. | —                                                                 |
   | Name the trigger         | yes      | The name in the list.                                    | `Email billing when a payment succeeds`                           |
   | Description              | no       | Free text.                                               | `Emails billing@example.com for every successful Stripe payment.` |
   | Is this trigger enabled? | no       | On: the trigger runs. Off: saved but quiet.              | on                                                                |

   <figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-f50eecdc70b3b5e9d33b23b164b0010dc577c35c%2Ftriggers-new-6.png?alt=media" alt="Lower part of the form: Select email provider Test Me (Fake), Order empty, Name the trigger Email billing when a payment succeeds, Description, the switch Is this trigger enabled? drawn off, Cancel and Save"><figcaption><p>The trigger's own fields.</p></figcaption></figure>

{% hint style="warning" %}
A new trigger starts **enabled**. Today the **Is this trigger enabled?** switch is still drawn in the off position on a new trigger; that is a display fault — the trigger is saved enabled (the list shows **Enabled: Yes**). Disable it from the **Actions** menu if it should not run yet.
{% endhint %}

## Result

Cloud goes back to **Payments Triggers** with the new row (**When webhook call received**, **Send Email**, **Enabled: Yes**).

<figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-bbc9babeeec299ad51fadaa10b615827eb37573f%2Ftriggers-new-7.png?alt=media" alt="Payments Triggers list with Email billing when a payment succeeds, When webhook call received, Send Email, Enabled Yes"><figcaption><p>The new trigger in the list.</p></figcaption></figure>

The next matching call runs it. In the example, two Stripe test-mode payments (`stripe trigger payment_intent.succeeded` with the [Stripe CLI](https://docs.stripe.com/stripe-cli)) reached the integration (**Received webhooks**: **200**, **Processed.**) and the trigger created one email campaign each, listed in **Email → Campaigns** with the template `Payment received`.

<figure><img src="https://712692422-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHy372bqsaex2cqS3ikhL%2Fuploads%2Fgit-blob-ea439d3e1a523c2d46b38f0cba18935f79e97a02%2Ftriggers-new-8.png?alt=media" alt="Email Campaigns list: three rows Started, Specific Email Addresses, template Payment received, integration Test Me (Default)"><figcaption><p>The email campaigns the payment triggers created.</p></figcaption></figure>

{% hint style="warning" %}
Today an email sent by a payment trigger stays at **Started** and is never delivered: the webhook call has no signed-in user, and the email sender stops when it finds none. The trigger itself runs (the Hub log says *Trigger ran: its Email action was sent on*) and the campaign carries the payment values; only the delivery is missing. The other actions were not tried on this page.
{% endhint %}

## Change or remove it later

* **Edit** — [Edit a trigger](/codemash/cloud/payments/triggers/edit.md).
* **Disable / Enable** — [Enable or disable a trigger](/codemash/cloud/payments/triggers/enable.md).
* **Delete** — [Delete a trigger](/codemash/cloud/payments/triggers/delete.md).

## Do it from code

```ts
const { id } = await norbix.hub.payments.savePaymentsTrigger({
  trigger: {
    type: 'Payments',
    when: 'OnWebhookCallReceived',
    name: 'Email billing about disputes',
    isEnabled: true,
    integrations: ['int_5Fg01ggCM3kAfgeSD1NMwV'], // Stripe test mode; omit = every integration
    events: ['charge.dispute.created'],           // omit = every event
    action: {
      type: 'Email',
      templateId: 'tmpl_4JTWpS2OZVpQLSoQZ7EdWF',  // Payment received
      integrationId: 'int_30rujXt91ZO6soFXlqDpJa', // the email provider (Test Me)
      deliverySettings: {
        recipientsSourceType: 'Email',
        recipients: ['billing@example.com'],
        mappedTokens: [{ key: 'Recipient.FirstName', value: 'Billing team', resolver: 'Custom' }],
      },
    },
  },
});
console.log(id); // trg_…
```

```sh
norbix hub payments trigger save --trigger '{"type":"Payments","when":"OnWebhookCallReceived","name":"Temp CLI trigger","isEnabled":true,"events":["invoice.paid"],"action":{"type":"Email","templateId":"tmpl_4JTWpS2OZVpQLSoQZ7EdWF","integrationId":"int_30rujXt91ZO6soFXlqDpJa","deliverySettings":{"recipientsSourceType":"Email","recipients":["billing@example.com"],"mappedTokens":[{"key":"Recipient.FirstName","value":"Billing team","resolver":"Custom"}]}}}'
```

An event name the provider does not have is refused. The client setup is on the [Payments page](/codemash/cloud/payments.md#use-it-from-code). API: [Save Payments Trigger](/codemash/api-reference/payments/triggers/save-payments-trigger.md)
