Server-to-Server Webhooks

This guide describes how to add and configure custom server-to-server webhook.

Server-to-server webhooks is a premium feature and available on Launch and Grow plans.

Apphud's webhook system for subscriptions allows you to catch the moment when subscription event occurs. You can use this data to implement custom logic or analytics on your own server. You simply need to specify a URL for POST-request.

Webhooks are being sent as POST request to specified URL.

How to Add Webhook?

Step 1
2
3
4
5
6
7
✅ 8
Step 1
2

At Apphud go to "Integrations" section and add Custom webhook:

3

Enter webhook name and specify webhook URL. Events will be sent to this URL using POST-request:

4

You may optionally specify Secret token that will be sent with the webhook request in the X-Apphud-Token HTTP header. Use this token to validate received payloads.

5

Choose which between Production and Sandbox events to be sent via webhook:

6

Enable events on which you would like to receive webhook:

7

Enable integration:

✅ 8

Save changes:

Apphud sends only one request per webhook without retries.

Webhook Structure

The POST body for all webhooks follows the same structure:

{
"app": {},
"event": {},
"user": {}
}

Let's look through each component of this structure.

App

This dictionary contains information about the app.

Field

Type

Description

app.uid

String

Apphud app ID.

app.bundle_id

String

iOS Bundle ID.

app.package_name

String

Android Package Name.

Event

This dictionary contains information about event.

Field

Type

Description

Possible values

event.id

String

Apphud event ID.

event.created_at

Date

Date when this event was created by Apphud.

event.name

String

Event name.

e.g. "trial_started"

event.properties

Dictionary

Dictionary containing event properties. View description below.

event.receipt

Dictionary

Apphud receipt information related to the event. View description below.

event.properties

event.properties may contain fields below.

Field

Type

Description

Possible values

event.properties.product_id

String

Product ID.

event.properties.reason

String

Depending on the event: the reason of an expiration of a subscription or the reason of refund.

user_canceled billing_issue declined_price_increase

unavailable_product

unknown_error

app_issue

another_reason

event.properties.currency

String

Local currency ISO code.

event.properties.usd_price

Float

Price in USD.

event.properties.local_price

Float

Price in local currency.

event.properties.offer_type

String

Introductory or promotional offer payment mode (iOS only).

pay_up_front

pay_as_you_go

trial

event.properties.offer_id

String

Promotional offer ID.

event.properties.unit

String

The increment of time that a subscription period is specified (iOS only).

day

week

month

year

event.properties.units_count

Integer

The number of units per subscription period (iOS only).

event.receipt

event.receipt may contain the fields below.

This is internal Apphud receipt model.

Field

Type

Description

event.receipt.id

String

Apphud receipt ID.

event.receipt.product_id

String

Product ID.

event.receipt.purchased_at

Date

Transaction date.

event.receipt.intro_period

Boolean

Is subscription in introductory period.

event.receipt.trial_period

Boolean

Is subscription in trial period.

event.receipt.transaction_id

String

App Store transaction ID / Google Play Order ID

event.receipt.original_transaction_id

String

App Store original transaction ID / Google Play Purchase Token.

event.receipt.price_usd

Float

Price in USD.

event.receipt.proceeds_usd

Float

Revenue in USD after Apple / Google commission deduction.

event.receipt.price

Float

Price in local currency.

event.receipt.proceeds

Float

Revenue in local currency after Apple / Google commission deduction.

event.receipt.currency

String

Local currency ISO code.

event.receipt.quantity

Integer

Always 1.

event.receipt.apple_share

Float

Apple commission. It can be 0.15 or 0.3.

User

This dictionary contains information about the user.

Field

Type

Description

user.user_id

String

User ID.

user.uid

String

Apphud user ID.

user.paying

Boolean

Is the user currently paying or not.

user.payments_count

Integer

User payments count.

user.total_spent

Float

User total spent in USD.

user.subscriptions[]

Array

Array containing information about all subscriptions of the user. View description below.

user.subscriptions[]

user.subscriptions is an array containing user's subscriptions. Each element of this array is a dictionary with the following structure:

Field

Type

Description

Possible values

user.subscriptions[].id

String

Apphud subscription ID

user.subscriptions[].product_id

String

Product ID

user.subscriptions[].group

String

Group name

user.subscriptions[].status

String

Current status

trial

intro

promo

regular

refunded

expired

user.subscriptions[].intro_period

Boolean

Is subscription in introductory period.

user.subscriptions[].trial_period

Boolean

Is subscription in trial period.

user.subscriptions[].started_at

Date

Subscription start date.

user.subscriptions[].expires_at

Date

Subscription expiration date.

user.subscriptions[].cancelled_at

Date

Subscription cancellation date.

user.subscriptions[].autorenew_enabled

Boolean

Is autorenew enabled for the subscription.

user.subscriptions[].in_retry_billing

