Firmhouse uses webhooks to allow you to communicate with different applications and share data smoothly. You can specify the information you want to send when each event happens using liquid templates. To set up a webhook on the Firmhouse Portal, check out this guide .
In this guide, we will use JSON payloads as it's the most common format for webhooks. However, you can use any other format that you can create a template for with Liquid, such as XML or YAML.
For each event group, there are specific variables that you can use in liquid templates.
Asset
You can use these variables in your templates for all asset events.
Asset assigned
This event is triggered when an asset is assigned to a customer. You can check out this guide to see how you can assign an asset to a customer on Firmhouse Portal.
Example Template
Copy {
"event": "asset_assigned",
"asset": {
"id": "{{asset.id}}",
"productId": "{{asset.product.id}}",
"internalNumber": "{{asset.internal_number}}",
"externalNumber": "{{asset.external_number}}",
"status": "{{asset.status}}",
"purchasePrice": {{asset.purchase_price | default: 0 }}
},
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}"
}
}
As shown in the example template above, you can use the liquid filter default: to set a default value for a field. You can also use any other filter supported by liquid. Check out the list here .
Contract term
You can use these variables in your templates for contract term events.
Billing cycle skipped
This event is triggered when a customer fails to pay for a billing cycle.
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0 }}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split: ';' | join: "," %}
{
"event": "billing_cycle_skipped",
"subscribedPlan": {
"id": {{subscribed_plan.id}},
"activatedAt": "{{subscribed_plan.activated_at}}",
"billingCycleInterval": "{{subscribed_plan.billing_cycle_interval}}",
"billingCycleIntervalUnit": "{{subscribed_plan.billing_cycle_interval_unit}}",
"fixedCommitmentEndsAt": "{{subscribed_plan.fixed_commitment_ends_at}}",
"fixedCommitmentPeriod": "{{subscribed_plan.fixed_commitment_period}}",
"fixedCommitmentUnit": "{{subscribed_plan.fixed_commitment_unit}}"
},
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}
As you can see in the example above, you can use tags like capture
and for .. in
to extract values from arrays easily. You can also use other tags supported by liquid. You can check the full list here .
Collection Case
You can use these variables in your templates for extra field events.
Collection Case Closed
This event is triggered when the status of collection case is changed to closed.
Example Template
Copy {%- capture invoice_items_string -%}
{%- for invoice_item in invoices -%}
{"id":"{{invoice_item.id}}", "number":"{{invoice_item.number}}", "amount": "{{invoice_item.amount}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign invoice_items = invoice_items_string | split: ';' | join: "," %}
{
"event": "collection_case_closed",
"collection_case": {
"id": "{{collection_case.id}}",
"status": "{{collection_case.status}}",
"created_at": "{{collection_case.created_at}}",
"updated_at": "{{collection_case.updated_at}}",
"case_number": "{{collection_case.case_number}}",
"project_id": "{{collection_case.project_id}}",
"case_type": "{{collection_case.case_type}}",
"invoices": [{{invoice_items }}]
},
"subscription": {
"id": "{{subscription.id}}"
}
}
Collection Case Created
This event is triggered when a collection case is created for an invoice.
Example Template
Copy {%- capture invoice_items_string -%}
{%- for invoice_item in invoices -%}
{"id":"{{invoice_item.id}}", "number":"{{invoice_item.number}}", "amount": "{{invoice_item.amount}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign invoice_items = invoice_items_string | split: ';' | join: "," %}
{
"event": "collection_case_created",
"collection_case": {
"id": "{{collection_case.id}}",
"status": "{{collection_case.status}}",
"created_at": "{{collection_case.created_at}}",
"updated_at": "{{collection_case.updated_at}}",
"case_number": "{{collection_case.case_number}}",
"project_id": "{{collection_case.project_id}}",
"case_type": "{{collection_case.case_type}}",
"invoices": [{{invoice_items }}]
},
"subscription": {
"id": "{{subscription.id}}"
}
}
Collection Case Open
This event is triggered when the status of collection case is changed to open.
Example Template
Copy {%- capture invoice_items_string -%}
{%- for invoice_item in invoices -%}
{"id":"{{invoice_item.id}}", "number":"{{invoice_item.number}}", "amount": "{{invoice_item.amount}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign invoice_items = invoice_items_string | split: ';' | join: "," %}
{
"event": "collection_case_open",
"collection_case": {
"id": "{{collection_case.id}}",
"status": "{{collection_case.status}}",
"created_at": "{{collection_case.created_at}}",
"updated_at": "{{collection_case.updated_at}}",
"case_number": "{{collection_case.case_number}}",
"project_id": "{{collection_case.project_id}}",
"case_type": "{{collection_case.case_type}}",
"invoices": [{{invoice_items }}]
},
"subscription": {
"id": "{{subscription.id}}"
}
}
If you added extra fields to your project, you can use these events to monitor when they are changed. Please check out this guide for instructions on setting up extra fields on Firmhouse Portal.
You can use these variables in your templates for extra field events.
extra_field
This field contains all extra_fields you configured for the project. You can access each with `{{extra_field.field_name}}
. The field names here are using snake_case. If you have an extra field with the name "Custom Message", you can access that with {{extra_field.custom_message}}
tag.
This event is triggered when one of the extra fields you defined for your project is updated on a subscription.
Example Template
Copy {
"event": "extra_field_answer_updated",
"extra_field": {
"how_did_you_hear_about_us": "{{extra_field.how_did_you_hear_about_us}}",
"custom_message": "{{extra_field.custom_message}}"
},
"subscription": {
"id": "{{subscription.id}}"
}
}
Invoice
You can use these variables in your templates for all invoice events.
Invoice invoiced
This event is triggered when an invoice is created.
Example Template
Copy {%- capture invoice_line_items_string -%}
{%- for invoice_line_item in invoice.invoice_line_items -%}
{"description": "{{invoice_line_item.description}}", "id":"{{invoice_line_item.id}}","quantity": {{invoice_line_item.quantity}}, "totalAmountIncludingTaxCents": {{invoice_line_item.total_amount_including_tax_cents}}, "lineItemType": "{{invoice_line_item.line_item_type}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign invoice_line_items = invoice_line_items_string | split: ';' | join: "," %}
{
"event": "invoice_invoiced",
"subscription": {
"id": "{{subscription.id}}"
},
"invoice": {
"amountPriceCents": {{invoice.amount_price_cents}},
"currency": "{{invoice.currency}}",
"statusCode": "{{invoice.status_code}}",
"status": "{{invoice.status}}",
"invoiceLineItems": [{{invoice_line_items}}]
}
}
Invoice paid
This event is triggered when the payment for an invoice is paid successfully.
Example Template
Copy {%- capture invoice_line_items_string -%}
{%- for invoice_line_item in invoice.invoice_line_items -%}
{"description": "{{invoice_line_item.description}}", "id":"{{invoice_line_item.id}}","quantity": {{invoice_line_item.quantity}}, "totalAmountIncludingTaxCents": {{invoice_line_item.total_amount_including_tax_cents}}, "lineItemType": "{{invoice_line_item.line_item_type}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign invoice_line_items = invoice_line_items_string | split: ';' | join: "," %}
{
"event": "invoice_paid",
"subscription": {
"id": "{{subscription.id}}"
},
"invoice": {
"amountPriceCents": {{invoice.amount_price_cents}},
"currency": "{{invoice.currency}}",
"statusCode": "{{invoice.status_code}}",
"status": "{{invoice.status}}",
"invoiceLineItems": [{{invoice_line_items}}]
},
"payment": {
"id": "{{payment.payment_id}}",
"attemptsCount": {{payment.attempts_count}},
"description": "{{payment.description}}",
"payment_type": "{{payment.payment_type}}",
"status": "{{payment.status}}"
}
}
Order
You can use these variables in your templates for all order events.
Order confirmed
This event is triggered when an order gets confirmed.
Example Template
Copy {%- capture order_line_items_string -%}
{%- for order_line_item in invoice.invoice_line_items -%}
{"productTitle": "{{order_line_item.product.title}}", "productId":"{{order_line_item.product.id}}","quantity": {{order_line_item.quantity}}, "metadata": "{{order_line_item.metadata}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign order_line_items = order_line_items_string | split: ';' | join: "," %}
{
"event": "order_confirmed",
"order": {
"id": "{{order.id}}",
"amountCents": {{order.amount_cents | default: 0 }},
"ammountCurrency": "{{order.amount_currency}}",
"orderLines": [{{order_line_items}}],
"shippingCostCents": {{order.shipping_cost_cents | default: 0 }},
"shippingCostsCurrency": "{{order.shipping_costs_currency}}",
"discountCents": {{order.discount_cents | default: 0 }},
"discountCurrency": "{{order.discount_currency}}",
"state": "{{order.state}}",
"status": "{{order.status}}"
},
"subscription": {
"id": "{{subscription.id}}"
}
}
Order fulfilled
This event is triggered when an order status becomes fulfilled .
Example Template
Copy {%- capture order_line_items_string -%}
{%- for order_line_item in invoice.invoice_line_items -%}
{"productTitle": "{{order_line_item.product.title}}", "productId":"{{order_line_item.product.id}}","quantity": {{order_line_item.quantity}}, "metadata": "{{order_line_item.metadata}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign order_line_items = order_line_items_string | split: ';' | join: "," %}
{
"event": "order_fulfilled",
"order": {
"id": "{{order.id}}",
"amountCents": {{order.amount_cents | default: 0 }},
"ammountCurrency": "{{order.amount_currency}}",
"orderLines": [{{order_line_items}}],
"shippingCostCents": {{order.shipping_cost_cents | default: 0 }},
"shippingCostsCurrency": "{{order.shipping_costs_currency}}",
"discountCents": {{order.discount_cents | default: 0 }},
"discountCurrency": "{{order.discount_currency}}",
"state": "{{order.state}}",
"status": "{{order.status}}"
},
"subscription": {
"id": "{{subscription.id}}"
}
}
Order pending
This event is triggered when an order status changes to pending .
Example Template
Copy {%- capture order_line_items_string -%}
{%- for order_line_item in invoice.invoice_line_items -%}
{"productTitle": "{{order_line_item.product.title}}", "productId":"{{order_line_item.product.id}}","quantity": {{order_line_item.quantity}}, "metadata": "{{order_line_item.metadata}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign order_line_items = order_line_items_string | split: ';' | join: "," %}
{
"event": "order_pending",
"order": {
"id": "{{order.id}}",
"amountCents": {{order.amount_cents | default: 0 }},
"ammountCurrency": "{{order.amount_currency}}",
"orderLines": [{{order_line_items}}],
"shippingCostCents": {{order.shipping_cost_cents | default: 0 }},
"shippingCostsCurrency": "{{order.shipping_costs_currency}}",
"discountCents": {{order.discount_cents | default: 0 }},
"discountCurrency": "{{order.discount_currency}}",
"state": "{{order.state}}",
"status": "{{order.status}}"
},
"subscription": {
"id": "{{subscription.id}}"
}
}
Ordered product
You can use these variables in your templates for all ordered product events.
Ordered product created
This event is triggered when a customer adds a new product to cart. This corresponds to createOrderedProduct
mutation on our GraphQL API. Note that if the same product added more than one times, since it's only a quantity update, Ordered product updated
event will be triggered.
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0 }}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split: ';' | join: "," %}
{
"event": "ordered_product_created",
"orderedProduct": {
"id": {{ordered_product.id}},
"product": {
"id": "{{ordered_product.product.id}}",
"price": "{{ordered_product.product.price_cents | default: 0 }}",
"sku": "{{ordered_product.product.sku}}"
},
"quantity": {{ordered_product.quantity}}
},
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}
Ordered product updated
This event is triggered when a product in cart is updated. This corresponds to updateOrderedProduct
and updateOrderedProductQuantity
mutations on our GraphQL API or when its automatically updated due to order state or shipment information change.
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0 }}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split: ';' | join: "," %}
{
"event": "ordered_product_updated",
"orderedProduct": {
"id": {{ordered_product.id}},
"product": {
"id": "{{ordered_product.product.id}}",
"price": "{{ordered_product.product.price_cents | default: 0 }}",
"sku": "{{ordered_product.product.sku}}"
},
"quantity": {{ordered_product.quantity}}
},
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}
Ordered product deleted
This event is triggered when a customer removed product from a cart. This corresponds to destroyOrderedProduct
mutation on our GraphQL API. ordered_product
variable in this even corresponds to the product removed from cart
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0 }}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split: ';' | join: "," %}
{
"event": "ordered_product_deleted",
"orderedProduct": {
"id": {{ordered_product.id}},
"product": {
"id": "{{ordered_product.product.id}}",
"price": "{{ordered_product.product.price_cents | default: 0 }}",
"sku": "{{ordered_product.product.sku}}"
},
"quantity": {{ordered_product.quantity}}
},
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}
Payment
You can use these variables in your templates for all payment events.
Payment failed
This event is triggered when a payment is failed.
Example Template
Copy {%- capture invoice_line_items_string -%}
{%- for invoice_line_item in invoice.invoice_line_items -%}
{"description": "{{invoice_line_item.description}}", "id":"{{invoice_line_item.id}}","quantity": {{invoice_line_item.quantity}}, "totalAmountIncludingTaxCents": {{invoice_line_item.total_amount_including_tax_cents}}, "lineItemType": "{{invoice_line_item.line_item_type}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign invoice_line_items = invoice_line_items_string | split: ';' | join: "," %}
{
"event": "payment_failed",
"subscription": {
"id": "{{subscription.id}}"
},
"invoice": {
"amountPriceCents": {{invoice.amount_price_cents}},
"currency": "{{invoice.currency}}",
"statusCode": "{{invoice.status_code}}",
"status": "{{invoice.status}}",
"invoiceLineItems": [{{invoice_line_items}}]
},
"payment": {
"id": "{{payment.payment_id}}",
"attemptsCount": {{payment.attempts_count}},
"description": "{{payment.description}}",
"payment_type": "{{payment.payment_type}}",
"status": "{{payment.status}}",
"scheduledRetryOn": "{{payment.scheduled_retry_on}}",
"payNowUrl": "{{payment.pay_now_url}}",
"failureReason": "{{payment.failure_reason}}"
}
}
Payment refunded
This event is triggered when a payment is refunded.
Example Template
Copy {%- capture invoice_line_items_string -%}
{%- for invoice_line_item in invoice.invoice_line_items -%}
{"description": "{{invoice_line_item.description}}", "id":"{{invoice_line_item.id}}","quantity": {{invoice_line_item.quantity}}, "totalAmountIncludingTaxCents": {{invoice_line_item.total_amount_including_tax_cents}}, "lineItemType": "{{invoice_line_item.line_item_type}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign invoice_line_items = invoice_line_items_string | split: ';' | join: "," %}
{
"event": "payment_refunded",
"subscription": {
"id": "{{subscription.id}}"
},
"invoice": {
"amountPriceCents": {{invoice.amount_price_cents}},
"currency": "{{invoice.currency}}",
"statusCode": "{{invoice.status_code}}",
"status": "{{invoice.status}}",
"invoiceLineItems": [{{invoice_line_items}}]
},
"payment": {
"id": "{{payment.payment_id}}",
"attemptsCount": {{payment.attempts_count}},
"description": "{{payment.description}}",
"payment_type": "{{payment.payment_type}}",
"status": "{{payment.status}}",
"scheduledRetryOn": "{{payment.scheduled_retry_on}}",
"payNowUrl": "{{payment.pay_now_url}}",
"failureReason": "{{payment.failure_reason}}"
}
}
Payment succeeded
This event is triggered when a payment successfully completes.
Example Template
Copy {%- capture invoice_line_items_string -%}
{%- for invoice_line_item in invoice.invoice_line_items -%}
{"description": "{{invoice_line_item.description}}", "id":"{{invoice_line_item.id}}","quantity": {{invoice_line_item.quantity}}, "totalAmountIncludingTaxCents": {{invoice_line_item.total_amount_including_tax_cents}}, "lineItemType": "{{invoice_line_item.line_item_type}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign invoice_line_items = invoice_line_items_string | split: ';' | join: "," %}
{
"event": "payment_succeeded",
"subscription": {
"id": "{{subscription.id}}"
},
"invoice": {
"amountPriceCents": {{invoice.amount_price_cents}},
"currency": "{{invoice.currency}}",
"statusCode": "{{invoice.status_code}}",
"status": "{{invoice.status}}",
"invoiceLineItems": [{{invoice_line_items}}]
},
"payment": {
"id": "{{payment.payment_id}}",
"attemptsCount": {{payment.attempts_count}},
"description": "{{payment.description}}",
"payment_type": "{{payment.payment_type}}",
"status": "{{payment.status}}"
}
}
Return order
You can use these variables in your templates for all return order events.
Return order cancelled
This event is triggered when a return order is cancelled.
Example Template
Copy {%- capture return_order_products_string -%}
{%- for item in return_order.return_order_products -%}
{"quantity": {{item.quantity}}, "orderedProductId": "{{item.ordered_product.id}}", "productId": "{{item.ordered_product.product_id}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign return_order_products = return_order_products_string | split: ';' | join: "," %}
{
"event": "return_order_cancelled",
"subscription": {
"id": "{{subscription.id}}"
},
"returnOrder": {
"id": "{{return_order.id}}",
"reason": "{{return_order.reason}}",
"desiredReturnDate": "{{return_order.desired_return_date}}",
"status": "{{return_order.status}}",
"trackingCode": "{{return_order.tracking_code}}",
"trackingUrl": "{{return_order.tracking_url}}",
"externalStatus": "{{return_order.external_status}}",
"externalReferance": "{{return_order.external_referance}}",
"externalUrl": "{{return_order.external_url}}",
"returnLabelFileUrl": "{{return_order.return_label_file_url}}",
"returnedOn": "{{return_order.returned_on}}",
"returnOrderProducts": [{{return_order_products}}]
}
}
Return order completed
This event is triggered when a return order is completed.
Example Template
Copy {%- capture return_order_products_string -%}
{%- for item in return_order.return_order_products -%}
{"quantity": {{item.quantity}}, "orderedProductId": "{{item.ordered_product.id}}", "productId": "{{item.ordered_product.product_id}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign return_order_products = return_order_products_string | split: ';' | join: "," %}
{
"event": "return_order_completed",
"subscription": {
"id": "{{subscription.id}}"
},
"returnOrder": {
"id": "{{return_order.id}}",
"reason": "{{return_order.reason}}",
"desiredReturnDate": "{{return_order.desired_return_date}}",
"status": "{{return_order.status}}",
"trackingCode": "{{return_order.tracking_code}}",
"trackingUrl": "{{return_order.tracking_url}}",
"externalStatus": "{{return_order.external_status}}",
"externalReferance": "{{return_order.external_referance}}",
"externalUrl": "{{return_order.external_url}}",
"returnLabelFileUrl": "{{return_order.return_label_file_url}}",
"returnedOn": "{{return_order.returned_on}}",
"returnOrderProducts": [{{return_order_products}}]
}
}
liq
Return order created
This event is triggered when a return order is created.
Example Template
Copy {%- capture return_order_products_string -%}
{%- for item in return_order.return_order_products -%}
{"quantity": {{item.quantity}}, "orderedProductId": "{{item.ordered_product.id}}", "productId": "{{item.ordered_product.product_id}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign return_order_products = return_order_products_string | split: ';' | join: "," %}
{
"event": "return_order_created",
"subscription": {
"id": "{{subscription.id}}"
},
"returnOrder": {
"id": "{{return_order.id}}",
"reason": "{{return_order.reason}}",
"desiredReturnDate": "{{return_order.desired_return_date}}",
"status": "{{return_order.status}}",
"trackingCode": "{{return_order.tracking_code}}",
"trackingUrl": "{{return_order.tracking_url}}",
"externalStatus": "{{return_order.external_status}}",
"externalReferance": "{{return_order.external_referance}}",
"externalUrl": "{{return_order.external_url}}",
"returnLabelFileUrl": "{{return_order.return_label_file_url}}",
"returnedOn": "{{return_order.returned_on}}",
"returnOrderProducts": [{{return_order_products}}]
}
}
Subscription acceptance check
If you are using manual activation, you can use these events to track the status of acceptance checks. Please refer to this guide for setting up manual activation and acceptance checks.
If you are using duplication , or Focum acceptance check with "As part of the signup on submitting the signup form " option, the acceptance check will be created and validated during sign up. This corresponds to createSubscriptionFromCart
call.
For other types of acceptance checks, namely Manual , Identity Verification or Focum acceptance check with "As part of the signup on submitting the signup form." option, the acceptance check will be created after customer completes the payment with pending status.
You can use these variables in your templates for all subscription acceptance check events.
Subscription acceptance check created
This event is triggered when an acceptance check is created for a subscription.
Example template
Copy {%- capture acceptance_checks_string -%}
{%- for check in subscription.subscription_acceptance_checks -%}
{"name": "{{check.name}}", "id":"{{check.id}}","status": "{{check.status}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign acceptance_checks = acceptance_checks_string | split: ';' | join: "," %}
{
"event": "subscription_acceptance_check_created",
"subscription_acceptance_checks": [{{acceptance_checks}}],
"subscription": {
"id": "{{subscription.id}}"
}
}
Subscription acceptance check pending
This event is triggered when an acceptance check is created with pending status. It will only be triggered for these acceptance check types: Manual , Identity Verification , Focum acceptance check with "As part of the signup on submitting the signup form."
Example template
Copy {%- capture acceptance_checks_string -%}
{%- for check in subscription.subscription_acceptance_checks -%}
{"name": "{{check.name}}", "id":"{{check.id}}","status": "{{check.status}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign acceptance_checks = acceptance_checks_string | split: ';' | join: "," %}
{
"event": "subscription_acceptance_check_pending",
"subscription_acceptance_checks": [{{acceptance_checks}}],
"subscription": {
"id": "{{subscription.id}}"
}
}
Subscription acceptance check accepted
This event is triggered when the status of an acceptance check changes to accepted .
This will happen immediately on signup if the check passes when its created for these events: duplication , or Focum acceptance check with "As part of the signup on submitting the signup form " option. For other acceptance check types it will happen when the value is set to accepted .
Example template
Copy {%- capture acceptance_checks_string -%}
{%- for check in subscription.subscription_acceptance_checks -%}
{"name": "{{check.name}}", "id":"{{check.id}}","status": "{{check.status}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign acceptance_checks = acceptance_checks_string | split: ';' | join: "," %}
{
"event": "subscription_acceptance_check_accepted",
"subscription_acceptance_checks": [{{acceptance_checks}}],
"subscription": {
"id": "{{subscription.id}}"
}
}
Subscription acceptance check rejected
This event is triggered when the status of an acceptance check changes to rejected .
The triggering timeline is similar to Subscription acceptance check accepted . The only difference is that it occurs when the checks fail or when it is manually set to rejected .
Example template
Copy {%- capture acceptance_checks_string -%}
{%- for check in subscription.subscription_acceptance_checks -%}
{"name": "{{check.name}}", "id":"{{check.id}}","status": "{{check.status}}"};
{%- endfor -%}
{%- endcapture -%}
{% assign acceptance_checks = acceptance_checks_string | split: ';' | join: "," %}
{
"event": "subscription_acceptance_check_rejected",
"subscription_acceptance_checks": [{{acceptance_checks}}],
"subscription": {
"id": "{{subscription.id}}"
}
}
Subscription
You can use these variables in your templates for all subscription events.
Subscription activated
This event is triggered when a subscription is activated. Depending on your project settings this could happen either after successful initial payment or when the subscription is manually activated.
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0 }}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split: ';' | join: "," %}
{
"event": "subscription_activated",
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}
Subscription Stopped
This event is triggered when a subscription is stopped. This happens automatically when the maximum commitment of a subscription is reached.
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0}}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split:';' | join:"," %}
{
"event": "subscription_activated",
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}
Subscription address changed
This event is triggered when subscription details are updated. Note that, updates to subscriptions with draft status won't trigger this event.
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0 }}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split: ';' | join: "," %}
{
"event": "subscription_address_changed",
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}
Subscription cancellation confirmation
This event triggers when a subscription is actually cancelled. If you enabled two step cancellation on your project, this corresponds to when you confirm cancellation through firmhoues portal. To learn more about two step cancellation, please refer to this guide .
If two step cancellation is disabled, it will be directly triggered after Subscription cancellation initiation event
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0 }}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split: ';' | join: "," %}
{
"event": "subscription_cancellation_confirmation",
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}
Subscription cancellation initiation
This event is triggered when a cancellation request is submitted.
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0 }}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split: ';' | join: "," %}
{
"event": "subscription_cancellation_initiation",
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}
Subscription signed up
This event is triggered when customer signs up. This corresponds to customer completing the initial payment successfully.
Example Template
Copy {%- capture subscription_ordered_products_string -%}
{%- for op in subscription.ordered_products -%}
{
"id": "{{op.id}}",
"quantity": {{op.quantity}},
"productId": "{{op.product.id}}",
"price": "{{op.product.price_cents | default: 0 }}",
"sku": "{{op.product.sku}}"
};
{%- endfor -%}
{%- endcapture -%}
{% assign subscription_ordered_products = subscription_ordered_products_string | split: ';' | join: "," %}
{
"event": "subscription_signed_up",
"subscription": {
"id": "{{subscription.id}}",
"email": "{{subscription.email}}",
"name": "{{subscription.name}}",
"lastName": "{{subscription.last_name}}",
"phoneNumber": "{{subscription.phone_number}}",
"address": "{{subscription.address}}",
"houseNumber": "{{subscription.house_number}}",
"city": "{{subscription.city}}",
"state": "{{subscription.state}}",
"zipcode": "{{subscription.zipcode}}",
"country": "{{subscription.country}}",
"paymentMethod": "{{subscription.payment_method}}",
"currency": "{{subscription.currency}}",
"monthlyAmountCents": "{{subscription.monthly_amount_cents}}",
"orderedProducts": [{{subscription_ordered_products}}],
"activePlan": {
"id": "{{subscription.active_plan.id}}",
"name": "{{subscription.active_plan.name}}"
}
}
}