Log eCommerce events
Learn how to log eCommerce recommended events through the Braze Android, Swift, and Web SDKs using typed event classes and
logEcommerceEvent. For event property schemas, platform features, and ingestion validation, see Recommended events and Event validation and troubleshooting.

For wrapper SDKs not listed, use the relevant native Android or Swift method instead.
Event schemas
The six eCommerce recommended events share an order-level schema across all platforms. Use the following property tables when you build each event payload. For the canonical schema with full validation behavior and REST API examples, see Recommended events. For platform features such as segmentation, Canvas templates, and reporting, see How to use eCommerce events.
Trigger when a user views a product detail page.
Event properties
| Property name | Data type | Required | Description |
|---|---|---|---|
product_id |
String | Yes | Unique product identifier (for example, SKU or item ID). |
product_name |
String | Yes | Product display name. |
variant_id |
String | Yes | Product variant identifier (for example, shirt_medium_blue). |
image_url |
String | No | Product image URL. |
product_url |
String | No | URL to the product page for more details. |
price |
Float | Yes | Variant unit price at the time of viewing. |
currency |
String | Yes | Three-letter ISO 4217 code (for example, USD or EUR). |
source |
String | Yes | Source the event originates from (for example, web, ios, or android). |
type |
Array of strings | No | Required to use Braze catalog trigger features for back-in-stock and price-drop alerts. Accepted values: "price_drop", "back_in_stock". |
metadata |
Object | No | Flexible key-value pairs. Recognized sub-property: sku (String). |
Trigger every time the contents of a user’s cart change. Use full cart replacement (omit action or set it to replace) or incremental updates (add or remove).
Event properties
| Property | Data type | Required | Description |
|---|---|---|---|
cart_id |
String | Yes | Unique identifier for the cart. Shared across cart, checkout, and order events for the user’s cart mapping. |
action |
String | No | add (increment quantity or add a line), remove (decrement quantity; line removed at 0), or replace (full cart replacement, same as omitting action). |
total_value |
Float | Conditional | Required when action is omitted or replace. Optional when action is add or remove. |
subtotal_value |
Float | No | Subtotal value of the cart (post-discount, pre-tax/shipping). |
tax |
Float | No | Total tax applied to the cart. |
shipping |
Float | No | Total shipping cost for the cart. |
currency |
String | Yes | Three-letter ISO 4217 code. |
products |
Array | Yes | Line items for this update. See the product properties table. |
source |
String | Yes | Source the event originates from. |
metadata |
Object | No | Flexible key-value pairs for additional event-level data. |
Product properties (products[])
| Property | Data type | Required | Description |
|---|---|---|---|
product_id |
String | Yes | Unique product identifier. |
product_name |
String | Yes | Product display name. |
variant_id |
String | Yes | Variant identifier. |
image_url |
String | No | Product image URL. |
product_url |
String | No | URL to the product page. |
quantity |
Integer | Yes | For full replacement, units in the cart for this line. For add or remove, how many units to add or remove. |
price |
Float | Yes | Variant unit price. |
metadata |
Object | No | Flexible key-value pairs (for example, color or size). |
Trigger when the user initiates the checkout flow.
Event properties
| Property | Data type | Required | Description |
|---|---|---|---|
checkout_id |
String | Yes | Unique identifier for the checkout session. |
cart_id |
String | No | Cart identifier. Shared across cart, checkout, and order events for the user’s cart mapping. |
total_value |
Float | Yes | Total monetary value of the checkout. |
subtotal_value |
Float | No | Subtotal value (post-discount, pre-tax/shipping). |
tax |
Float | No | Total tax applied to the checkout. |
shipping |
Float | No | Total shipping cost. |
currency |
String | Yes | Three-letter ISO 4217 code. |
products |
Array | Yes | Items being checked out. See the product properties table. |
source |
String | Yes | Source the event originates from. |
metadata |
Object | No | Flexible key-value pairs. Recognized sub-property: checkout_url (String). |
Product properties (products[])
| Property | Data type | Required | Description |
|---|---|---|---|
product_id |
String | Yes | Unique product identifier. |
product_name |
String | Yes | Product display name. |
variant_id |
String | Yes | Variant identifier. |
image_url |
String | No | Product image URL. |
product_url |
String | No | URL to the product page. |
quantity |
Integer | Yes | Number of units in the cart. |
price |
Float | Yes | Variant unit price. |
metadata |
Object | No | Flexible key-value pairs (for example, color or size). |
Trigger when an order is successfully completed or payment is confirmed.
Event properties
| Property | Data type | Required | Description |
|---|---|---|---|
order_id |
String | Yes | Unique identifier for the order. |
cart_id |
String | No | Cart identifier. Shared across cart, checkout, and order events for the user’s cart mapping. |
total_value |
Float | Yes | Total monetary value of the order. |
subtotal_value |
Float | No | Subtotal value (post-discount, pre-tax/shipping). |
tax |
Float | No | Total tax applied to the order. |
shipping |
Float | No | Total shipping cost. |
currency |
String | Yes | Three-letter ISO 4217 code. |
total_discounts |
Float | No | Total amount of discounts applied to the order. |
discounts |
Array | No | Detailed list of discounts applied. Each discount object supports code (String), amount (Float), and type (String). |
products |
Array | Yes | Items in the order. See the product properties table. |
source |
String | Yes | Source the event originates from. |
metadata |
Object | No | Flexible key-value pairs. Recognized sub-property: order_status_url (String). |
Product properties (products[])
| Property | Data type | Required | Description |
|---|---|---|---|
product_id |
String | Yes | Unique product identifier. |
product_name |
String | Yes | Product display name. |
variant_id |
String | Yes | Variant identifier. |
image_url |
String | No | Product image URL. |
product_url |
String | No | URL to the product page. |
quantity |
Integer | Yes | Number of units in the order. |
price |
Float | Yes | Variant unit price. |
metadata |
Object | No | Flexible key-value pairs (for example, color or size). |
Trigger when an order is cancelled.
Event properties
| Property | Data type | Required | Description |
|---|---|---|---|
order_id |
String | Yes | Unique identifier for the order. |
total_value |
Float | Yes | Total monetary value of the order being cancelled. Send the absolute amount (greater than or equal to 0); Braze handles the decrement. |
subtotal_value |
Float | No | Subtotal value (post-discount, pre-tax/shipping). |
tax |
Float | No | Total tax applied to the order. |
shipping |
Float | No | Total shipping cost. |
currency |
String | Yes | Three-letter ISO 4217 code. |
total_discounts |
Float | No | Total amount of discounts applied to the order. |
discounts |
Array | No | Detailed list of discounts applied. |
cancel_reason |
String | Yes | Reason the order was cancelled. |
products |
Array | Yes | Items in the cancelled order. See the product properties table. |
source |
String | Yes | Source the event originates from. |
metadata |
Object | No | Flexible key-value pairs. Recognized sub-property: order_status_url (String). |
Product properties (products[])
| Property | Data type | Required | Description |
|---|---|---|---|
product_id |
String | Yes | Unique product identifier. |
product_name |
String | Yes | Product display name. |
variant_id |
String | Yes | Variant identifier. |
image_url |
String | No | Product image URL. |
product_url |
String | No | URL to the product page. |
quantity |
Integer | Yes | Number of units in the order. |
price |
Float | Yes | Variant unit price. |
metadata |
Object | No | Flexible key-value pairs (for example, color or size). |
Trigger when a full or partial refund is issued. For partial refunds, set total_value to the refunded amount only, not the original order total.
Event properties
| Property | Data type | Required | Description |
|---|---|---|---|
order_id |
String | Yes | Unique identifier for the original order. |
total_value |
Float | Yes | Total monetary value of the refund. Send the absolute amount (greater than or equal to 0); Braze handles the revenue adjustment. |
currency |
String | Yes | Three-letter ISO 4217 code. |
total_discounts |
Float | No | Total amount of discounts originally applied. |
discounts |
Array | No | Detailed list of discounts. |
products |
Array | Yes | Items being refunded. See the product properties table. |
source |
String | Yes | Source the event originates from. |
metadata |
Object | No | Flexible key-value pairs. Recognized sub-property: order_status_url (String). |
Product properties (products[])
| Property | Data type | Required | Description |
|---|---|---|---|
product_id |
String | Yes | Unique product identifier. |
product_name |
String | Yes | Product display name. |
variant_id |
String | Yes | Variant identifier. |
image_url |
String | No | Product image URL. |
product_url |
String | No | URL to the product page. |
quantity |
Integer | Yes | Number of units refunded. |
price |
Float | Yes | Variant unit price. |
metadata |
Object | No | Flexible key-value pairs (for example, color or size). |
Android
Android SDK 42.3.0+ provides typed eCommerce event classes with client-side validation at construction time and automatic snake_case serialization when you call Braze.logEcommerceEvent.
| Android class | Event name | Notes |
|---|---|---|
ProductViewedEvent |
ecommerce.product_viewed |
Flattens product fields to the top level of properties (no products array). This class does not support the top-level type property for catalog triggers. If you need type, use logCustomEvent or the REST API. |
CartUpdatedEvent |
ecommerce.cart_updated |
Use CartUpdatedAction (ADD, REMOVE, REPLACE) for the action property. |
CheckoutStartedEvent |
ecommerce.checkout_started |
|
OrderPlacedEvent |
ecommerce.order_placed |
Supports optional cartId, totalDiscounts, and discounts. |

