Merge field syntax for email and callout templates
This article describes the merge field syntax you can use when creating or editing email or callout templates.
Overview
A merge field serves as a placeholder in email and callout templates to automatically incorporate values from objects when an email or a callout notification is triggered. Merge fields are enclosed by angle brackets or double curly brackets, which depend on the merge field type.
Email and callout templates support all merge field syntax for HTML templates. For more information, see Merge field syntax for HTML templates.
The following table describes the main differences between merge fields in email and callout templates, and HTML templates:
Email and callout template | HTML template | |
---|---|---|
Support data source and system merge fields? | Yes | No |
Root object of a template |
The base object of the standard or custom event linked to the email template. For example, if the related event is Order Processed, the base object is Order. |
One of the following objects depending on the template type:
|
Limit on the number of merge fields in a template | >= 0 | >= 1 |
Supported merge field types
Email and callout templates support the following merge field types:
- Advanced merge field
- Data source merge field
- System merge field
Field type | When to use | Example | Note |
---|---|---|---|
Advanced merge field |
Use advanced merge fields for the following scenarios:
|
|
|
Data source merge field |
Use data source merge fields to retrieve field values from the objects that are supported by Data Source Exports. Normally, the base object or joined objects of the event to which the email or callout template is related. For more information, see Data source merge fields for email and callout templates. |
|
Data source merge fields are defined at the system level and do not support syntax customization, so you cannot use the advanced merge field syntax and functions on these fields. |
System merge field |
Use system merge fields to retrieve system-level information, such as the date of today, or your tenant information. For more information, see System merge fields for email and callout templates. |
|
System merge fields are defined at the system level and do not support syntax customization, so you cannot use the advanced merge field syntax and functions on these fields. |
Merge field syntax for fields from the base object or joined objects
Most standard or custom events are defined on base objects.
The following table lists the base object for some commonly used events:
Event name | Event type | Base object | Base object type |
---|---|---|---|
Bill Run Completion | Standard event | Bill Run | Standard object |
Invoice Due | Standard event | Invoice | Standard object |
Order Processed | Standard event | Order | Standard object |
Account Created | Custom event | Account | Standard object |
Vehicle Created | Custom event | Vehicle | Custom object |
When creating or editing an email or a callout template, you can use fields not only from the base object but also from joined objects. For example, if the base object is Invoice, you can use fields from Invoice and fields from Account, Bill To, Send To, and Default Payment Method objects.
The following table lists merge field syntax for each object field:
Object | Field | Merge field syntax |
---|---|---|
Invoice (base object) | Amount | {{Invoice.Amount}} |
MyData__c | {{Invoice.MyData__c}} |
|
Account (joined object) | AccountName | {{Invoice.Account.AccountName}} |
Bill To (joined object) | FirstName | {{Invoice.Account.BillTo.FirstName}} |
Note that advanced merge fields must start with the base object related to the event.
For example, if you would like to retrieve a product name from an OrderAction event, you should access the Product object in the following order:
OrderAction → Subscription → RatePlan → Product
For more information on extended objects, see Zuora business object model.
If you receive the following error message when creating email templates:
"Email body rendering error: X can not be used as root level merge field in a template”
It indicates that there was an issue with getting the right object and field in the notification because of incorrect merge field syntax.
As shown in the following table, if the merge field is for email or callout templates related to the Invoice Due event, the first object must be Invoice instead of Account:
Correct | Incorrect |
---|---|
{{Invoice.Account.AccountName}} |
{{Account.AccountName}} |
You can use the following merge field syntax if the base object is a custom object:
Object | Field | Merge field syntax |
---|---|---|
Vehicle (base object) | Color__c | <default__vehicle.Color__c> |
Model__c | <default__vehicle.Model__c> |
Merge field syntax for custom fields from custom objects
When using custom fields from custom objects as merge fields in email or callout templates, you must follow these rules:
- Use section and variable merge fields (start with
{{#...}}
and end with{{/...}}
). - Add the
default__
prefix to custom object names. - Use custom object names in their plural form.
For more information and examples about merge field syntax for custom objects, see Use custom objects in HTML templates.
There are two main scenarios for using custom object fields as merge fields in email or callout templates:
Scenario | Merge field syntax | Description |
---|---|---|
Fields from a custom object linked to the base object or a joined object | {{#baseobject.default__myobjects}} |
The mydata__c value of each myobject record linked to a particular baseobject record (in the context of this event). |
Fields from an independent custom object | {{#default__myobjects}} |
The mydata__c value of each myobject record. |
Merge field resolving
When an event is triggered, a specific object record of the base object type is considered as the context data. Zuora replaces all merge fields in email or callout templates with the corresponding values from the context data or other related objects before sending notifications.
The following table provides details on the base object and context data for some commonly used events:
Event name | Base object | Context data |
---|---|---|
Bill Run Completion | Bill Run | The completed bill run |
Invoice Due | Invoice | The invoice whose invoice due date matches the criteria set in the notification |
Order Processed | Order | The order that is processed |
Account Created | Account | The newly created account |
Vehicle Created | Vehicle | The newly created vehicle |
For example, suppose that the context data (an invoice) of a triggered Invoice Due event is as follows:
{ "id": "8ad0962d87bc17870187c0ff4dc80cca", "invoiceNumber": "INV00065283", "accountId": "2c92c0f959916d780159973781be2f15", "amount": 150.000000000, … }
The account info of this invoice is as follows:
{ "basicInfo": { "id": "2c92c0f959916d780159973781be2f15", "accountNumber": "A00000077", "status": "Active", … }, … }
The custom object records linked to the Invoice object are as follows:
{ "Id": "14b65982-a61f-4452-b89d-59b072506a08", "type": "MyObject", "invoiceID__c": "8ad0962d87bc17870187c0ff4dc80cca", "mydata__c": "My Data 1", … }, { "Id": "66e1a250-c544-4cc9-8ebc-72dcce36c40c", "type": "MyObject", "invoiceID__c": "8ad0962d87bc17870187c0ff4dc80cca", "mydata__c": "My Data 2", … }, { "Id": "f25ecd70-0875-4dec-8afc-9228d8de0796", "type": "MyObject", "invoiceID__c": "8a9099d584ccc5180184cfe470277450", "mydata__c": "My Data 3", … }
The first two records are linked to the context invoice of this event, and the third record is linked to another invoice.
The following table shows the values of merge fields in email or callout templates related to the Invoice Due event:
Merge field | Value |
---|---|
{{Invoice.Amount}} |
150.000000000 |
{{Invoice.Account.AccountNumber}} |
A00000077 |
{{#Invoice.default__myobjects}} |
My Data 1 My Data 2 |
{{#default__myobjects}} |
My Data 1 My Data 2 My Data 3 |
Examples of using merge fields
Field values from the context invoice
Use the following example to display field values from the context invoice of invoice-related events, such as Invoice Due or Invoice Posted:
{{#Invoice}} Invoice Number: {{InvoiceNumber}} Invoice Date: {{InvoiceDate}} Invoice Due Date: {{DueDate}} Account Name: {{Account.Name}} First Name (Bill To): {{Account.BillTo.FirstName}} {{/Invoice}}
The returned content is as follows:
Invoice Number: INV00065283 Invoice Date: 2023-11-20 Invoice Due Date: 2023-12-20 Account Name: ABC Company First Name (Bill To): Mike
Field values from the custom object records linked to the context account
Use the following example to display field values from the Entitlement custom object records linked to the context account:
{{#Account.default__entitlements|SortBy(Entitled__c, ASC)}} Entitled: {{Entitled__c}} Usage: {{Usage__c}} Status: {{Status__c}} {{/Account.default__entitlements|SortBy(Entitled__c, ASC)}}
The entitlements linked to this particular account are sorted by entitled values in ascending order as follows:
Entitled: 100 Usage: 20 Status: Active Entitled: 150 Usage: 45 Status: Trial Entitled: 220 Usage: 0 Status: Active
Field values from the last created custom object record
Use the following example to display the price of the last created Vehicle object record. This example applies to any event.
{{#default__vehicles|Last(1)}} Price: {{Price__c}} {{#default__vehicles|Last(1)}}
The returned content is as follows:
Price: 35,000
Localized values of date and number fields
You can format the field values using the Localise (locale_NAME)
function, which applies to date, datetime, and numeric fields.
When no local_NAME
parameter is specified, the formatting is based on the locale setting of the related communication profile.
Invoice Amount (default): {{Invoice.Amount}} Invoice Amount (English - United States): {{Invoice.Amount|Localise}} Invoice Amount (German - Germany): {{Invoice.Amount|Localise(de_DE)}} Invoice Amount (French - France): {{Invoice.Amount|Localise(fr_FR)}} Invoice Date (default): {{Invoice.InvoiceDate}} Invoice Date (English - United States): {{Invoice.InvoiceDate|Localise}} Invoice Date (German - Germany): {{Invoice.InvoiceDate|Localise(de_DE)}} Invoice Date (French - France): {{Invoice.InvoiceDate|Localise(fr_FR)}}
The returned content is as follows:
Invoice Amount (default): 10.23 Invoice Amount (English - United States): 10.23 Invoice Amount (German - Germany): 10,23 Invoice Amount (French - France): 10,23 Invoice Date (default): 11/28/2023 Invoice Date (English - United States): 11/28/2023 Invoice Date (German - Germany): 28.11.2023 Invoice Date (French - France): 28/11/2023
For more information, see Localise function.
Field values from the products related to the context subscription
A subscription can contain multiple rate plans and each rate plan is associated with a product.
Use the following example to display field values from the products related to the context subscription:
{{#Subscription.RatePlans}} Product Name: {{ProductRatePlan.Product.Name}} {{/Subscription.RatePlans}}
The returned content is as follows:
Product Name: Gold Membership Product Name: …
Field values from the products related to the context order action
The subscription that relates to an order action can contain multiple rate plans, and each rate plan is associated with a product.
Use the following example to display field values from the products related to the context order action:
{{#OrderAction.Subscription.RatePlans}} Product Name: {{ProductRatePlan.Product.Name}} {{/OrderAction.Subscription.RatePlans}}
The returned content is as follows:
Product Name: Gold Membership Product Name: …
Field values from the rate plan charge and rate plan charge tiers related to the context rating result
The rating result object is linked to a rate plan charge, which might contain multiple rate plan charge tiers with pricing information.
Use the following example to display field values from the rate plan charge and rate plan charge tiers related to the context rating result:
{{#RatingResult}} Rating Result - Amount: {{Amount}} Rating Result - Quantity: {{Quantity}} {{#RatePlanCharge}} Rate Plan Charge - Name: {{Name}} Pricing information: {{#RatePlanChargeTiers}} Tier: {{Id}} Starting Unit: {{StartingUnit}} Ending Unit: {{EndingUnit}} Price: {{Price}} {{/RatePlanChargeTiers}} {{/RatePlanCharge}} {{/RatingResult}}
The returned content is as follows:
Rating Result - Amount: 49.5 Rating Result - Quantity: 55 Rate Plan Charge - Name: Volume-type charge Pricing information: Tier: 1 Starting Unit: 0.0 Ending Unit: 100.0 Price: 0.9 Tier: 2 Starting Unit: 100.1 Ending Unit: 200.0 Price: 0.8
Field values from the invoices associated with the context payment
The merge field syntax for retrieving information from invoices associated with the context payment varies depending on whether the Invoice Settlement feature is enabled or not.
If the Invoice Settlement feature is enabled, you can retrieve the invoices through the PaymentPart object:
{{#Payment.PaymentParts}} Invoice Number: {{Invoice.InvoiceNumber}} {{/Payment.PaymentParts}}
If the Invoice Settlement feature is disabled, you can retrieve the invoices through the InvoicePayment object:
{{#Payment.InvoicePayments}} Invoice Number: {{Invoice.InvoiceNumber}} {{/Payment.InvoicePayments}}
When multiple invoices are associated with the payment, the returned content is as follows:
Invoice Number: INV00000001 Invoice Number: INV00000002 …
Use evaluation expressions to dynamically generate content
When evaluation expressions (Wp_Eval
) are used in email or callout templates, Zuora evaluates the expressions and then generates the content. For more information, see Expressions.
Use the following expression as an example.
You have paid {{#Wp_Eval}} {{Invoice.Amount}} - {{Invoice.Balance}} {{/Wp_Eval}} dollar(s).
Zuora replaces {{Invoice.Amount}}
and {{Invoice.Balance}}
with the real data 100
and 90
.
You have paid {{#Wp_Eval}} 100 - 90 {{/Wp_Eval}} dollar(s).
And then evaluates the expression and returns the following information:
You have paid 10 dollar(s).
Use evaluation expressions with if-else statements to dynamically generate content
You can use if-else statements in evaluation expressions to compare strings and dynamically generate content.
The following expression compares the tenant ID with TN1
.
{{#Wp_Eval}} "{{Tenant.ID}}" == "TN1" ? "The tenant ID is TN1" : "The tenant ID is not TN1" {{/Wp_Eval}}
If the tenant ID is TN1
, it returns the following information:
The tenant ID is TN1
Otherwise, the following information is returned:
The tenant ID is not TN1
The following expression is another example that compares the communication profile ID with CP1
.
{{#Wp_Eval}} "{{DataSource.Account.CommunicationProfileId}}" == "CP1" ? "<p>Dear {{DataSource.BillToContact.FirstName}},</p><p>...</p>" : "<p>Sehr geehrte/r {{DataSource.BillToContact.FirstName}},</p><p>...</p>" {{/Wp_Eval}} <p>Acme Inc.</p>
If the communication profile ID is CP1
, it returns the following information:
Dear John, … Acme Inc.
Otherwise, the following information is returned:
Sehr geehrte/r John, … Acme Inc.
Use evaluation expressions to filter data that contains specific strings
You can use the contains
function in evaluation expressions to check whether a merge field contains a specific string and return conditional content with if-else statements.
The following example returns the rate plan names that contain the keyword Discount
.
{{#OrderAction.Subscription.RatePlans}} {{#Wp_Eval}} "{{Name}}".contains("Discount") ? "" : "Discount plan: {{Name}}" {{/Wp_Eval}} {{/OrderAction.Subscription.RatePlans}}
However, if you have multiple rate plans and most of the names do not contain Discount
, it is recommended to use a custom field to indicate whether or not it is a discount rate plan.
For example, suppose that the DiscountFlag__c
custom field on the RatePlan object is set to 1
if it is a discount rate plan.
The following example returns the names of rate plans where the DiscountFlag__c
field equals 1
.
{{#OrderAction.Subscription.RatePlans|FilterByValue(DiscountFlag__c,EQ,1)}} Discount plan: {{Name}} {{/OrderAction.Subscription.RatePlans|FilterByValue(DiscountFlag__c,EQ,1)}}