# Next Commerce: Apps and webhooks > Building apps with OAuth, app manifests and settings, service integrations (fulfillment, disputes, attribution), and every webhook event with its payload. This is one of 6 domain bundles derived from the platform capability map at https://developers.nextcommerce.com/capabilities.json (generated 2026-09-03). The other bundles are listed at https://developers.nextcommerce.com/llms.txt. Merchant and operator guides are on https://docs.nextcommerce.com; the changelog is https://docs.nextcommerce.com/changelog. The Admin API contract is the OpenAPI file at https://developers.nextcommerce.com/api/admin/2024-04-01.yaml. ## Capabilities ### Apps and OAuth (id: apps) Apps extend a store through OAuth, a manifest, settings, snippets, and storefront extensions, and can act as fulfillment, dispute, or marketing-attribution services. Merchants install apps from the dashboard; App Kit is the developer toolchain. Status: available. Audiences: developer. Links verified: 2026-09-03. Caveats: - The merchant site documents individual apps (Klaviyo, ShipStation, Gorgias, and others) under /docs/apps/, not app installation in general. Developer guides (developers.nextcommerce.com): - https://developers.nextcommerce.com/docs/apps - https://developers.nextcommerce.com/docs/apps/app-development-flow - https://developers.nextcommerce.com/docs/apps/app-kit - https://developers.nextcommerce.com/docs/apps/manifest - https://developers.nextcommerce.com/docs/apps/settings - https://developers.nextcommerce.com/docs/apps/snippets - https://developers.nextcommerce.com/docs/apps/assets - https://developers.nextcommerce.com/docs/apps/review - https://developers.nextcommerce.com/docs/apps/event-tracking - https://developers.nextcommerce.com/docs/apps/oauth - https://developers.nextcommerce.com/docs/apps/oauth/getting-started - https://developers.nextcommerce.com/docs/apps/oauth/install-flows - https://developers.nextcommerce.com/docs/apps/oauth/session-auth - https://developers.nextcommerce.com/docs/apps/guides/server-to-server-apps - https://developers.nextcommerce.com/docs/apps/guides/storefront-extension - https://developers.nextcommerce.com/docs/apps/guides/marketing-attribution Admin API operations, version 2024-04-01 (5): - [GET /apps/{clientId}/ — Retrieve a object of app.](https://developers.nextcommerce.com/docs/admin-api/reference/apps/appsRetrieve) - [GET /apps/{clientId}/settings/ — Retrieve a object of all app settings.](https://developers.nextcommerce.com/docs/admin-api/reference/apps/appsSettingsRetrieve) - [PUT /apps/{clientId}/settings/ — Update an existing app settings.](https://developers.nextcommerce.com/docs/admin-api/reference/apps/appsSettingsUpdate) - [PATCH /apps/{clientId}/settings/ — Partially update an existing app settings.](https://developers.nextcommerce.com/docs/admin-api/reference/apps/appsSettingsPartialUpdate) - [DELETE /apps/{clientId}/settings/ — Delete an existing app settings.](https://developers.nextcommerce.com/docs/admin-api/reference/apps/appsSettingsDestroy) Webhook events (1): - [app.uninstalled](https://developers.nextcommerce.com/docs/webhooks/reference/apps/app.uninstalled) ### Webhooks (id: webhooks) Stores send signed JSON webhooks for events on orders, customers, subscriptions, transactions, disputes, fulfillment, products, gateways, tickets, exports, apps, and the store itself. Merchants configure endpoints in the dashboard; developers manage them through the Admin API and verify the X-29Next-Signature header. Status: available. Audiences: merchant, developer. Links verified: 2026-09-03. Merchant and operator guides (docs.nextcommerce.com): - https://docs.nextcommerce.com/docs/build-a-store/technical-settings/configure-webhooks Developer guides (developers.nextcommerce.com): - https://developers.nextcommerce.com/docs/webhooks Admin API operations, version 2024-04-01 (6): - [GET /webhooks/ — Retrieve a list of webhooks.](https://developers.nextcommerce.com/docs/admin-api/reference/webhooks/webhooksList) - [POST /webhooks/ — Create a new webhook.](https://developers.nextcommerce.com/docs/admin-api/reference/webhooks/webhooksCreate) - [GET /webhooks/{id}/ — Retrieve a webhook.](https://developers.nextcommerce.com/docs/admin-api/reference/webhooks/webhooksRetrieve) - [PUT /webhooks/{id}/ — Update an existing webhook.](https://developers.nextcommerce.com/docs/admin-api/reference/webhooks/webhooksUpdate) - [PATCH /webhooks/{id}/ — Partial update an existing webhook.](https://developers.nextcommerce.com/docs/admin-api/reference/webhooks/webhooksPartialUpdate) - [DELETE /webhooks/{id}/ — Delete an existing webhook.](https://developers.nextcommerce.com/docs/admin-api/reference/webhooks/webhooksDestroy) Webhook events (24): - [app.uninstalled](https://developers.nextcommerce.com/docs/webhooks/reference/apps/app.uninstalled) - [cart.abandoned](https://developers.nextcommerce.com/docs/webhooks/reference/carts/cart.abandoned) - [customer.created](https://developers.nextcommerce.com/docs/webhooks/reference/customers/customer.created) - [customer.redacted](https://developers.nextcommerce.com/docs/webhooks/reference/customers/customer.redacted) - [customer.updated](https://developers.nextcommerce.com/docs/webhooks/reference/customers/customer.updated) - [dispute.created](https://developers.nextcommerce.com/docs/webhooks/reference/payments/dispute.created) - [dispute.updated](https://developers.nextcommerce.com/docs/webhooks/reference/payments/dispute.updated) - [export.created](https://developers.nextcommerce.com/docs/webhooks/reference/exports/export.created) - [fulfillment.created](https://developers.nextcommerce.com/docs/webhooks/reference/fulfillment/fulfillment.created) - [fulfillment.updated](https://developers.nextcommerce.com/docs/webhooks/reference/fulfillment/fulfillment.updated) - [gateway.created](https://developers.nextcommerce.com/docs/webhooks/reference/payments/gateway.created) - [gateway.updated](https://developers.nextcommerce.com/docs/webhooks/reference/payments/gateway.updated) - [order.created](https://developers.nextcommerce.com/docs/webhooks/reference/orders/order.created) - [order.updated](https://developers.nextcommerce.com/docs/webhooks/reference/orders/order.updated) - [product.created](https://developers.nextcommerce.com/docs/webhooks/reference/products/product.created) - [product.deleted](https://developers.nextcommerce.com/docs/webhooks/reference/products/product.deleted) - [product.updated](https://developers.nextcommerce.com/docs/webhooks/reference/products/product.updated) - [store.updated](https://developers.nextcommerce.com/docs/webhooks/reference/store/store.updated) - [subscription.created](https://developers.nextcommerce.com/docs/webhooks/reference/subscriptions/subscription.created) - [subscription.updated](https://developers.nextcommerce.com/docs/webhooks/reference/subscriptions/subscription.updated) - [ticket.created](https://developers.nextcommerce.com/docs/webhooks/reference/support/ticket.created) - [ticket.updated](https://developers.nextcommerce.com/docs/webhooks/reference/support/ticket.updated) - [transaction.created](https://developers.nextcommerce.com/docs/webhooks/reference/payments/transaction.created) - [transaction.updated](https://developers.nextcommerce.com/docs/webhooks/reference/payments/transaction.updated) ## Pages The full text of every developer page cited above, in the order listed. # Apps (https://developers.nextcommerce.com/docs/apps) > **Note:** Apps and supporting tools are in Public Beta. If you have questions or run into any issues, don't hesitate to reach out to [support@29next.com](mailto:support@29next.com). More documentation, examples, and tools are on the way. Apps let you extend built-in functionality of the Next Commerce platform to solve merchant challenges and ship new functionality as an easily installed app. ### Apps Allow You To [#apps-allow-you-to] #### Extend Core Functionality [#extend-core-functionality] Use [Webhooks](https://developers.nextcommerce.com/docs/webhooks) to subscribe to events and the [Admin API](https://developers.nextcommerce.com/docs/admin-api) to add new logic and integrations, see the [Server to Server Guide](https://developers.nextcommerce.com/docs/apps/guides/server-to-server-apps). #### Extend Storefront Themes [#extend-storefront-themes] Use [Event Tracking](https://developers.nextcommerce.com/docs/apps/event-tracking) or [App Snippets](https://developers.nextcommerce.com/docs/apps/snippets) to extend storefront themes, see the [Storefront Extension Guide](https://developers.nextcommerce.com/docs/apps/guides/storefront-extension). ### Example Apps [#example-apps] We have full-featured, open-source example apps that provide complete code examples for many of the concepts needed to build apps. | Example Apps | Description | Link | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | Example S2S App | Server-to-server example covering [OAuth flow](https://developers.nextcommerce.com/docs/apps/oauth), [session tokens](https://developers.nextcommerce.com/docs/apps/oauth/session-auth), [remote settings](https://developers.nextcommerce.com/docs/apps/settings), [webhook setup](https://developers.nextcommerce.com/docs/webhooks), and [verification](https://developers.nextcommerce.com/docs/webhooks#verifying-webhook-requests). | [View](https://github.com/NextCommerceCo/example-app) | | Google Analytics 4 | Demonstrates [snippets](https://developers.nextcommerce.com/docs/apps/snippets) and [event tracking](https://developers.nextcommerce.com/docs/apps/event-tracking) for storefront integrations. | [View](https://github.com/NextCommerceCo/google-analytics-4) | | Fulfillment Service App | Demonstrates the [OAuth flow](https://developers.nextcommerce.com/docs/apps/oauth) and the [fulfillment flow](https://developers.nextcommerce.com/docs/apps/guides/fulfillment-service#fulfillment-flow-detail) using the [Fulfillment APIs](https://developers.nextcommerce.com/docs/admin-api/reference/fulfillment/fulfillmentOrdersList). | [View](https://github.com/NextCommerceCo/demo-fulfillment-service-app) | ### App Developer Reference Guides [#app-developer-reference-guides] - [Server to Server Apps](https://developers.nextcommerce.com/docs/apps/guides/server-to-server-apps) - [Storefront Extension Apps](https://developers.nextcommerce.com/docs/apps/guides/storefront-extension) - [Dispute Service Apps](https://developers.nextcommerce.com/docs/apps/guides/dispute-service) - [Fulfillment Service Apps](https://developers.nextcommerce.com/docs/apps/guides/fulfillment-service) - [Marketing Attribution Apps](https://developers.nextcommerce.com/docs/apps/guides/marketing-attribution) # Development Flow (https://developers.nextcommerce.com/docs/apps/app-development-flow) Like any software, Apps require initial development and then ongoing maintenance and improvements. Below is an overview of how to manage develop and release new versions of your app after it's already been installed and live in production. ### Development Stores [#development-stores] App development stores are stores linked to your app for quick iterations, testing and reviewing functionality. **App changes are automatically pushed to your development stores** When developing your app, you'll be using App Kit to `nak build` and `nak push` your latest changes to Next Commerce. Your app will automatically updated on your development store for a quick feedback loop and reviewing your latest changes. **App changes are not automatically pushed to existing stores with your app installed** This is to ensure developers have a safe path add new features, test on your development store, and [create a release once](#releases) you're ready. :handshake: > **Warning:** You should always test and verify your latest changes on your development store to make sure that everything is working as expected before creating a release. ### Releases [#releases] Once you're confident with your app and tested it on your development store, you can create a **Release** on the App detail page in your Partner account. Releases are versioned snapshots of your App that can be installed on public stores and also trigger updates for existing installations. Store's always install the latest version of your app. #### Versioning [#versioning] App versions follow [semantic versioning](https://semver.org/) which allows app developers to create and track releases of their app. App version's should always increase to trigger an available update for stores that have already the app installed. #### App Updates [#app-updates] If store already has your app installed and you create a new release, existing app installations will be able to update to the latest version. ### Development & Release Flow [#development--release-flow] Below is a diagram to highlight the workflow for creating your first app, reviewing it on your development store, and creating point releases to distribute your app to production stores. ```mermaid flowchart TD A[Developer] --> B[Push Update] B --> |Auto| C{{Development Store Review}} C ---> A C -- Review Passed --> D[Create New Release] D -- Update Available--> E[App Update Available In Stores] ``` # App Kit (https://developers.nextcommerce.com/docs/apps/app-kit) App Kit is a command line tool for developers to build and maintain apps that extend storefront themes with [Event Trackers](https://developers.nextcommerce.com/docs/apps/event-tracking). > **Warning (Not Required for Server to Server Apps):** App Kit is only required for Apps that extend to the storefront with App Snippets, [Server to Server Apps](https://developers.nextcommerce.com/docs/apps/guides/server-to-server-apps) do not need to use App Kit to complete the Oauth Flow for your App to access the Admin API. > **Note:** [See Full Instructions on Github](https://github.com/NextCommerceCo/app-kit) or [Install App Kit from PyPi](https://pypi.org/project/next-app-kit/) ## Installation [#installation] App Kit is a python package available on [PyPi](https://pypi.org/project/next-app-kit/) If you already have `python` and `pip`, install with the following command: ```bash title="Installation" pip install next-app-kit ``` #### Mac OSX Requirements [#mac-osx-requirements] See how to install `python` and `pip` with [HomeBrew](https://docs.brew.sh/Homebrew-and-Python#python-3x). Once you have completed this step you can install using the `pip` instructions above. #### Windows Requirements [#windows-requirements] See how to install `python` and `pip` with [Chocolatey](https://python-docs.readthedocs.io/en/latest/starting/install3/win.html). Once you have completed this step you can install using the `pip` instructions above. ## Usage [#usage] With the package installed, you can now use the commands inside your app directory to build and push your app updates. | Commands | Description | | ----------- | ------------------------------------------------------- | | `nak setup` | Configure current directory with an app in your account | | `nak build` | build new app zip file | | `nak push` | push latest app zip file to Next Commerce platform | #### Setup [#setup] Configures the current directory with necessary data to push the app files to Next Commerce. **Data collected by the `setup` command:** * **App Client ID** - retrieve this from the app in your partner account. * **Email** - your email used to access your partner account. * **Password** - your password used to access your partner account. #### Build [#build] Creates a new version (zip of the current directory files) to prepare your app to be pushed to Next Commerce. #### Push [#push] Pushes the latest version to Next Commerce and to your development stores to review and test your app. # Manifest Reference (https://developers.nextcommerce.com/docs/apps/manifest) App manifest.json is used for apps extending the storefront to configure HTML snippets that can be injected into storefront themes through [app\_hooks](https://developers.nextcommerce.com/docs/storefront/themes/templates/tags#app_hook). You can also add settings that can generate a settings page in the store dashboard to configure your app in the case your app only extends the storefront and doesn't have a server side integration. > **Note:** To upload your snippets and manifest.json, install [App Kit](https://developers.nextcommerce.com/docs/apps/app-kit) to zip your snippet files and push them to Next Commerce. ## Manifest Reference [#manifest-reference] The manifest.json file is used to configure your app. ```json title="Example manifest.json" { "storefront_event_tracker": "tracking.js", "locations": { "storefront": { "global_header": "snippets/global-header.html" } }, "settings_schema": [ { "name": "enable_app", "type": "checkbox", "label": "Enable Custom Optimizer App", "help_text": "", "default": false }, { "name": "example_setting", "type": "text", "label": "Example App Text Setting", "default": "", "required": 1, "help_text": "", "max_length": 250 } ] } ``` ## Manifest Properties [#manifest-properties] ### storefront\_event\_tracker [#storefront_event_tracker] Specify a javascript file to install a storefront [Event Tracker](https://developers.nextcommerce.com/docs/storefront/event-tracking) to be installed to track user behavior on the storefront and ecommerce related user behavior. ```json title="Example Storefront Event Tracker" "storefront_event_tracker": "tracking.js", ``` ### locations [#locations] Specifies and maps App Snippets that extend Storefront theme templates. See Theme [app\_hook reference](https://developers.nextcommerce.com/docs/storefront/themes/templates/tags#app_hook) for a full list of supported Storefront Theme locations. ```json title="Example locations" "locations": { "storefront": { "global_header": "snippets/global-header.html", } } ``` > **Warning:** App Hook Locations are limited to only extending a themes header and do not have access to tracking events, consider using an [Event Tracker](https://developers.nextcommerce.com/docs/storefront/event-tracking) instead. ### settings\_schema [#settings_schema] Specifies the settings schema used for storing local settings data within the app that can be referenced in snippets. The settings schema will generate a form available to store admins to add settings for their store. Server side apps also will have access to an App Settings API that can be used to push settings values directly to stores. ```json title="Example settings_schema" "settings_schema": [ { "name": "enable_app", "type": "checkbox", "label": "Enable Custom App", "help_text": "", "default": false }, { "name": "example_setting", "type": "text", "label": "Example App Text Setting", "default": "", "required": 1, "help_text": "", "max_length": 250 } ], ``` # Settings Reference (https://developers.nextcommerce.com/docs/apps/settings) App Settings allow you to define settings that you want users to configure and store with your app. Settings should be defined in your [manifest.json](https://developers.nextcommerce.com/docs/apps/manifest) file which will automatically create a form for your app to be configured in the dashboard. ### Example Usage [#example-usage] At this time, the primary use case of settings is to allow apps to store settings data that can then be used with snippets. This makes it possible to extend storefront theme's natively through the use of that are rendered in themes yet fully contained and controlled by your app. :tada: ```json title="Example Settings Schema" "settings_schema": [ { "name": "custom_app_id_enabled", "type": "checkbox", "label": "Enable My Custom App", "help_text": "", "default": false }, { "name": "custom_app_id", "type": "text", "label": "Example App Text Setting", "default": "", "required": 1, "help_text": "", "max_length": 250 } ] ``` You can then use the settings in your app snippets. ```javascript title="Example Settings Usage in Snippet" // access your app settings through app.settings. if (app.settings.custom_app_id_enabled) { console.log(app.settings.custom_app_id); } ``` > **Note:** For Sever to Server Apps with access to the Admin API, you can update the app settings values stored in the database on the Admin API allowing you to configure the app from your external application. ### Reference [#reference] | Attribute | Required | Description | | ------------ | -------- | ---------------------------------------------------------------------------------------------------- | | `type` | Yes | Type of form input, see Input Types. | | `name` | Yes | Name of the setting and key for access in template settings object variable. | | `label` | Yes | Theme settings form input label. | | `help_text` | No | Theme settings form input help text that shows below the input. | | `required` | No | JSON boolean, accepts true or false, false by default. | | `default` | No | Default value for the setting. | | `options` | No | List of `key:value` pairs for options. Applicable to radio and select field types for their choices. | | `max_length` | No | Applicable to `text` field types to limit the length of text input. | | `max_value` | No | Applicable to number field types to limit the max value. | | `min_value` | No | Applicable to number field types to set a min value. | ### Input Types [#input-types] Settings schema input types map to input fields that will be rendered in the theme settings form in the dashboard. #### text [#text] ```json title="text" { "type": "text", "name": "custom_app_id", "label": "App Account ID", "help_text": "Can be found in your app settings.", "max_length": 250, "required": true, "default": "" } ``` #### textarea [#textarea] ```json title="textarea" { "type": "textarea", "name": "description", "label": "Description", "help_text": "Example input textarea", "default": "Test" } ``` #### checkbox [#checkbox] ```json title="checkbox" { "name": "enable_cookie_msg", "label": "Enable Cookie Message Pop", "help_text": "Enable cookie message to site visitors.", "type": "checkbox", "default": true } ``` #### number [#number] ```json title="number" { "type": "number", "name": "homepage_testimonials_count", "label": "Homepage Number Testimonials to Show", "help_text": "Control the number of homepage testimonials to show", "max_value": 10, "min_value": 0, "default": 3 } ``` #### email [#email] ```json title="email" { "type": "email", "name": "contact_email_address", "label": "Public contact email address.", "help_text": "Email to show in site footer.", "default": "" } ``` #### radio [#radio] ```json title="radio" { "type": "radio", "name": "layout", "label": "Layout Style", "help_text": "Control the layout style.", "options": [ { "name": "Boxed", "value": "boxed" }, { "name": "Full Width", "value": "full" } ], "default": "boxed" } ``` #### select [#select] ```json title="select" { "type": "select", "name": "header_style", "label": "Header Style", "help_text": "Choose header layout style.", "options": [ { "name": "Full Width", "value": "full" }, { "name": "Boxed", "value": "boxed" }, { "name": "Overlay", "value": "overlay" } ], "default": "full" } ``` #### multi-select [#multi-select] ```json title="multi-select" { "type": "select", "multi-select": true, "name": "accepted_payment_methods", "label": "Accepted Payment Methods", "help_text": "Control which payment methods are shown.", "options": [ { "name": "Visa", "value": "visa" }, { "name": "Master Card", "value": "mastercard" } ], "default": [ "visa", "mastercard" ] } ``` #### url [#url] ```json title="url" { "type": "url", "name": "social_link", "label": "Social Media Link", "help_text": "Link to your social media page.", "default": "" } ``` #### color [#color] ```json title="color" { "type": "color", "name": "btn_primary_color", "label": "Primary Button Color", "help_text": "Primary color for buttons.", "default": "" } ``` # Snippets (https://developers.nextcommerce.com/docs/apps/snippets) App Snippets are HTML template files used to extend Storefront Themes. Snippets follow the same syntax and features of [theme templates](https://developers.nextcommerce.com/docs/storefront/themes/templates) which bring a full suite of tools and context available to app developers to leverage when adding custom features to a storefront. ### Locations [#locations] Theme's on the Next Commerce platform support `app_hooks` which are locations within storefront themes your app can target to include your snippets without needing the customize the theme itself. > **Note:** To upload your snippets and manifest.json, install [App Kit](https://developers.nextcommerce.com/docs/apps/app-kit) to zip your snippet files and push them to Next Commerce. ### Snippet Usage Example [#snippet-usage-example] # Assets Reference (https://developers.nextcommerce.com/docs/apps/assets) App Assets are static files included in an App that can be included in Event Trackers or Snippets to extend storefront themes. > **Warning:** **App bundle max size is 2MB**, it's important to minimize and reduce the size of the assets in your App to maintain efficiency. If you are compiling CSS or JS bundles locally, it is recommended to not include the raw source files and only include the compiled minified files. ### Asset Usage Example [#asset-usage-example] ### Supported File Types [#supported-file-types] | File Extension | | -------------- | | `.html` | | `.json` | | `.css` | | `.scss` | | `.js` | | `.woff2` | | `.gif` | | `.ico` | | `.png` | | `.jpg` | | `.jpeg` | | `.svg` | | `.eot` | | `.tff` | | `.ttf` | | `.woff` | | `.webp` | | `.mp4` | | `.webm` | | `.mp3` | # Submitting an App for Review (https://developers.nextcommerce.com/docs/apps/review) Congratulations, you've built an app and now it's ready to publish to all Next Commerce customers. Before we publish your app, we need to ensure your app is ready to go. > **Tip:** Private apps can be shared with merchants and installed using the **Install Link** feature available on your app dashboard. Use install links to install and validate your app with merchants before submitting for review. ### App Review Checklist [#app-review-checklist] * Your app is currently live and on more than 3 merchant stores. * You've uploaded a logo to your app that is properly sized and displays nicely. * You've named your app inline with your business and how customers would find your service/app. * Your app description is 40-60 characters that concisely describes your app. * Admin API App Requirements: * Your app requests appropriate Oauth2 permissions for it's use cases instead of a blanket `admin:read` and `admin:write`. * Your app uses webhooks for listening to events instead of polling the Admin APIs. * Your app subscribes to the [`app.uninstalled` webhook event](https://developers.nextcommerce.com/docs/webhooks#webhook-events) for handling uninstall clean up on your end. ### Submit App for Review [#submit-app-for-review] Once you've completed all of your app functionality and the checklist items, you're now ready to submit your app for review. Use the link below to submit your app for review. Our team will review your app to make sure it works properly and is aligned with our expectations. Once we complete the review we will reach out to you to let you know about the review result. If it is approved, it will appear in the App store for all of our customers. If it is not approved, we will let you know what needs to be fixed/changed for your app to be approved. # Event Tracking (https://developers.nextcommerce.com/docs/apps/event-tracking) Apps can install an [Event Tracker](https://developers.nextcommerce.com/docs/storefront/event-tracking) to add storefront ecommerce Event Tracking as part of their integration. An installed event tracker simplifies the setup flow and makes the app easier for merchants to use, with fewer manual setup steps and simple dashboard configuration. > **Warning:** Event trackers and App snippets are not cross compatible as Event Trackers are loaded in their own sandboxed environment for greater security. ### Add Event Tracker to Manifest [#add-event-tracker-to-manifest] When building your app, map a javascript file to be installed as an [Event Tracker](https://developers.nextcommerce.com/docs/storefront/event-tracking). ```json title="Example Storefront Event Tracker" "storefront_event_tracker": "tracking.js", "settings_schema": [ { "name": "custom_app_id_enabled", "type": "checkbox", "label": "Enable Custom App", "help_text": "", "default": false }, { "name": "custom_app_id", "type": "text", "label": "Example Text Setting", "default": "", "required": 1, "help_text": "", "max_length": 250 } ] ``` When your app is installed, an event tracker will be automatically created with the contents of the JavaScript file mapped to the `storefront_event_tracker` key in your manifest.json. ### Access App Settings Inside Event Tracker [#access-app-settings-inside-event-tracker] Apps also have [Settings](https://developers.nextcommerce.com/docs/apps/settings) that can be used to control how the app works, such as enabling or disabling functionality or adding an ID for the tracking script. Access the settings keys in your event tracker to read configuration variables in your JavaScript. ```javascript title="Example Settings Usage in Snippet" // access your app settings through app.settings. if (app.settings.custom_app_id_enabled) { console.log(app.settings.custom_app_id); } ``` # OAuth Overview (https://developers.nextcommerce.com/docs/apps/oauth) This guide introduces OAuth Authentication for Server-side Apps to access the Admin API. ### Introduction to OAuth [#introduction-to-oauth] OAuth 2.0 is the industry standard protocol for authorizing and assigning permissions to 3rd party apps. There are many great guides on the internet regarding OAuth 2.0, such as this [OAuth 2.0 introduction guide from Auth0.com](https://auth0.com/intro-to-iam/what-is-oauth-2/). Your Server-side App's language most likely has pre-built packages to assist with handling Oauth 2.0 Authentication flows. ### Access Tokens [#access-tokens] OAuth 2.0 uses **Access Tokens** which represent authorization to access resources on behalf of the end-user, ie access the Admin API. During the setup flow for your app, you'll be able to obtain request required permissions, get authorization from a user and retrieve a long lived access token to use for all future access to the Admin API. ### OAuth Setup Flow [#oauth-setup-flow] Next Commerce uses OAuth 2.0's Authorization Code Flow to issue an access token on behalf of users. ##### Authorization Flow [#authorization-flow] ```mermaid sequenceDiagram autonumber User->>Store: Initiate App install Store->>App: Redirects to App URL App->>Store: Redirect to store App Authorize View User->>Store: Authorizes the App Store->>App: Redirect to redirect_uri with Authorize Code App->>Store: App requests Access Token with Authorize Code Store->>App: Store responds with Access Token App->>Store: App can now access Admin API with Access Token ``` ##### Authorization Flow Step Detail [#authorization-flow-step-detail] 1. User initiates the App installation process. 2. Store redirects to the App URL configured in App Oauth Settings. 3. App redirects to the store to load the OAuth Authorization view and requests the merchant to authorize app and permission required scopes, [see authorization link example](https://developers.nextcommerce.com/docs/apps/oauth/getting-started#step-2-app-permissions-setup). 4. User authorizes the app and requested permission scopes in the store dashboard. 5. Store redirects to the Redirect URL with an [Authorization Code](https://oauth.net/2/grant-types/authorization-code/), a temporary credential representing the authorization, [see authorization code example](https://developers.nextcommerce.com/docs/apps/oauth/getting-started#step-3-confirm-installation). 6. The app requests an Access Token using the Authorization Code, [see example access token request](https://developers.nextcommerce.com/docs/apps/oauth/getting-started#step-4-retrieve-access-token). 7. Store returns an Access Token, [see example access token response](https://developers.nextcommerce.com/docs/apps/oauth/getting-started#step-4-retrieve-access-token). 8. The app can now access the Admin API using the Access Token, [see Admin API examples](https://developers.nextcommerce.com/docs/admin-api). ### Oauth Guides [#oauth-guides] # Getting Started with OAuth (https://developers.nextcommerce.com/docs/apps/oauth/getting-started) Server-side Apps that use Stores' Admin API must obtain authorization using OAuth 2.0 ([see overview](https://developers.nextcommerce.com/docs/apps/oauth)). This guide shows you how to authorize your app and retrieve your Access Token to access the Admin API. ### Step 1: Retrieve API Credentials [#step-1-retrieve-api-credentials] To get started, make sure that you have your Apps' `client_id` and `client_secret` available on the App details in your Partner account. ### Step 2: App Permissions Setup [#step-2-app-permissions-setup] During the App installation flow, Apps that have `oauth` configured will be redirected to the Oauth App URL from thee App Settings. > **Warning:** Your app should redirect the user back to the store authorization view configured with the scope permissions your app requires. > **Note:** At every stage in the Oauth flow you'll receive a querystring variable `store` with the network domain of the store that is installing the app. **You should use this in your app logic as the unique identifier for the store.** ```bash title="Authorization Link Format" https://{network_domain}/oauth2/authorize/?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scopes} ``` | Parameter | Description | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `network_domain` | The store network domain that is installing the app. Can be referenced from the `store` url parameter sent to your App Oauth App URL. | | `response_type` | Must be `code`, which only authorization flow supported at this time. | | `client_id` | Your app `client_id` found in in your partner account. | | `redirect_uri` | The url you want to receive the Authorization Code in your app. **Must be listed in your app Redirect URLs setting**. | | `scope` | A space separated list of scopes such as `orders:read orders:write users:read users:write`. [See list of all available scopes](https://developers.nextcommerce.com/docs/admin-api/permissions). | ### Step 3: Confirm Installation [#step-3-confirm-installation] After user click's Authorize to confirm App installation, it will redirect to the `redirect_uri` with `?store={network_domain}&code={authorize_code}` appended. ```bash title="Example" https://yourapp.com/setup/authorize/?store={network_domain}&code={authorization_code} ``` | Parameter | Description | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `network_domain` | The store network domain that is installing the app. Can be referenced from the `store` url parameter sent to your app Oauth Redirect URL. | | `authorization_code` | The authorization code used to retrieve the Access Token in the next step. | ### Step 4: Retrieve Access Token [#step-4-retrieve-access-token] After you have the `authorization_code`, you then need to retrieve the access token to gain access to the Admin API. **Send a POST Request to `https://{network_domain}/oauth2/token/` to retrieve your access token** > **Note:** Post request must be sent as `application/x-www-form-urlencoded` format. ```json title="Post Request to Retrieve Access Token" { "grant_type": "authorization_code", "client_id": "{client_id}", "client_secret": "{client_secret}", "redirect_uri": "{redirect_uri}", "code": "{authorize_code}" } ``` A successful request will have the following response. ```json title="Response with Access Token" { "access_token": "{access_token}", "expires_in": 15778476000, "token_type": "Bearer", "scope": "{scopes}", "refresh_token": "{refresh_token}" } ``` Save the `access_token` to your app to use with requests to the [Admin API](https://developers.nextcommerce.com/docs/admin-api) for the store. :clap: > **Note:** To see this in action, see the [Example App](https://github.com/NextCommerceCo/example-app) on Github. # Install Flows (https://developers.nextcommerce.com/docs/apps/oauth/install-flows) ### Private Apps [#private-apps] All apps start in a `private` state while the app developer is building and testing their app internally. While an app is `private`, you can use the "Install Link" builder form on your app detail page. You may also want to trigger the install flow from your app's UI, to do this you can add a form to build the install link for your user to start the install flow on their store. ```bash title="Install Link" https://{store_subdomain}.29next.store/dashboard/apps/install-app/?client_id={client_id} ``` | Parameter | Description | | ----------------- | ------------------------------------------------ | | `store_subdomain` | The store subdomain. | | `client_id` | Your app Client ID found on the app detail page. | ### Public Apps [#public-apps] Public apps show in all store dashboards and can be installed by any merchant at any time. If you plan to publish your app, ensure your app handles the install flow with a good user experience that guides the user through the process with your app. To get your app published to our Public App store, see the [review and publishing guide](https://developers.nextcommerce.com/docs/apps/review). # Session Token Overview (https://developers.nextcommerce.com/docs/apps/oauth/session-auth) Session tokens are a method your app can use to authenticate users and requests from Next Commerce and your App. ### How Session Tokens Work [#how-session-tokens-work] Session tokens follow the [JSON Web Tokens](https://jwt.io/introduction) standard. JWT tokens are signed objects your app can use to authenticate users to your app, see the example decoded token below. The JWT token is appended to requests to your app in the `token` parameter. The JWT token can be verified with your App `CLIENT ID` and `CLIENT SECRET`, see example below. ```python title="JWT Token Decrypt & Verify" token = jwt.decode( , , audience= algorithms=["HS256"] ) print(token) ``` ```json title="JWT Token Decoded" { "iss": "https://example.29next.store/dashboard", "sub": "https://example.29next.store", "aud": "kbCWYEPXMezpXripKyDSlA68fb4auutiaEXmh3Rx", "exp": 1660881585, "nbf": 1660881525, "iat": 1660881525, "uid": 3, "user_email": "demo@29next.com", "store": "example.29next.store" } ``` Tokens include details of the store and the store user (id & email) making the request. A valid token can be trusted as a verified request from a store with your app installed. ### Token Expiration [#token-expiration] Tokens are shortlived with an expiration of 30 seconds, meaning they quickly expire and cannot be reused. It is recommended that you authenticate the users into your App with every request. ### Session Token Flow [#session-token-flow] Session tokens are generated from the store dashboard and can be used by your App to verify request authenticity before authenticating the user to your app. ```mermaid sequenceDiagram autonumber Store->>App: Redirects to App Oauth App URL with JWT token. App->>User: App decrypt/verify JWT token to authorize request App->>User: App loads an authenticated view for user. ``` > **Tip:** To see this in action, see the [Example App](https://github.com/NextCommerceCo/example-app) on Github. # Server to Server Apps (https://developers.nextcommerce.com/docs/apps/guides/server-to-server-apps) Server-to-server apps leverage the [OAuth flow](https://developers.nextcommerce.com/docs/apps/oauth) to obtain API access and then use the [Admin APIs](https://developers.nextcommerce.com/docs/admin-api) and [Webhooks](https://developers.nextcommerce.com/docs/webhooks) to subscribe to store event activity. > **Note:** Server-to-server apps don't need to upload any code or files to Next Commerce; they are fully external and simply use OAuth to obtain Admin API access. In this guide, we'll walk through creating your first app so you can get up and running with the core concepts. ## Preparation [#preparation] 1. If you haven't done so already, create your [Next Commerce account](https://accounts.29next.com) and complete your [Partner Registration](https://accounts.29next.com/partners/). 2. Make sure you have access to a store you plan to use for development - you will use this in later steps. ## Create Your App [#create-your-app] 1. Inside your Partner Account, navigate to Apps and then Create App. Follow the form to create your first app, don't worry about the App name and details, you can change this later. 2. After creating your App, you'll be able to see your App details. Take note of your `Client ID` and `Client Secret` which are used in the [OAuth flow](https://developers.nextcommerce.com/docs/apps/oauth) to retrieve an API Access Token during the [App Install flow](https://developers.nextcommerce.com/docs/apps/oauth/getting-started). ## Configure App OAuth [#configure-app-oauth] Server-to-server apps use the [OAuth flow](https://developers.nextcommerce.com/docs/apps/oauth) to get an Admin API access token. Let's add the [OAuth 2.0 ](https://oauthdebugger.com/) URLs to our app to simulate the install flow. 1. In **App > Settings**, add `https://oauthdebugger.com/debug` as your App URL and Redirect URL to configure your app to use OAuth Debugger. 2. Install your app on your store using the **Install Link** tool on your App Overview. ## Test App On Development Store [#test-app-on-development-store] 1. You can now use [OAuth Debugger](https://oauthdebugger.com/) to simulate the OAuth flow. Your app should now be installed and ready for testing and further development. :raised\_hands: # Storefront Extension Apps (https://developers.nextcommerce.com/docs/apps/guides/storefront-extension) In this guide we'll go over all of the steps to get started building an app that extends storefront functionality to introduce many of the core app framework concepts and how to use them. ## Common Use Cases [#common-use-cases] Storefront extensions are commonly used for but not limited to: * Install javascript tracking snippets to storefront and checkout flow, see [event tracking](https://developers.nextcommerce.com/docs/apps/event-tracking). ## Preparation [#preparation] 1. If you haven't done so already, create your [Next Commerce account](https://accounts.29next.com) and complete your [Partner Registration](https://accounts.29next.com/partners/). 2. Make sure you have access to a store you plan to use for development - you will use this in later steps. ## App Layout Overview [#app-layout-overview] Let's take a look at the basic file structure of apps to understand how to get started creating our first app. ```bash title="Example App Structure" your-app ├── assets │ └── my-app.js └── manifest.json ``` ## Manifest.json [#manifestjson] A manifest.json file specifies the configuration and metadata needed to install and configure your app. [See Manifest Reference](https://developers.nextcommerce.com/docs/apps/manifest) ## App Kit [#app-kit] App Kit is a tool you install on your local machine to assist with bundling your app files and pushing them to the platform so they can be installed on a store. ## Setup App [#setup-app] Now that you have your app files, it's time to configure your app on your local to link it to your App `Client ID`. ```bash title="Setup App Kit Authentication" App Client ID: // your app client id accounts.29next.com Email: your user account email accounts.29next.com Password: your user account password ``` ## Build Your App Bundle [#build-your-app-bundle] Using App Kit, create a build of your app using the command line from your app directory. ```bash title="Build App" nak build ``` ## Push App [#push-app] Now, push your app to your our platform using your username and password credentials for your account at `accounts.29next.com`. ```bash title="Push App" nak push ``` # Marketing Attribution Apps (https://developers.nextcommerce.com/docs/apps/guides/marketing-attribution) Marketing attribution apps connect conversion events with sales channels across storefront, campaigns, and API. 1. **Storefront Order Attribution** — Use [Event Tracking](https://developers.nextcommerce.com/docs/apps/event-tracking) and the [GraphQL Storefront API](https://developers.nextcommerce.com/docs/storefront/graphql) to capture platform-specific identifiers from the visitor's browser and store them as attribution metadata on the cart. 2. **Campaigns & API Order Attribution** — Subscribe to [Webhooks](https://developers.nextcommerce.com/docs/webhooks) to receive order events server-side and extract the stored attribution metadata for conversion tracking. ## Attribution Flow Overview [#attribution-flow-overview] ```mermaid sequenceDiagram autonumber participant Visitor participant Storefront participant App Note over Visitor, Storefront: Storefront Order Attribution Visitor->>Storefront: Lands on storefront from ad App->>Storefront: Event tracker captures platform IDs App->>Storefront: Stores IDs as cart attribution metadata (GraphQL) Note over Storefront, App: Campaigns & API Order Attribution Visitor->>Storefront: Completes checkout Storefront->>App: Sends order.created webhook App->>App: Extracts attribution metadata from order ``` ## Storefront Order Attribution [#storefront-order-attribution] Storefront order attribution runs in the visitor's browser via an [Event Tracker](https://developers.nextcommerce.com/docs/apps/event-tracking) installed through your app's manifest. The event tracker needs to do three things: 1. **Capture platform identifiers** from browser cookies and URL parameters. 2. **Store identifiers as cart attribution metadata** using the [GraphQL Storefront API](https://developers.nextcommerce.com/docs/storefront/graphql) so they persist through to the completed order. 3. **Fire client-side pixel events** by subscribing to [Storefront Events](https://developers.nextcommerce.com/docs/storefront/event-tracking) for real-time browser-side tracking. ### App Setup [#app-setup] > **Note (Getting Started with Apps):** If you haven't already, create your app on [Next Commerce Accounts](https://accounts.29next.com) and install [App Kit](https://developers.nextcommerce.com/docs/apps/guides/storefront-extension#app-kit) to build and push your app files. Your app's [manifest](https://developers.nextcommerce.com/docs/apps/manifest) defines the storefront integration. Map a javascript file as the `storefront_event_tracker`, use `settings_schema` to allow merchants to configure platform-specific IDs, and add an [App Snippet](https://developers.nextcommerce.com/docs/apps/snippets) to inject the ad platform's pixel script into the storefront. ```json title="manifest.json" { "storefront_event_tracker": "tracking.js", "settings_schema": [ { "name": "pixel_id", "type": "text", "label": "Pixel ID", "default": "", "required": 1, "help_text": "Your ad platform pixel identifier.", "max_length": 250 } ], "locations": { "storefront": { "global_header": "snippets/global_header.html" } } } ``` > **Tip (Manage Settings via API):** Apps can programmatically manage the merchant's settings values (e.g. Pixel ID) through the [appsSettingsUpdate](https://developers.nextcommerce.com/docs/admin-api/reference/apps/appsSettingsUpdate) Admin API endpoint, allowing you to populate configuration from your own app dashboard. The `global_header` snippet is where you load the ad platform's pixel script so that it sets the necessary browser cookies. The event tracker then reads these cookies and stores them on the cart. ```html title="snippets/global_header.html" {% if app.settings.pixel_id %} {% endif %} ``` ### Event Tracker [#event-tracker] When your app is installed, the event tracker is automatically created with the content of `tracking.js`. The merchant's settings are accessible via `app.settings` and the [GraphQL Storefront API](https://developers.nextcommerce.com/docs/storefront/graphql) is available at `/api/graphql/`. Below is an example event tracker that captures platform identifiers, stores them as cart attribution metadata via the `createCart` and `updateCartAttribution` GraphQL mutations, and subscribes to storefront events for client-side pixel tracking. > **Note (Cookie Timing):** Ad platform pixel scripts set cookies asynchronously after page load. Your event tracker should wait for the relevant cookies to be set before attempting to read them. A timeout of \~5 seconds is typically sufficient. ```javascript title="tracking.js" if (app.settings.pixel_id) { // --- Helpers --- function getCookie(name) { return document.cookie .split(";") .find(c => c.trim().startsWith(`${name}=`)) ?.split("=")[1]; } function waitForCookie(name, timeout = 5000, interval = 500) { return new Promise((resolve, reject) => { const start = Date.now(); const check = setInterval(() => { if (getCookie(name)) { clearInterval(check); resolve(getCookie(name)); } else if (Date.now() - start >= timeout) { clearInterval(check); reject(new Error(`Timeout waiting for cookie: ${name}`)); } }, interval); }); } function queryGraphql(query, variables = {}) { return fetch("/api/graphql/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query, variables }) }).then(r => r.json()); } // --- GraphQL Mutations --- const CREATE_CART = `mutation createCart { createCart(input: {}) { success errors cart { id, pk, attribution { metadata } } } }`; const UPDATE_CART_ATTRIBUTION = `mutation updateCartAttrMetadata( $cartId: String, $metadata: GenericScalar ) { updateCartAttribution( input: {cartId: $cartId, attribution: {metadata: $metadata}} ) { success errors cart { id, pk, attribution { metadata } } } }`; // --- Attribution Capture --- async function captureAttribution() { // 1. Create a cart const cartData = await queryGraphql(CREATE_CART); const cart = cartData.data?.createCart?.cart; if (!cart) return; // 2. Wait for ad platform cookies to be set try { await waitForCookie("your_cookie_name"); } catch (e) { console.error(e); } // 3. Capture identifiers and store as cart attribution metadata const metadata = cart.attribution?.metadata || {}; const browserId = getCookie("your_cookie_name"); const clickId = getCookie("your_click_cookie_name"); if (browserId) metadata.your_browser_id = browserId; if (clickId) metadata.your_click_id = clickId; metadata.pixel_id = app.settings.pixel_id; await queryGraphql(UPDATE_CART_ATTRIBUTION, { cartId: cart.id, metadata: metadata }); } captureAttribution(); // --- Client-Side Pixel Events --- analytics.subscribe("page_viewed", event => { // Fire page view event on your ad platform }); analytics.subscribe("product_viewed", event => { // Fire view content event with event.data product details }); analytics.subscribe("product_added_to_cart", event => { // Fire add to cart event with event.data line item details }); analytics.subscribe("checkout_started", event => { // Fire initiate checkout event with event.data cart details }); analytics.subscribe("checkout_completed", event => { // Fire purchase/conversion event with event.data order details }); } ``` See [Storefront Event Tracking](https://developers.nextcommerce.com/docs/storefront/event-tracking) for the full list of available events and their data structures. > **Note (Attribution Metadata Persists to Orders):** Attribution metadata stored on the cart is automatically carried over to the order when the customer completes checkout. This is what makes the webhook-based conversion flow possible — the identifiers captured in the browser are available in the `order.created` webhook payload. ## Campaigns & API Order Attribution [#campaigns--api-order-attribution] Not all orders originate from the storefront. Orders created through [Campaigns](https://developers.nextcommerce.com/docs/campaigns), the [Admin API](https://developers.nextcommerce.com/docs/admin-api), and recurring [Subscription](https://developers.nextcommerce.com/docs/admin-api/guides/subscription-management) renewals bypass the storefront entirely — [Webhooks](https://developers.nextcommerce.com/docs/webhooks) are the way to capture attribution data for these conversions. ### Subscribe to Webhooks [#subscribe-to-webhooks] Subscribe to the `order.created` webhook event using the [webhooksCreate](https://developers.nextcommerce.com/docs/admin-api/reference/webhooks/webhooksCreate) Admin API endpoint. Your app should do this during the OAuth installation flow. Always [verify the webhook signature](https://developers.nextcommerce.com/docs/webhooks#verifying-webhook-requests) before processing incoming events. ```json title="__http:POST:https://{store}.29next.store/api/admin/webhooks/" { "target": "https://your-app.example.com/webhooks/", "events": ["order.created"], "signing_secret": "your-signing-secret" } ``` ### Extract Attribution Metadata from Order [#extract-attribution-metadata-from-order] The `order.created` webhook payload contains the full order data, including the `attribution` object with the metadata your event tracker stored on the cart. ```json title="order.created Webhook Payload (abbreviated)" { "event_type": "order.created", "object": "order", "data": { ... "number": "109659", "source": "storefront", "total_incl_tax": "84.98", "total_excl_tax": "84.98", "currency": "USD", "reporting_values": { "currency": "USD", "total_incl_tax": "84.98", "total_excl_tax": "84.98", "shipping_incl_tax": "4.99", "shipping_excl_tax": "4.99", "total_discount": "0.00" }, "attribution": { ... "metadata": { "your_platform_id": "your_value", "your_click_id": "your_value", "your_browser_id": "your_value" } }, ... } } ``` > **Note:** View the full [order.created webhook payload](https://developers.nextcommerce.com/docs/webhooks/reference/orders/order.created) for all available fields including user, lines, shipping address, and transaction data. # Webhooks (https://developers.nextcommerce.com/docs/webhooks) Use webhooks to be notified about events that happen in your store. Stores can send webhooks that notify your application anytime an event happens. This is especially useful for building custom reporting solutions that need to receive data on order or customer activity. ### Why Webhooks [#why-webhooks] Webhooks are an efficient way to sync data from a store in near real time, keeping your app up to date without the overhead of traditional polling. See the example below for subscribing to `order.created` events. ```mermaid sequenceDiagram autonumber App->>Store: Subscribes to order.created event Customer->>Store: New order created Store->>App: Sends order.created event payload ``` ### Use Cases [#use-cases] Common use cases include, but are not limited to: * Integrating with external marketing platforms * Collecting data for external reporting applications * Integrating with external fulfillment services * Integrating with dispute management services ### Setting Up Webhooks [#setting-up-webhooks] You can register new webhooks through **Settings > Webhooks** or the Admin API to send event data to your application endpoint. For each webhook, you can subscribe to all events or select specific events to send to your endpoint. See a list of all events and example event data below. > **Warning:** Webhook target endpoints must accept JSON data and respond with a `200` response code. If we do not receive a `200` response, we will retry up to 10 times over a several-day period on an exponential backoff schedule. > > Webhook handlers should also complete within about 20 seconds. Longer-running endpoints can be treated as failed deliveries and retried. > > **Failing webhooks will trigger email notifications to all store admins and will eventually be deactivated.** > > Returning a `410` response code indicates the target resource is no longer available and will automatically disable the webhook. ### Webhook Events [#webhook-events] | Event | Description | Reference | | ---------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------- | | `app.uninstalled` | Triggers when an app is uninstalled. *Only available for apps.* | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/apps/app.uninstalled) | | `cart.abandoned` | Triggers when a cart is marked as abandoned. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/carts/cart.abandoned) | | `customer.created` | Triggers when a new customer is created. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/customers/customer.created) | | `customer.redacted` | Triggers when a customer is redacted. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/customers/customer.redacted) | | `customer.updated` | Triggers when an existing customer is updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/customers/customer.updated) | | `dispute.created` | Triggers when a new dispute is created. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/payments/dispute.created) | | `dispute.updated` | Triggers when a dispute is updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/payments/dispute.updated) | | `export.created` | Triggers when an export is available for download. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/exports/export.created) | | `fulfillment.created` | Triggers when a new fulfillment is created. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/fulfillment/fulfillment.created) | | `fulfillment.updated` | Triggers when a fulfillment is updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/fulfillment/fulfillment.updated) | | `gateway.created` | Triggers when a new gateway is created. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/payments/gateway.created) | | `gateway.updated` | Triggers when a gateway is updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/payments/gateway.updated) | | `order.created` | Triggers when an order is created. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/orders/order.created) | | `order.updated` | Triggers when an existing order is updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/orders/order.updated) | | `product.created` | Triggers when a product is created. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/products/product.created) | | `product.deleted` | Triggers when an existing product is deleted. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/products/product.deleted) | | `product.updated` | Triggers when an existing product is updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/products/product.updated) | | `transaction.created` | Triggers when a payment transaction is created. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/payments/transaction.created) | | `transaction.updated` | Triggers when a payment transaction is updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/payments/transaction.updated) | | `subscription.created` | Triggers when a new subscription is created. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/subscriptions/subscription.created) | | `subscription.updated` | Triggers when an existing subscription is updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/subscriptions/subscription.updated) | | `store.updated` | Triggers when store settings are updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/store/store.updated) | | `ticket.created` | Triggers a new support ticket is created. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/support/ticket.created) | | `ticket.updated` | Triggers when an existing support ticket is updated. | [View Example](https://developers.nextcommerce.com/docs/webhooks/reference/support/ticket.updated) | > **Note (Handling subscription charges):** The `subscription` object on a `transaction.created` webhook links the charge to its subscription and identifies the billing cycle. See [Identifying Subscription Charges](https://developers.nextcommerce.com/docs/admin-api/guides/subscription-management#identifying-subscription-charges). > > There is no renewal-specific event. A renewal charge arrives as `transaction.created` with `billing_cycle` of 1 or higher on that `subscription` object; the initial charge has `billing_cycle` 0. > **Note (Disputes include chargebacks):** Chargebacks and pre-chargeback alerts both arrive as `dispute.created` and `dispute.updated`; the dispute's `type` field says which it is. See the [Disputes guide](https://docs.nextcommerce.com/docs/features/payments/disputes-guide). ### Webhook Data Structure [#webhook-data-structure] Webhook payloads follow the same structure as Admin API data serializers, which makes them predictable. In general, the data in a webhook payload matches the data you would get by retrieving the same resource through the API. You can set up test webhooks and view the webhook logs in the dashboard to help build and verify your receiver. ```json title="Webhook Event Payload Structure" { "object": "", "data": "", "event_id": "", "event_type": "", "webhook": "", "api_version": "2023-02-10" } ``` Below is a full example of a webhook payload for a `customer.created` event to demonstrate. ```json title="Example Webhook Event Data" { "api_version": "2023-02-10", "data": { "accepts_marketing": true, "addresses": [], "date_joined": "2021-12-17T14:52:53.715787+07:00", "email": "testing@testing.com", "first_name": "Tester", "id": 32234664, "ip": null, "is_blocked": false, "language": "en", "last_name": "Test", "orders_count": 0, "phone_number": null, "subscriptions_count": 0, "tags": [], "total_spent": null, "user_type": "lead" }, "event_id": "f7eb1338-0934-4cda-8128-d6a77761a368", "event_type": "customer.created", "object": "customer", "webhook": { "events": [ "customer.created" ], "id": 39, "store": "storename", "target": "https://webhook.site/6a880c2a-48db-4e28-a575-294dfee934234" } } ``` ### Webhook API Versions [#webhook-api-versions] Webhook object data structure follows the [Admin API](https://developers.nextcommerce.com/docs/admin-api) and Admin API versioning to ensure predictable data structure for existing webhook receiver endpoints with a path for upgrades. **Handling Webhook API Versions** Your app can add handling logic using the `api_version` key when receiving and processing data to handle multiple webhook data structures while upgrading to a newer webhook api version. ### Verifying Webhook Requests [#verifying-webhook-requests] Webhook endpoints are generally open to the internet and therefore it's a best practice to verify the payload data. Webhook requests include a header `X-29Next-Signature`, the value is a signature of the webhook payload signed using the webhook signing secret. Your application can use the signature to verify the payload authenticity, see an example below. ```python title="Verifying Webhook Payload" webhook_secret = def webhook_payload_validator(request): request_sig = request.headers.get('X-29Next-Signature', None) webhook_data = json.loads(request.body) expected_sig = hmac.new( webhook_secret.encode(), json.dumps(webhook_data).encode(), hashlib.sha256 ).hexdigest() return True if expected_sig == request_sig else False ``` As shown above, we can verify the data by generating the same signature with the webhook secret. > **Tip:** When creating webhooks on the API, you can provide your own signing secret to simplify the signature verification process for webhook payloads.