ecommerce.order_cancelled and ecommerce.order_refunded are not available as typed Android SDK classes. Log them with logCustomEvent or the REST API.
Shared building blocks
EcommerceProduct: Line items for cart, checkout, and order events.- Required:
productId,productName,variantId,price,quantity(non-negativeLong) - Optional:
imageUrl,productUrl,metadata
- Required:
BrazeProperties: Event-level or product-levelmetadata. Keys must be non-empty strings that are at least 255 characters with no leading dollar sign ($).
Client-side validation
Invalid payloads throw IllegalArgumentException when you construct the event class, so the event is never queued. Common rules:
| Field or rule | Validation |
|---|---|
String IDs and names (product_id, product_name, variant_id, cart_id, checkout_id, order_id, source, optional URLs) |
Non-blank, up to 255 characters |
price, total_value, total_discounts |
Must be greater than or equal to 0 |
currency |
Valid ISO 4217 code (trimmed and converted to uppercase by the SDK) |
products (cart, checkout, order events) |
At least one EcommerceProduct |
quantity (per product) |
Non-negative integer |
At dispatch time, if serialized properties exceed the SDK size limit, logEcommerceEvent logs an error and does not send the event.
Code examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import com.braze.Braze
import com.braze.models.outgoing.BrazeProperties
import com.braze.models.recommended.ecommerce.ProductViewedEvent
val metadata = BrazeProperties()
.addProperty("sku", "SS-R-101")
.addProperty("category", "Apparel")
val productViewedEvent = ProductViewedEvent(
productId = "PROD101",
productName = "Silk Scarf",
variantId = "SCARF_RED_SILK",
price = 150.00,
currency = "EUR",
source = "https://braze-fashion.eu",
imageUrl = "https://braze-fashion.eu/images/scarf_red.jpg",
productUrl = "https://braze-fashion.eu/products/scarf",
metadata = metadata,
)
Braze.getInstance(context).logEcommerceEvent(productViewedEvent)
Set action using CartUpdatedAction:
| Value | Wire value | Description |
|---|---|---|
CartUpdatedAction.ADD |
add |
Increase quantity or add a line. |
CartUpdatedAction.REMOVE |
remove |
Decrease quantity; remove the line at 0. |
CartUpdatedAction.REPLACE |
replace |
Replace the full cart (default). |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import com.braze.Braze
import com.braze.models.recommended.ecommerce.CartUpdatedAction
import com.braze.models.recommended.ecommerce.CartUpdatedEvent
import com.braze.models.recommended.ecommerce.EcommerceProduct
val product = EcommerceProduct(
productId = "SKU-RUN-4821",
productName = "Ultraboost Running Shoe",
variantId = "UB-BLK-11",
price = 189.99,
quantity = 1,
)
val cartUpdatedEvent = CartUpdatedEvent(
cartId = "cart_abc123",
currency = "USD",
source = "android",
totalValue = 189.99,
products = listOf(product),
action = CartUpdatedAction.ADD,
)
Braze.getInstance(context).logEcommerceEvent(cartUpdatedEvent)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import com.braze.Braze
import com.braze.models.outgoing.BrazeProperties
import com.braze.models.recommended.ecommerce.CheckoutStartedEvent
import com.braze.models.recommended.ecommerce.EcommerceProduct
val products = listOf(
EcommerceProduct(
productId = "SKU-RUN-4821",
productName = "Ultraboost Running Shoe",
variantId = "UB-BLK-11",
price = 189.99,
quantity = 1,
),
)
val checkoutStartedEvent = CheckoutStartedEvent(
checkoutId = "chk_88291",
currency = "USD",
source = "android",
totalValue = 234.96,
products = products,
cartId = "cart_abc123",
metadata = BrazeProperties().addProperty("checkout_url", "https://www.example.com/checkout/chk_88291"),
)
Braze.getInstance(context).logEcommerceEvent(checkoutStartedEvent)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import com.braze.Braze
import com.braze.models.outgoing.BrazeProperties
import com.braze.models.recommended.ecommerce.EcommerceProduct
import com.braze.models.recommended.ecommerce.OrderPlacedEvent
val products = listOf(
EcommerceProduct(
productId = "SKU-RUN-4821",
productName = "Ultraboost Running Shoe",
variantId = "UB-BLK-11",
price = 189.99,
quantity = 1,
),
)
val orderPlacedEvent = OrderPlacedEvent(
orderId = "ord_77821",
currency = "USD",
source = "android",
totalValue = 224.96,
products = products,
cartId = "cart_abc123",
totalDiscounts = 10.0,
discounts = listOf(
mapOf("code" to "SPRING10", "amount" to 10.0, "type" to "percentage"),
),
metadata = BrazeProperties().addProperty("order_status_url", "https://www.example.com/orders/ord_77821/status"),
)
Braze.getInstance(context).logEcommerceEvent(orderPlacedEvent)
Braze does not provide a typed SDK class for this event. Use logCustomEvent with a payload that matches the ecommerce.order_cancelled event schema.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import com.braze.Braze
import com.braze.models.outgoing.BrazeProperties
import org.json.JSONArray
import org.json.JSONObject
val properties = BrazeProperties(
JSONObject()
.put("order_id", "ord_77821")
.put("total_value", 224.96)
.put("currency", "USD")
.put("cancel_reason", "customer_request")
.put("source", "android")
.put(
"products",
JSONArray().put(
JSONObject()
.put("product_id", "SKU-RUN-4821")
.put("product_name", "Ultraboost Running Shoe")
.put("variant_id", "UB-BLK-11")
.put("quantity", 1)
.put("price", 189.99),
),
),
)
Braze.getInstance(context).logCustomEvent("ecommerce.order_cancelled", properties)
Braze does not provide a typed SDK class for this event. Use logCustomEvent with a payload that matches the ecommerce.order_refunded event schema.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import com.braze.Braze
import com.braze.models.outgoing.BrazeProperties
import org.json.JSONArray
import org.json.JSONObject
val properties = BrazeProperties(
JSONObject()
.put("order_id", "ord_77821")
.put("total_value", 189.99)
.put("currency", "USD")
.put("source", "android")
.put(
"products",
JSONArray().put(
JSONObject()
.put("product_id", "SKU-RUN-4821")
.put("product_name", "Ultraboost Running Shoe")
.put("variant_id", "UB-BLK-11")
.put("quantity", 1)
.put("price", 189.99),
),
),
)
Braze.getInstance(context).logCustomEvent("ecommerce.order_refunded", properties)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import com.braze.Braze;
import com.braze.models.outgoing.BrazeProperties;
import com.braze.models.recommended.ecommerce.ProductViewedEvent;
BrazeProperties metadata = new BrazeProperties()
.addProperty("sku", "SS-R-101")
.addProperty("category", "Apparel");
ProductViewedEvent productViewedEvent = new ProductViewedEvent(
/* productId */ "PROD101",
/* productName */ "Silk Scarf",
/* variantId */ "SCARF_RED_SILK",
/* price */ 150.00,
/* currency */ "EUR",
/* source */ "https://braze-fashion.eu",
/* imageUrl */ "https://braze-fashion.eu/images/scarf_red.jpg",
/* productUrl */ "https://braze-fashion.eu/products/scarf",
/* metadata */ metadata
);
Braze.getInstance(context).logEcommerceEvent(productViewedEvent);
Set action using CartUpdatedAction:
| Value | Wire value | Description |
|---|---|---|
CartUpdatedAction.ADD |
add |
Increase quantity or add a line. |
CartUpdatedAction.REMOVE |
remove |
Decrease quantity; remove the line at 0. |
CartUpdatedAction.REPLACE |
replace |
Replace the full cart (default). |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import com.braze.Braze;
import com.braze.models.recommended.ecommerce.CartUpdatedAction;
import com.braze.models.recommended.ecommerce.CartUpdatedEvent;
import com.braze.models.recommended.ecommerce.EcommerceProduct;
import java.util.Collections;
EcommerceProduct product = new EcommerceProduct(
/* productId */ "SKU-RUN-4821",
/* productName */ "Ultraboost Running Shoe",
/* variantId */ "UB-BLK-11",
/* price */ 189.99,
/* quantity */ 1
);
CartUpdatedEvent cartUpdatedEvent = new CartUpdatedEvent(
/* cartId */ "cart_abc123",
/* currency */ "USD",
/* source */ "android",
/* totalValue */ 189.99,
/* products */ Collections.singletonList(product),
/* metadata */ null,
/* action */ CartUpdatedAction.ADD
);
Braze.getInstance(context).logEcommerceEvent(cartUpdatedEvent);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import com.braze.Braze;
import com.braze.models.outgoing.BrazeProperties;
import com.braze.models.recommended.ecommerce.CheckoutStartedEvent;
import com.braze.models.recommended.ecommerce.EcommerceProduct;
import java.util.Collections;
EcommerceProduct product = new EcommerceProduct(
/* productId */ "SKU-RUN-4821",
/* productName */ "Ultraboost Running Shoe",
/* variantId */ "UB-BLK-11",
/* price */ 189.99,
/* quantity */ 1
);
BrazeProperties metadata = new BrazeProperties()
.addProperty("checkout_url", "https://www.example.com/checkout/chk_88291");
CheckoutStartedEvent checkoutStartedEvent = new CheckoutStartedEvent(
/* checkoutId */ "chk_88291",
/* currency */ "USD",
/* source */ "android",
/* totalValue */ 234.96,
/* products */ Collections.singletonList(product),
/* cartId */ "cart_abc123",
/* metadata */ metadata
);
Braze.getInstance(context).logEcommerceEvent(checkoutStartedEvent);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import com.braze.Braze;
import com.braze.models.outgoing.BrazeProperties;
import com.braze.models.recommended.ecommerce.EcommerceProduct;
import com.braze.models.recommended.ecommerce.OrderPlacedEvent;
import java.util.Collections;
EcommerceProduct product = new EcommerceProduct(
/* productId */ "SKU-RUN-4821",
/* productName */ "Ultraboost Running Shoe",
/* variantId */ "UB-BLK-11",
/* price */ 189.99,
/* quantity */ 1
);
BrazeProperties metadata = new BrazeProperties()
.addProperty("order_status_url", "https://www.example.com/orders/ord_77821/status");
OrderPlacedEvent orderPlacedEvent = new OrderPlacedEvent(
/* orderId */ "ord_77821",
/* currency */ "USD",
/* source */ "android",
/* totalValue */ 224.96,
/* products */ Collections.singletonList(product),
/* cartId */ "cart_abc123",
/* totalDiscounts */ 10.0,
/* discounts */ null,
/* metadata */ metadata
);
Braze.getInstance(context).logEcommerceEvent(orderPlacedEvent);
Braze does not provide a typed SDK class for this event. Use logCustomEvent with a payload that matches the ecommerce.order_cancelled event schema.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import com.braze.Braze;
import com.braze.models.outgoing.BrazeProperties;
import org.json.JSONArray;
import org.json.JSONObject;
Braze.getInstance(context).logCustomEvent(
"ecommerce.order_cancelled",
new BrazeProperties(new JSONObject()
.put("order_id", "ord_77821")
.put("total_value", 224.96)
.put("currency", "USD")
.put("cancel_reason", "customer_request")
.put("source", "android")
.put("products", new JSONArray()
.put(new JSONObject()
.put("product_id", "SKU-RUN-4821")
.put("product_name", "Ultraboost Running Shoe")
.put("variant_id", "UB-BLK-11")
.put("quantity", 1)
.put("price", 189.99)))));
Braze does not provide a typed SDK class for this event. Use logCustomEvent with a payload that matches the ecommerce.order_refunded event schema.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import com.braze.Braze;
import com.braze.models.outgoing.BrazeProperties;
import org.json.JSONArray;
import org.json.JSONObject;
Braze.getInstance(context).logCustomEvent(
"ecommerce.order_refunded",
new BrazeProperties(new JSONObject()
.put("order_id", "ord_77821")
.put("total_value", 189.99)
.put("currency", "USD")
.put("source", "android")
.put("products", new JSONArray()
.put(new JSONObject()
.put("product_id", "SKU-RUN-4821")
.put("product_name", "Ultraboost Running Shoe")
.put("variant_id", "UB-BLK-11")
.put("quantity", 1)
.put("price", 189.99)))));
iOS
The Swift SDK provides typed eCommerce event classes—ProductViewedEvent, CartUpdatedEvent, CheckoutStartedEvent, and OrderPlacedEvent—that you build and pass to logEcommerceEvent. Use ProductLineItem for the products in cart, checkout, and order events. Each initializer is throwing, so wrap it in try? and log the event only when construction succeeds.
This is available in Swift SDK version 15.0.0 and later.
ecommerce.order_cancelled and ecommerce.order_refunded are not available as typed Swift SDK classes. Log them with logCustomEvent.
Code examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if let productViewedEvent = try? Braze.Ecommerce.ProductViewedEvent(
productId: "4111176",
productName: "Torchie runners",
variantId: "4111176700",
imageUrl: "https://braze-apparel.com/images/products/large/torchie-runners.jpg",
productUrl: "https://braze-apparel.com/footwear-categories/sneakers/braze-orange-torchie-runners/",
price: 85,
currency: "GBP",
source: "https://braze-apparel.com/",
metadata: [
"sku": "",
"color": "ORANGE",
"size": "6",
"brand": "Braze"
],
typeIdentifiers: ["price_drop", "back_in_stock"]
) {
AppDelegate.braze?.logEcommerceEvent(productViewedEvent)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if let productLine = try? Braze.Ecommerce.ProductLineItem(
productId: "8266836345064",
productName: "Classic T-Shirt",
variantId: "44610569208040",
imageUrl: "https://braze-apparel.com/images/tshirt-blue-medium.jpg",
productUrl: "https://braze-apparel.com/products/classic-tshirt?variant=44610569208040",
quantity: 2,
price: 99.99,
metadata: [
"sku": "TSH-BLU-M",
"color": "BLUE",
"size": "Medium",
"brand": "Braze"
]
), let cartUpdatedEvent = try? Braze.Ecommerce.CartUpdatedEvent(
cartId: "cart_12345",
totalValue: 199.98,
currency: "USD",
products: [productLine],
source: "https://braze-apparel.com",
metadata: [:]
) {
AppDelegate.braze?.logEcommerceEvent(cartUpdatedEvent)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if let productLine = try? Braze.Ecommerce.ProductLineItem(
productId: "632910392",
productName: "Wireless Headphones",
variantId: "808950810",
quantity: 1,
price: 199.98,
metadata: [
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
]
), let checkoutStartedEvent = try? Braze.Ecommerce.CheckoutStartedEvent(
checkoutId: "checkout_abc123",
cartId: "cart_12345",
totalValue: 199.98,
currency: "USD",
products: [productLine],
source: "https://braze-audio.com",
metadata: [
"checkout_url": "https://checkout.braze-audio.com/abc123"
]
) {
AppDelegate.braze?.logEcommerceEvent(checkoutStartedEvent)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
if let productLine = try? Braze.Ecommerce.ProductLineItem(
productId: "632910392",
productName: "Wireless Headphones",
variantId: "808950810",
quantity: 1,
price: 199.98,
metadata: [
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
]
), let orderPlacedEvent = try? Braze.Ecommerce.OrderPlacedEvent(
orderId: "order_67890",
cartId: "cart_12345",
totalValue: 189.98,
currency: "USD",
totalDiscounts: 10.00,
discounts: [.structured(code: "SAVE10", amount: 10.00, type: "fixed")],
products: [productLine],
source: "https://braze-audio.com",
metadata: [
"order_status_url": "https://braze-audio.com/orders/67890/status",
"order_number": "ORD-2024-001234",
"tags": ["electronics", "audio"],
"referring_site": "https://www.e-referrals.com",
"payment_gateway_names": ["tap2pay", "dotcash"]
]
) {
AppDelegate.braze?.logEcommerceEvent(orderPlacedEvent)
}
Braze does not provide a typed SDK class for this event. Use logCustomEvent with a payload that matches the ecommerce.order_cancelled event schema.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
let discounts: [[String: Any]] = [
[
"code": "SAVE10",
"amount": 10.00
]
]
let products: [[String: Any]] = [
[
"product_id": "632910392",
"product_name": "Wireless Headphones",
"variant_id": "808950810",
"quantity": 1,
"price": 199.98,
"metadata": [
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
]
]
]
let properties: [String: Any] = [
"order_id": "order_67890",
"cancel_reason": "customer changed mind",
"total_value": 189.98,
"subtotal_value": 169.98,
"tax": 14.40,
"shipping": 5.60,
"currency": "USD",
"total_discounts": 10.00,
"discounts": discounts,
"products": products,
"source": "https://braze-audio.com",
"metadata": [
"order_status_url": "https://braze-audio.com/orders/67890/status",
"order_number": "ORD-2024-001234",
"tags": ["cancelled", "customer_request"]
]
]
AppDelegate.braze?.logCustomEvent(name: "ecommerce.order_cancelled", properties: properties)
Braze does not provide a typed SDK class for this event. Use logCustomEvent with a payload that matches the ecommerce.order_refunded event schema.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
let discounts: [[String: Any]] = [
[
"code": "SAVE5",
"amount": 5.00
]
]
let products: [[String: Any]] = [
[
"product_id": "632910392",
"product_name": "Wireless Headphones",
"variant_id": "808950810",
"quantity": 1,
"price": 99.99,
"metadata": [
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
]
]
]
let properties: [String: Any] = [
"order_id": "order_67890",
"total_value": 99.99,
"currency": "USD",
"total_discounts": 5.00,
"discounts": discounts,
"products": products,
"source": "https://braze-audio.com",
"metadata": [
"order_status_url": "https://braze-audio.com/orders/67890/status",
"order_note": "Customer requested refund due to defective item",
"order_number": "ORD-2024-001234",
"tags": ["refund", "defective"]
]
]
AppDelegate.braze?.logCustomEvent(name: "ecommerce.order_refunded", properties: properties)
Web
On Web SDK 6.8.0+, call logEcommerceEvent with an event name and properties. On legacy SDK versions, call logCustomEvent with the event name and a properties object. ecommerce.order_cancelled and ecommerce.order_refunded use logCustomEvent.
Code examples
On newer SDK versions, call logEcommerceEvent():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
braze.logEcommerceEvent({
"name": "ecommerce.product_viewed",
"properties": {
"product_id": "4111176",
"product_name": "Torchie runners",
"variant_id": "4111176700",
"image_url": "https://braze-apparel.com/images/products/large/torchie-runners.jpg",
"product_url": "https://braze-apparel.com/footwear-categories/sneakers/braze-orange-torchie-runners/",
"price": 85,
"currency": "GBP",
"source": "https://braze-apparel.com/",
"metadata": {
"sku": "",
"color": "ORANGE",
"size": "6",
"brand": "Braze"
}
}
});
On legacy SDK versions, call logCustomEvent():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
braze.logCustomEvent("ecommerce.product_viewed", {
"product_id": "4111176",
"product_name": "Torchie runners",
"variant_id": "4111176700",
"image_url": "https://braze-apparel.com/images/products/large/torchie-runners.jpg",
"product_url": "https://braze-apparel.com/footwear-categories/sneakers/braze-orange-torchie-runners/",
"price": 85,
"currency": "GBP",
"source": "https://braze-apparel.com/",
"metadata": {
"sku": "",
"color": "ORANGE",
"size": "6",
"brand": "Braze"
}
});
On newer SDK versions, call logEcommerceEvent():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
braze.logEcommerceEvent({
"name": "ecommerce.cart_updated",
"properties": {
"cart_id": "cart_12345",
"currency": "USD",
"total_value": 199.98,
"products": [
{
"product_id": "8266836345064",
"product_name": "Classic T-Shirt",
"variant_id": "44610569208040",
"image_url": "https://braze-apparel.com/images/tshirt-blue-medium.jpg",
"product_url": "https://braze-apparel.com/products/classic-tshirt?variant=44610569208040",
"quantity": 2,
"price": 99.99,
"metadata": {
"sku": "TSH-BLU-M",
"color": "BLUE",
"size": "Medium",
"brand": "Braze"
}
}
],
"source": "https://braze-apparel.com",
"metadata": {}
}
});
On legacy SDK versions, call logCustomEvent():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
braze.logCustomEvent("ecommerce.cart_updated", {
"cart_id": "cart_12345",
"currency": "USD",
"total_value": 199.98,
"subtotal_value": 179.98,
"tax": 15.00,
"shipping": 5.00,
"products": [
{
"product_id": "8266836345064",
"product_name": "Classic T-Shirt",
"variant_id": "44610569208040",
"image_url": "https://braze-apparel.com/images/tshirt-blue-medium.jpg",
"product_url": "https://braze-apparel.com/products/classic-tshirt?variant=44610569208040",
"quantity": 2,
"price": 99.99,
"metadata": {
"sku": "TSH-BLU-M",
"color": "BLUE",
"size": "Medium",
"brand": "Braze"
}
}
],
"source": "https://braze-apparel.com",
"metadata": {}
});
On newer SDK versions, call logEcommerceEvent():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
braze.logEcommerceEvent({
"name": "ecommerce.checkout_started",
"properties": {
"checkout_id": "checkout_abc123",
"cart_id": "cart_12345",
"total_value": 199.98,
"currency": "USD",
"products": [
{
"product_id": "632910392",
"product_name": "Wireless Headphones",
"variant_id": "808950810",
"quantity": 1,
"price": 199.98,
"metadata": {
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
}
}
],
"source": "https://braze-audio.com",
"metadata": {
"checkout_url": "https://checkout.braze-audio.com/abc123"
}
}
});
On legacy SDK versions, call logCustomEvent():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
braze.logCustomEvent("ecommerce.checkout_started", {
"checkout_id": "checkout_abc123",
"cart_id": "cart_12345",
"total_value": 199.98,
"subtotal_value": 179.98,
"tax": 15.00,
"shipping": 5.00,
"currency": "USD",
"products": [
{
"product_id": "632910392",
"product_name": "Wireless Headphones",
"variant_id": "808950810",
"quantity": 1,
"price": 199.98,
"metadata": {
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
}
}
],
"source": "https://braze-audio.com",
"metadata": {
"checkout_url": "https://checkout.braze-audio.com/abc123"
}
});
On newer SDK versions, call logEcommerceEvent():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
braze.logEcommerceEvent({
"name": "ecommerce.order_placed",
"properties": {
"order_id": "order_67890",
"cart_id": "cart_12345",
"total_value": 189.98,
"currency": "USD",
"total_discounts": 10.00,
"discounts": [
{
"code": "SAVE10",
"amount": 10.00
}
],
"products": [
{
"product_id": "632910392",
"product_name": "Wireless Headphones",
"variant_id": "808950810",
"quantity": 1,
"price": 199.98,
"metadata": {
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
}
}
],
"source": "https://braze-audio.com",
"metadata": {
"order_status_url": "https://braze-audio.com/orders/67890/status",
"order_number": "ORD-2024-001234",
"tags": ["electronics", "audio"],
"referring_site": "https://www.e-referrals.com",
"payment_gateway_names": ["tap2pay", "dotcash"]
}
}
});
On legacy SDK versions, call logCustomEvent():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
braze.logCustomEvent("ecommerce.order_placed", {
"order_id": "order_67890",
"cart_id": "cart_12345",
"total_value": 189.98,
"subtotal_value": 169.98,
"tax": 14.40,
"shipping": 5.60,
"currency": "USD",
"total_discounts": 10.00,
"discounts": [
{
"code": "SAVE10",
"amount": 10.00
}
],
"products": [
{
"product_id": "632910392",
"product_name": "Wireless Headphones",
"variant_id": "808950810",
"quantity": 1,
"price": 199.98,
"metadata": {
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
}
}
],
"source": "https://braze-audio.com",
"metadata": {
"order_status_url": "https://braze-audio.com/orders/67890/status",
"order_number": "ORD-2024-001234",
"tags": ["electronics", "audio"],
"referring_site": "https://www.e-referrals.com",
"payment_gateway_names": ["tap2pay", "dotcash"]
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
braze.logCustomEvent("ecommerce.order_cancelled", {
"order_id": "order_67890",
"cancel_reason": "customer changed mind",
"total_value": 189.98,
"subtotal_value": 169.98,
"tax": 14.40,
"shipping": 5.60,
"currency": "USD",
"total_discounts": 10.00,
"discounts": [
{
"code": "SAVE10",
"amount": 10.00
}
],
"products": [
{
"product_id": "632910392",
"product_name": "Wireless Headphones",
"variant_id": "808950810",
"quantity": 1,
"price": 199.98,
"metadata": {
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
}
}
],
"source": "https://braze-audio.com",
"metadata": {
"order_status_url": "https://braze-audio.com/orders/67890/status",
"order_number": "ORD-2024-001234",
"tags": ["cancelled", "customer_request"]
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
braze.logCustomEvent("ecommerce.order_refunded", {
"order_id": "order_67890",
"total_value": 99.99,
"currency": "USD",
"total_discounts": 5.00,
"discounts": [
{
"code": "SAVE5",
"amount": 5.00
}
],
"products": [
{
"product_id": "632910392",
"product_name": "Wireless Headphones",
"variant_id": "808950810",
"quantity": 1,
"price": 99.99,
"metadata": {
"sku": "WH-BLK-PRO",
"color": "Black",
"brand": "BrazeAudio"
}
}
],
"source": "https://braze-audio.com",
"metadata": {
"order_status_url": "https://braze-audio.com/orders/67890/status",
"order_note": "Customer requested refund due to defective item",
"order_number": "ORD-2024-001234",
"tags": ["refund", "defective"]
}
});
Manual logging with logCustomEvent
To manually log a recommended event, call logCustomEvent with the exact event name (for example, ecommerce.product_viewed) and a manually built BrazeProperties or JSONObject payload. The SDK does not validate recommended-event schemas for manual calls. Braze validates these payloads during ingestion:
- Valid payloads are processed as recommended events with full post-processing.
- Invalid payloads (missing required fields, wrong types, extra top-level properties) are dropped after ingestion. Failures appear in the workspace SDK processing log and the failure summary email.
Use logEcommerceEvent when possible so you catch invalid data before it leaves the app. For general logCustomEvent usage, see Log custom events.