Creating a Simple Webhook
Configure a Webhook
Login to secure.ultracart.com and navigate to Home → Configuration → Development → Webhooks.
Click the New Webhook button.
Enter the Target URL. This is the full, absolute URL of your server. For this example, we entered https://www.myserver.com:9999/order_webhook.php
API Version: Leave this at Latest Version if possible. If your webhook is mission critical, then specify a version to avoid changes.
Authentication Type: For this example, we used no Authentication. You may configure Basic authentication if desired.
Event Subscription: Select which events to receive for this webhook.
Auto Order
Chargeback
Checkout
Customer
Fulfillment
Item
Order
For a clean implementation, you may wish to only receive one event per webhook. Your application will likely do something different for most events and having them separate will provide clarity. For this example, we selected all the events.
Add the expansion you need. The expansion is a csv list of which order parts you desire. For event_ship, you may only need the shipping part of an order. This reduces payload size considerably. The list of expansions are here: https://www.ultracart.com/api/#resource_order.html (you'll need to click on the Expansion link under the Order section in the left hand navigation).
For this example, we added the kitchen sink.
affiliate,affiliate.ledger,auto_order,billing,channel_partner,checkout,coupon,customer_profile,digital_order,edi,fraud_score,gift,gift_certificate,internal,item,linked_shipment,marketing,payment,payment.transaction,quote,salesforce,shipping,summary,taxes
Message Payload: Configure Max Size and Max Events / Payload
Click the Save button
After saving, edit the webhook and add any expansions needed. See http://www.ultracart.com/api/ for expansion lists.
List of Webhooks
Event | Description | Response | Expansion |
|---|---|---|---|
order_create | Fired when an order is created. | Order | Yes |
order_update | Fired when an order is updated. | Order | Yes |
order_delete | Fired when an order is deleted. | Order | Yes |
order_stage_change | Fired when an order stage changes. | Order | Yes |
order_payment_failed | Fired when a payment fails. | Order | Yes |
order_payment_process | Fired when a payment is processed. | Order | Yes |
order_ship | Fired when an order is shipped. | Order | Yes |
order_ship_expected | Fired when an order has an expected delivery date. | Order | Yes |
order_ship_out_for_delivery | Fired when an order is out for delivery. | Order | Yes |
order_ship_delivered | Fired when an order is delivered. | Order | Yes |
order_reject | Fired when an order is rejected. | Order | Yes |
order_refund | Fired when an order is refunded. | Order | Yes |
order_s3_invoice | Fired when an order has a PDF invoice archived to S3. | Order | Yes |
Webhook Expansions
Webhooks have expansions! They are only visible after you create the webhook. Once you create your webhook, edit it and add expansions to your events to ensure you get all the data you need.
Additional Step for Fulfillment Webhooks
The fulfillment webhooks are built on top of the distribution center infrastructure. So fulfillment webhooks will not fire like other webhooks. When an order is placed, order_create may fire nearly immediately, but the fulfillment_transmit may fire 5 minutes later when the distribution center polling routine starts up. The distribution center transmitters may also have custom frequencies. If a distribution center is configured to only transmit once a day, there may be significant lag between an order entering shipping and a fulfillment_transmit event firing.
Fulfillment webhooks are designed to fire for a specific distribution center. The webhook must be connected to the distribution center. Here are the steps:
After fully creating your webhook using the steps above, navigate to the Distribution Centers.
Home → Configuration → Checkout → Shipping → Distribution Centers (4th tab on Shipping screen)
Shortcut link: https://secure.ultracart.com/merchant/configuration/shipping/distributionCenterListLoad.do
Find the target distribution center and click the edit button.
Click on the
Transmission Mechanismtab when the distribution center loads.Scroll down until you find the mechanism named
REST. Select that mechanism.Select the API User and then the webhook.
Save your changes.
Webhook Script Examples
The webhook will receive a JSON payload as a POST body. The structure of the payload is an array of simple objects with key = event_name and value = object.
Test your Webhook
Once your webhook script is deployed, test out your webhook by clicking the test button on the configuration screen. All webhooks have detailed logging accessible via the log button.
Sample JSON Payload
This webhook contains an order_create event. Note that all payloads are arrays of events, even those containing a single event.
Sample JSON of a webhook payload consisting of a single order
[
{"order_create":
{
"merchant_id": "DEMO",
"order_id": "DEMO-0009103373",
"current_stage": "Shipping Department",
"creation_dts": "2016-04-07T14:07:36-04:00",
"language_iso_code": "ENG",
"billing": {
"first_name": "Test",
"last_name": "Order",
"address1": "Test Street",
"city": "ELK GROVE",
"state_region": "CA",
"postal_code": "95758",
"country_code": "US",
"email": "adam@kontor.hu"
},
"shipping": {
"weight": {
"value": 5,
"uom": "LB"
},
"shipping_method": "USPS: Priority Mail",
"first_name": "Test",
"last_name": "Order",
"address1": "Test Street",
"city": "ELK GROVE",
"state_region": "CA",
"postal_code": "95758",
"country_code": "US",
"ship_to_residential": true,
"day_phone": "(234) 234-2342",
"tracking_numbers": [
""
],
"lift_gate": false
},
"taxes": {
"tax_rate": 0.08000,
"tax_rate_state": 0.07250,
"tax_rate_city": 0.00750
},
"payment": {
"payment_method": "Credit Card",
"payment_status": "Processed",
"test_order": true,
"hold_for_fraud_review": false,
"credit_card": {
"card_type": "VISA",
"card_number": "1111",
"card_number_truncated": true,
"card_expiration_month": 12,
"card_expiration_year": 2018,
"card_auth_ticket": "TEST"
},
"payment_dts": "2016-04-07T14:07:36-04:00",
"transactions": [
{
"transaction_gateway": "WorldPay Business Gateway",
"transaction_timestamp": "2016-04-07T14:07:36-04:00",
"details": [
{
"name": "Authorization Code",
"value": "TEST",
"type": "AuthTicket"
},
{
"name": "Test Transaction",
"value": "Yes"
}
],
"successful": true
}
]
},
"summary": {
"shipping_handling_total": {
"value": 2.96,
"localized": 2.96,
"localized_formatted": "$2.96"
},
"subtotal": {
"value": 20.00,
"localized": 20.00,
"localized_formatted": "$20.00"
},
"tax": {
"value": 1.60,
"localized": 1.60,
"localized_formatted": "$1.60"
},
"total": {
"value": 24.56,
"localized": 24.56,
"localized_formatted": "$24.56"
},
"shipping_handling_total_discount": {
"value": 0.00,
"localized": 0.00,
"localized_formatted": "$0.00"
},
"subtotal_discount": {
"value": 0.00,
"localized": 0.00,
"localized_formatted": "$0.00"
},
"taxable_subtotal_discount": {
"value": 0.00,
"localized": 0.00,
"localized_formatted": "$0.00"
},
"taxable_subtotal": {
"value": 20.00,
"localized": 20.00,
"localized_formatted": "$20.00"
}
},
"internal": {
"exported_to_accounting": true
},
"marketing": {
"mailing_list": true
},
"items": [
{
"merchant_item_id": "Bone",
"quantity": 1,
"description": "TJ\u0027s DOGGIE BONES (5 lbs.)\nCode: JQXZPZWBFQ",
"cost": {
"value": 20.00,
"localized": 20.00,
"localized_formatted": "$20.00"
},
"weight": {
"value": 2.26796,
"uom": "KG"
},
"tax_free": false,
"special_product_type": "",
"free_shipping": false,
"discount": {
"value": 0,
"localized": 0.00,
"localized_formatted": "$0.00"
},
"item_reference_oid": 50786363,
"accounting_code": "Bone",
"length": {
"value": 0.394,
"uom": "IN"
},
"height": {
"value": 0.394,
"uom": "IN"
},
"width": {
"value": 0.394,
"uom": "IN"
},
"no_shipping_discount": false,
"ship_separately": false,
"distribution_center_code": "DFLT",
"hazmat": false,
"kit": false,
"kit_component": false,
"upsell": false,
"exclude_coupon": false,
"unit_cost_with_discount": {
"value": 20.00,
"localized": 20.00,
"localized_formatted": "$20.00"
},
"total_cost_with_discount": {
"value": 20.00,
"localized": 20.00,
"localized_formatted": "$20.00"
},
"cogs": 3.0000,
"barcode": "078742226583",
"country_code_of_origin": "US"
}
],
"customer_profile": {
"customer_profile_oid": 1971831,
"email": "adam@kontor.hu",
"track_separately": false,
"tax_exempt": false,
"allow_purchase_order": false,
"auto_approve_purchase_order": false,
"allow_cod": false,
"auto_approve_cod": false,
"free_shipping": false,
"unapproved": false,
"send_signup_notification": false,
"no_realtime_charge": false,
"allow_selection_of_address_type": false,
"exempt_shipping_handling_charge": false,
"no_free_shipping": false,
"allow_3rd_party_billing": false,
"no_coupons": false,
"allow_quote_request": false
},
"checkout": {
"customer_ip_address": "79.121.124.98",
"custom_field7": "Y",
"screen_branding_theme_code": "CSTM",
"upsell_path_code": "DFLT"
},
}
}
]Alternatives to JSON format
If you're interested in extracting a sub-set of the JSON data into a flatter format, I would really encourage you to have a look at our Data Warehouse for BigQuery. You can have all that order information flow into your BigQuery account for next to nothing cost wise. It's incredibly economical. You can then write queries to extract a sub-set of the data into a flat result and save that as a "view". From there you can do:
easy reporting in Google Data Studio / Microsoft Power BI
connect data to Microsoft Excel or Google Sheets
extract querying using the BigQuery CLI or SDK to extract the data set
Frequently Asked Questions
Q: Is there a way to customize our webhook call to apply only to specific storefront?
A: The Event Ruler JSON allows you to specify filtering. Here is an example ruler to filter to a specific StoreFront:
{
"checkout": {
"storefront_host_name": ["store.yourstorefrontURL.com"]
}
}Q: How can we identify Upsell orders via either a Webhook or REST API? We have a webhook setup to get real-time orders from Ultracart, and we would like to know if there is a chance we can determine if that order is an Upsell (1, 2, 3). Either through API or Webhook.)
A: The payload you are receiving is an order object. If the webhook expansion contains 'item', you'll receive the order items.
OrderItem.upsell is a boolean flag that is true if the item was added as part of an upsell. So, you may need iterate the items in order to determine what role upsells played in the order. (*This same property is exposed on orders returned through the rest api.)