Boolean

Is subscription in retry billing period.

user.subscriptions[].introductory_activated

Boolean

Is intro (including trial) was user by the user.

user.subscriptions[].environment

String

Subscription environment

sandbox

production

user.subscriptions[].original_transaction_id

String

App Store original transaction ID / Google Play Purchase Token

Webhooks Examples

Subscription Renewed
Subscription Expired
Subscription Renewed
{
"app": {
"uid": "e0ce9fc3",
"bundle_id": "com.apphud.testapp",
"package_name" : "com.apphud.testapp"
},
"event": {
"id": "2c2cba55-c41e-4ef8-81a7-7c11b3715502",
"receipt": {
"id": "13f4134c-c123-42d8-aadb-b3c97bb72e3d",
"intro_period": false,
"price_usd": 4.35,
"purchased_at": "2020-01-21 11:51:33 UTC",
"transaction_id": "1000000617611104",
"original_transaction_id": "1000000615808360",
"trial_period": false,
"price": 269,
"quantity": 1,
"apple_share": 0.3,
"proceeds_usd": 3.0449999999999995,
"proceeds": 188.29999999999998,
"product_id": "BronzeMonthly",
"currency": "RUB"
},
"created_at": "2020-01-21 11:51:33 UTC",
"properties": {
"usd_price": 4.35,
"local_price": 269,
"product_id": "BronzeMonthly",
"currency": "RUB"
},
"name": "subscription_renewed"
},
"user": {
"user_id": "user_10",
"total_spent": 0,
"payments_count": 0,
"uid": "ce4aac3d",
"paying": false,
"subscriptions": [
{
"id": "e89c975d-aa18-4661-8a25-8e4a67c038de",
"status": "regular",
"environment": "sandbox",
"original_transaction_id": "1000000615808360",
"expires_at": "2020-01-21 11:41:17 UTC",
"cancelled_at": null,
"started_at": "2020-01-16 11:58:39 UTC",
"autorenew_enabled": false,
"in_retry_billing": false,
"introductory_activated": true,
"group": "Bronze",
"product_id": "BronzeMonthly",
"intro_period": false,
"trial_period": false
},
{
"id": "da27352b-2e25-48c1-8812-e8001e691d1f",
"status": "expired",
"environment": "sandbox",
"original_transaction_id": "1000000616814874",
"expires_at": "2020-01-19 15:55:19 UTC",
"cancelled_at": null,
"started_at": "2020-01-19 14:55:20 UTC",
"autorenew_enabled": false,
"in_retry_billing": false,
"introductory_activated": false,
"group": "Gold",
"product_id": "Gold2Months",
"intro_period": false,
"trial_period": false
}
]
}
}
Subscription Expired
{
"app": {
"uid": "e0ce9fc3",
"bundle_id": "com.apphud.testapp"
},
"event": {
"id": "8e8544c6-bd5c-4f6a-a039-cc7639b65ae5",
"created_at": "2020-01-21 11:56:31 UTC",
"properties": {
"product_id": "BronzeMonthly",
"reason": "user_canceled"
},
"name": "subscription_expired"
},
"user": {
"user_id": "user_10",
"total_spent": 0,
"payments_count": 0,
"uid": "ce4aac3d",
"paying": false,
"subscriptions": [
{
"id": "e89c975d-aa18-4661-8a25-8e4a67c038de",
"status": "expired",
"environment": "sandbox",
"original_transaction_id": "1000000615808360",
"expires_at": "2020-01-21 11:56:33 UTC",
"cancelled_at": null,
"started_at": "2020-01-16 11:58:39 UTC",
"autorenew_enabled": false,
"in_retry_billing": false,
"introductory_activated": true,
"group": "Bronze",
"product_id": "BronzeMonthly",
"intro_period": false,
"trial_period": false
},
{
"id": "da27352b-2e25-48c1-8812-e8001e691d1f",
"status": "expired",
"environment": "sandbox",
"original_transaction_id": "1000000616814874",
"expires_at": "2020-01-19 15:55:19 UTC",
"cancelled_at": null,
"started_at": "2020-01-19 14:55:20 UTC",
"autorenew_enabled": false,
"in_retry_billing": false,
"introductory_activated": false,
"group": "Gold",
"product_id": "Gold2Months",
"intro_period": false,
"trial_period": false
}
]
}
}

How to Test Webhook

You can test webhooks using any service that may receive HTTP events, for example, RequestBin.com.

Step 1
2
3
✅ 4
Step 1

Open RequestBin.com and click to "Create Request Bin" button.

2

Copy Endpoint URL:

3

Create new Webhook in Apphud using this URL. Make sure you selected "Sandbox" environment while configuring webhook.

✅ 4

Make a test purchase on your device using Sandbox environment. You can read how to do this here. Now whenever webhook is triggered, you will see a full report on RequestBin: