Webhook List
Comprehensive list of all webhook events that Stash can send to your backend, including event types, triggers, payload structures, and detailed examples for each webhook type across Stash products.
This page contains a comprehensive list of all webhook events that Stash can send to your backend. Each webhook is triggered by specific user actions or system events.
Product-specific events: Some events are specific to Stash Pay or Stash Webshop. See the Stash Pay integration guide or Stash Webshop integration guide for product-specific webhook details.
Required Events
These events are essential for purchase processing and should always be subscribed to:
PURCHASE_SUCCEEDED
Products: Stash Pay, Stash Webshop
Sent when a purchase is successfully completed. This is the primary event for granting items to players.
When to use: Always subscribe to this event to grant items to players after successful payment.
Key Fields:
orderId: Order identifieruserId: External user IDitems: Array of purchased items with quantities and pricestotal: Total amount paidcurrency: Currency code (e.g., "USD", "EUR")source: Indicates the source product ("StashPay"or"Cart"for Webshop)
Optional Events
These events are optional and primarily used for analytics, user behavior tracking, and marketing purposes:
Stash Webshop Events
The following events are specific to Stash Webshop:
MUTATE_CART
Product: Stash Webshop only
Sent when a user adds, removes, or modifies items in their cart.
Use Case: Track cart abandonment, analyze shopping behavior, trigger marketing campaigns.
VIEW_ITEM
Product: Stash Webshop only
Sent when a user views an item (debounced to once per 100 seconds per item).
Use Case: Product interest tracking, recommendation algorithms.
VIEW_CHECKOUT_PAGE
Product: Stash Webshop only
Sent when a user views the checkout page.
Use Case: Track checkout page visits, identify drop-off points.
VIEW_PRODUCT_DETAIL_PAGE
Product: Stash Webshop only
Sent when a user views a product detail page.
Use Case: Product interest tracking, content engagement metrics.
CART_BUTTON_CLICK
Product: Stash Webshop only
Sent when a user clicks the cart button/icon.
Use Case: Track cart interactions, shopping behavior analysis.
Shared Events
The following events can be sent by both Stash Pay and Stash Webshop:
CREATE_PAYMENT_INTENT
Products: Stash Pay, Stash Webshop
Sent when a payment intent is created (user initiates checkout).
Use Case: Track checkout initiation, payment method selection analytics.
FREE_ITEM_REDEEMED
Products: Stash Pay, Stash Webshop
Sent when a user redeems a free item (promotional items, rewards, etc.).
Use Case: Track promotional campaign effectiveness, user engagement.
Available webhooks
| Event Type | Products | Description | Trigger |
|---|---|---|---|
PURCHASE_SUCCEEDED | Pay, Webshop | Fired when a purchase is successfully completed | When a user completes a purchase transaction |
MUTATE_CART | Webshop | Fired when items are added, removed, or modified in cart | When cart contents change (add/remove items, quantity changes) |
VIEW_ITEM | Webshop | Fired when a user views a specific item | When a user visits an item page or views item details |
CREATE_PAYMENT_INTENT | Pay, Webshop | Fired when a payment process is initiated | When user starts checkout process or opens payment flow |
FREE_ITEM_REDEEMED | Pay, Webshop | Fired when a user redeems a free item | When a free item is claimed or redeemed |
VIEW_CHECKOUT_PAGE | Webshop | Fired when user visits the checkout page | When checkout page is loaded |
VIEW_PRODUCT_DETAIL_PAGE | Webshop | Fired when user views product details | When product detail page is accessed |
CART_BUTTON_CLICK | Webshop | Fired when cart-related buttons are clicked | When user interacts with cart buttons |
Payload structure
All webhooks follow a consistent structure with a base webhook object:
{
"type": "EVENT_TYPE",
"eventData": {
// Event-specific payload data
}
}Detailed payload examples
PURCHASE_SUCCEEDED
Triggered when a purchase is successfully completed.
Note: The source field will be "StashPay" for purchases made through Stash Pay, or "Cart" for purchases made through Stash Webshop.
{
"type": "PURCHASE_SUCCEEDED",
"purchaseSucceeded": {
"timeMillis": 1640995200000,
"orderId": "order_abc123",
"checkoutLinkId": "checkout_xyz789",
"currency": "USD",
"userId": "user_123",
"items": [
{
"id": "item_456",
"quantity": 2,
"price": "9.99",
"metadata": {
"category": "weapons",
"rarity": "legendary"
}
}
],
"tax": "1.50",
"total": "21.48",
"taxDetails": {
"items": [
{
"label": "Sales Tax",
"isInclusive": false,
"amount": "1.50",
"percentage": "7.5",
"country": "US",
"state": "CA"
}
]
},
"emailMarketingOptIn": true,
"regionCode": "US",
"source": "StashPay",
"ipAddress": "192.168.1.1"
}
}MUTATE_CART
Triggered when cart contents are modified.
{
"type": "MUTATE_CART",
"mutateCart": {
"cartId": "cart_789",
"timeMillis": 1640995200000,
"userId": "user_123",
"items": [
{
"id": "item_456",
"quantity": 3
},
{
"id": "item_789",
"quantity": -1
}
],
"regionCode": "US",
"source": "Cart",
"ipAddress": "192.168.1.1"
}
}VIEW_ITEM
Triggered when a user views an item.
{
"type": "VIEW_ITEM",
"viewItem": {
"userId": "user_123",
"itemId": "item_456",
"regionCode": "US"
}
}CREATE_PAYMENT_INTENT
Triggered when payment process is initiated.
Note: The source field will be "StashPay" for Stash Pay or "Cart" for Stash Webshop.
{
"type": "CREATE_PAYMENT_INTENT",
"openPayment": {
"cartId": "cart_789",
"userId": "user_123",
"items": [
{
"id": "item_456",
"quantity": 2
}
],
"source": "StashPay"
}
}FREE_ITEM_REDEEMED
Triggered when a free item is redeemed.
{
"type": "FREE_ITEM_REDEEMED",
"freeItemRedeemed": {
"userId": "user_123",
"itemId": "item_free_001",
"ipAddress": "192.168.1.1",
"metadata": {
"promotionId": "summer_promo",
"redeemCode": "SUMMER2024"
}
}
}VIEW_CHECKOUT_PAGE
Triggered when checkout page is viewed.
{
"type": "VIEW_CHECKOUT_PAGE",
"viewCheckoutPage": {
"userId": "user_123",
"regionCode": "US"
}
}VIEW_PRODUCT_DETAIL_PAGE
Triggered when product details are viewed.
{
"type": "VIEW_PRODUCT_DETAIL_PAGE",
"viewProductDetailsPage": {
"userId": "user_123",
"itemId": "item_456",
"regionCode": "US"
}
}CART_BUTTON_CLICK
Triggered when cart buttons are clicked.
{
"type": "CART_BUTTON_CLICK",
"sendCartButtonClick": {
"userId": "user_123",
"regionCode": "US"
}
}Common fields
Several fields appear across multiple webhook types:
userId: The external user identifier from your systemregionCode: Unicode CLDR region code (e.g., "US", "FR") based on user locationipAddress: User's IP address when the event occurredtimeMillis: Timestamp in milliseconds since Unix epoch
Subscription Events (v2)
Subscription webhooks use a v2 payload format with lowercase dot-notation event types, unlike the v1 format used by purchase and webshop events above.
Subscription events notify your system of subscription lifecycle changes. See the Subscriptions guide for full integration details.
Available subscription events
| Event Type | Description | Trigger |
|---|---|---|
subscription.created | New subscription created | Player completes subscription checkout |
subscription.updated | Subscription changed | Plan or status was modified |
subscription.canceled | Subscription canceled | Player cancels their subscription |
subscription.reactivated | Subscription reactivated | Canceled subscription was reactivated |
subscription.expired | Subscription expired | Subscription reached terminal state |
subscription.payment_failed | Payment failed | Renewal payment attempt failed |
subscription.payment_succeeded | Payment succeeded | Renewal payment processed successfully |
v2 Payload structure
Subscription webhooks use a different structure from v1 events:
{
"type": "subscription.event_name",
"data": {
// Subscription object
}
}subscription.created
Triggered when a new subscription is created.
{
"type": "subscription.created",
"data": {
"id": "sub_xyz789",
"external_account_id": "player_123",
"plan_id": "plan_abc123",
"status": "active",
"period": {
"value": 1,
"unit": "month"
},
"trial_end": "2024-02-01T00:00:00Z",
"access_end_date": "2024-03-01T00:00:00Z",
"current_period_end": "2024-03-01T00:00:00Z",
"next_billing_date": "2024-03-01T00:00:00Z",
"cancel_at_period_end": false,
"canceled_at": null,
"created_at": "2024-01-01T00:00:00Z"
}
}subscription.updated
Triggered when a subscription's plan or status changes.
{
"type": "subscription.updated",
"data": {
"id": "sub_xyz789",
"external_account_id": "player_123",
"plan_id": "plan_abc123",
"status": "active",
"period": {
"value": 1,
"unit": "month"
},
"trial_end": null,
"access_end_date": "2024-04-01T00:00:00Z",
"current_period_end": "2024-04-01T00:00:00Z",
"next_billing_date": "2024-04-01T00:00:00Z",
"cancel_at_period_end": false,
"canceled_at": null,
"created_at": "2024-01-01T00:00:00Z"
}
}subscription.canceled
Triggered when a player cancels their subscription.
{
"type": "subscription.canceled",
"data": {
"id": "sub_xyz789",
"external_account_id": "player_123",
"plan_id": "plan_abc123",
"status": "canceled",
"period": {
"value": 1,
"unit": "month"
},
"trial_end": null,
"access_end_date": "2024-03-01T00:00:00Z",
"current_period_end": "2024-03-01T00:00:00Z",
"next_billing_date": "2024-03-01T00:00:00Z",
"cancel_at_period_end": true,
"canceled_at": "2024-02-15T14:30:00Z",
"created_at": "2024-01-01T00:00:00Z"
}
}subscription.reactivated
Triggered when a canceled subscription is reactivated before expiration.
{
"type": "subscription.reactivated",
"data": {
"id": "sub_xyz789",
"external_account_id": "player_123",
"plan_id": "plan_abc123",
"status": "active",
"period": {
"value": 1,
"unit": "month"
},
"trial_end": null,
"access_end_date": "2024-03-01T00:00:00Z",
"current_period_end": "2024-03-01T00:00:00Z",
"next_billing_date": "2024-03-01T00:00:00Z",
"cancel_at_period_end": false,
"canceled_at": null,
"created_at": "2024-01-01T00:00:00Z"
}
}subscription.expired
Triggered when a subscription reaches its terminal state.
{
"type": "subscription.expired",
"data": {
"id": "sub_xyz789",
"external_account_id": "player_123",
"plan_id": "plan_abc123",
"status": "expired",
"period": {
"value": 1,
"unit": "month"
},
"trial_end": null,
"access_end_date": "2024-03-01T00:00:00Z",
"current_period_end": "2024-03-01T00:00:00Z",
"next_billing_date": "2024-03-01T00:00:00Z",
"cancel_at_period_end": true,
"canceled_at": "2024-02-15T14:30:00Z",
"created_at": "2024-01-01T00:00:00Z"
}
}subscription.payment_failed
Triggered when a renewal payment attempt fails. The subscription enters past_due status and Stash will retry.
{
"type": "subscription.payment_failed",
"data": {
"id": "sub_xyz789",
"external_account_id": "player_123",
"plan_id": "plan_abc123",
"status": "past_due",
"period": {
"value": 1,
"unit": "month"
},
"trial_end": null,
"access_end_date": "2024-03-03T00:00:00Z",
"current_period_end": "2024-03-01T00:00:00Z",
"next_billing_date": "2024-03-02T00:00:00Z",
"cancel_at_period_end": false,
"canceled_at": null,
"created_at": "2024-01-01T00:00:00Z"
}
}subscription.payment_succeeded
Triggered when a renewal payment is processed successfully.
{
"type": "subscription.payment_succeeded",
"data": {
"id": "sub_xyz789",
"external_account_id": "player_123",
"plan_id": "plan_abc123",
"status": "active",
"period": {
"value": 1,
"unit": "month"
},
"trial_end": null,
"access_end_date": "2024-04-01T00:00:00Z",
"current_period_end": "2024-04-01T00:00:00Z",
"next_billing_date": "2024-04-01T00:00:00Z",
"cancel_at_period_end": false,
"canceled_at": null,
"created_at": "2024-01-01T00:00:00Z"
}
}Subscription object fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the subscription |
external_account_id | string | Identifier for the player/user |
plan_id | string | Plan identifier |
status | string | active, past_due, canceled, or expired |
period | object | Billing period with value (integer) and unit (day/week/month/year) |
trial_end | string (nullable) | ISO 8601 timestamp when trial ends |
access_end_date | string | ISO 8601 timestamp when access expires |
current_period_end | string | ISO 8601 timestamp for current period end |
next_billing_date | string | ISO 8601 timestamp for next billing attempt |
cancel_at_period_end | boolean | Whether cancellation is scheduled |
canceled_at | string (nullable) | ISO 8601 timestamp when canceled |
created_at | string | ISO 8601 timestamp when created |
How is this guide?