Notifications Webhooks
Events
Subscription
SubscriptionCreated
-
Subscription was created
-
Subscription may still be inactive
-
Subscription may still be in trial mode
SubscriptionActivated
-
Subscription was started (no trial/trial ended)
-
Subscription was continued after pause
-
Subscription was reactivated after cancellation
SubscriptionUpdated
-
Subscription has been changed (addons or charges added/removed, payment method changed, address data changed ...)
SubscriptionPaused
-
Subscription was paused but not cancelled
SubscriptionCancelled
-
Subscription was cancelled
Item-Purchase
ItemPurchased
-
regular item (not a subscription) was purchased
ItemCancelled
-
regular item (not a subscription) was cancelled
Customer
CustomerUpdated
-
a customer changed his email address via customer portal
Delivery
-
Webhooks are sent exclusively via HTTP POST to the stored URL
-
the target server MUST support HTTPS (SSL) and provide a valid certificate
-
insecure URLs for endpoints (http://xxx) are not accepted
-
missing or invalid SSL certificates will trigger a failed attempt of the webhook
-
-
delivery at least once is guaranteed (exception in case of 10 failed delivery attempts, see above "Errors & Retries")
-
the delivery sequence is not guaranteed
Topic-Assignment
-
each webhook contains an
X-Webhook-Topic
-Header
Validation
-
each webhook contains an
X-Webhook-Content-Hash
-Headerthe hash is generated from the payload (JSON-encoded) and the webhook secret assigned to each supplier as a key (HMAC sha256)
Example for validation:
-
// This assumes the received data has been cast to object/array beforehand by the used framework
$calculatedWebhookHash = hash_hmac('sha256', json_encode($receivedWebhookData), $vendorSecret);
$hashesMatch = hash_equals($calculatedWebhookHash, $receivedHashFromHeader);
// TRUE if calculated hash and hash received in X-Webhook-Content-Hash header match,
// FALSE otherwise
// If hashes do not match, the Webhook MUST be discarded
Errors & Retries
-
if the receiving server does not respond within 5 seconds with a 200 status code, the send is considered failed
-
failed webhooks are resent up to 10 times, with each attempt increasing the time interval until the next one is sent
-
after 5 attempts, the supplier will receive an email notification with a warning that a webhook could not be delivered yet
-
-
after 10 failed attempts (approx. 3 days after initial sending) the webhook is considered as finally failed and will not be sent again
-
the supplier is informed about the undeliverable webhook via e-mail
-
Versioning
-
Webhooks are versioned via
X-Webhook-Version
-Header -
Suppliers may choose the version they prefer
-
if an outdated version is used, an
X-Webhook-Version-Deprecated
header is sent along with it -
obsolete versions are not supported indefinitely (Timeline TBD)
-
several warnings are sent via e-mail before shutdown and a fixed date of shutdown is given
-
Payloads [v1]
Subscription-Events
{
"order_id":"foo_order123",
"payment_status":"paid",
"contract_number":"23-1002243",
"subscription":{
"id":"foobar123",
"status":"active",
"billing_period":1,
"billing_period_unit":"month"
},
"plan":{
"sku":"foo_subscription",
"unique_id":"9893f0a0-2e90-4b73-9b3c-3f501f1a2d0c",
"quantity":8,
"price":"150.00",
"total":"1050.00",
"discount":"10.00",
"taxes":[
{
"name":"VAT",
"rate":19,
"amount":"177.84"
}
],
"free_quantity":1,
"currency":"EUR"
},
"addons":[
],
"parts_list_items":[
{
"0":"SP-00015",
"1":"SP-00136",
"..."
}
],
"previous_contract":{
"number":"23-000012"
},
"discount_codes":[
"foo_discount_10"
],
"customer":{
"id":"foo_customer123",
"unique_id":"9893f0a0-2e90-4b73-9b3c-3f501f1a2d0c",
"first_name":"Foo",
"last_name":"Bar",
"email":"foo@bar.baz",
"phone":null,
"vat_id":null,
"billing_address":{
"company":null,
"first_name":"Foo",
"last_name":"Bar",
"email":"foo@bar.baz",
"phone":null,
"street":"Foostreet 123",
"address_addition":null,
"zip_code":"12345",
"city":"Foocity",
"country":"DE"
},
"delivery_address":{
"company":null,
"first_name":"Foo",
"last_name":"Bar",
"email":"foo@bar.baz",
"phone":null,
"street":"Foostreet 123",
"address_addition":null,
"zip_code":"12345",
"city":"Foocity",
"country":"DE"
}
}
}
Item-Purchased-Events
{
"order_id":"foo_order123",
"contract_number":"23-1002243",
"payment_status":"paid",
"item":{
"sku":"foo_item",
"unique_id":"9893f0a0-2e90-4b73-9b3c-3f501f1a2d0c",
"quantity":8,
"price":"150.00",
"total":"1050.00",
"discount":"10.00",
"taxes":[
{
"name":"VAT",
"rate":19,
"amount":"177.84"
}
],
"free_quantity":1,
"currency":"EUR"
},
"addons":[
],
"parts_list_items":[
],
"previous_contract":[
],
"discount_codes":[
"foo_discount_10"
],
"customer":{
"id":"foo_customer123",
"unique_id":"9893f0a0-2e90-4b73-9b3c-3f501f1a2d0c",
"first_name":"Foo",
"last_name":"Bar",
"email":"foo@bar.baz",
"phone":null,
"vat_id":null,
"billing_address":{
"company":null,
"first_name":"Foo",
"last_name":"Bar",
"email":"foo@bar.baz",
"phone":null,
"street":"Foostreet 123",
"address_addition":null,
"zip_code":"12345",
"city":"Foocity",
"country":"DE"
},
"delivery_address":{
"company":null,
"first_name":"Foo",
"last_name":"Bar",
"email":"foo@bar.baz",
"phone":null,
"street":"Foostreet 123",
"address_addition":null,
"zip_code":"12345",
"city":"Foocity",
"country":"DE"
}
}
}
Customer-Events
{
"customer_id":"9aa8b48a-c4d5-48a8-b230-5e9b0bfd5b05",
"customer_name":"name",
"customer_old_email":"old-mail@customer.de",
"customer_email":"new-mail@customer.de"
}
Notifications Email
Example
A Subscription has been activated.
Order ID: xxxxxxxx-1234-5678-90xx-xxxxxxxxxxxx Payment Status: paid
Subscription Details:
-
ID: xxxxxxxx-1234-5678-xxxx-xxxxxxxxxxxx
-
Status: active
-
Billing Period: 1
-
Billing Period Unit: month
Plan details:
-
SKU: vendor-sku
-
Quantity: 1
-
Price: 49.00
-
Total: 49.00
-
Discount: 0.00
-
Taxes:
-
Name: DE Umsatzsteuer
-
Rate: 19
-
Amount: 9.31
-
-
Free Quantity: 0
-
Currency: EUR
Addons: Discount Codes:
Previous contract:
-
Number:
Customer Details:
-
Id: email|0123456789xx0123456789
-
Email: customer@domain.tld
-
Phone:
-
Vat Id:
-
Last Name: Doe
-
First Name: John
Billing Address:
-
City: Berlin
-
Email: customer@domain.tld
-
Phone:
-
Street: Berliner Straße 123
-
Company: Company GmbH
-
Country: DE
-
Zip Code: 12345
-
Last Name: Doe
-
First Name: John
-
Address Addition:
Delivery Address:
-
City: Berlin
-
Email: customer@domain.tld
-
Phone:
-
Street: Berliner Straße 123
-
Company: Company GmbH
-
Country: DE
-
Zip Code: 12345
-
Last Name: Doe
-
First Name: John
-
Address Addition: