Search documentation

Search across BlockBee docs, API endpoints, webhooks and guides.

Subscriptions Webhook

View as Markdown

Overview

BlockBee sends webhooks to notify your application about subscription events. There are two types of webhook notifications:

  1. Payment Notification (action=renew) - Sent when a user makes a payment to extend or create a subscription
  2. Expiration Notification (action=expired) - Sent when a subscription reaches its end date

Payment Notification Webhook

Sent when a user makes a payment (initial subscription payment or renewal).

Webhook Fields

actionstring•Required

Action performed: renew if user made a payment, either the initial one or the extension.

Notes:

  • Important to check the subscription_end_date_ts as it will be updated with the current subscription end date.
Example:renew

subscription_idstring•Required

Unique token of the subscription.

Example:I55hhRINHptLJPwsqwYNxJOKBItRiq1o

subscription_urlstring•Required

Link to the subscription page.

Example:https://pay.blockbee.io/subscription/I55hhRINHptLJPwsqwYNxJOKBItRiq1o

subscription_start_date_tsinteger•Required

Timestamp when the subscription started.

Example:1718131200

subscription_end_date_tsinteger•Required

Timestamp when the subscription will expire.

Example:1720723200

subscription_option_slugstring•Required

Slug of the subscription option selected by the user.

Example:pro-plan

subscription_option_duration_tsnumber•Required

Duration of the subscription option selected by the user, in seconds.

Example:2592000

subscription_option_valuenumber•Required

Value of the subscription option in fiat you selected in the Payment Settings.

Example:5

subscription_user_idstring•Required

User identifier of your system provided in the here.

Example:user_123

subscription_user_emailstring•Required

Email address of the user, provided here.

payment_urlstring•Required

Payment link associated with this subscription renewal.

Example:https://pay.blockbee.io/subscription/payment/ls25hhRINHptLJPwsqwYNxJOKBItRiq1o

payment_redirect_urlstring•Required

URL where the user will be redirected after payment.

Example:https://example.com/payment-successful

payment_valuenumber•Required

Value expected to be paid in fiat.

Example:5

payment_success_tokenstring•Required

Success token used to validate the payment.

Example:sU7EGOlRRxsxJu4zZoYLa69UXrSijzb73eP6nbQQgpJYAfSL3NiI407lpYqsMbR2

payment_currencystring•Required

Currency code (e.g. usd, eur).

Example:usd

payment_is_paidinteger•Required

Whether the payment is completed (1) or not (0).

Example:1

payment_paid_amountnumber•Required

Amount paid in crypto.

Example:5

payment_paid_amount_fiatnumber•Required

Amount paid in fiat.

Example:4.85

payment_received_amountnumber•Required

Amount received after fee deductions in crypto.

Example:5

payment_received_amount_fiatnumber•Required

Amount received after fee deductions in fiat.

Example:4.85

payment_paid_coinstring•Required

Coin used for payment (e.g. btc, trc20_usdt, etc...).

Example:btc

payment_exchange_ratenumber•Required

Exchange rate at the time of payment.

Example:0.97

payment_txidstring•Required

Comma-separated transaction IDs of the payment.

Example:0xa1234...,0xa5678...

payment_addressstring•Required

Blockchain address that received the payment.

Example:0xabc123...

payment_typestring•Required

Always payment for subscription renewals.

Example:payment

payment_statusstring•Required

Payment status string.

Example:done

Example Payload

JSON
{
  "action": "renew",
  "subscription_id": "I55hhRINHptLJPwsqwYNxJOKBItRiq1o",
  "subscription_url": "https://pay.blockbee.io/subscription/I55hhRINHptLJPwsqwYNxJOKBItRiq1o",
  "subscription_start_date_ts": 1718131200,
  "subscription_end_date_ts": 1720723200,
  "subscription_option_slug": "pro-plan",
  "subscription_option_duration_ts": 2592000,
  "subscription_option_value": 5,
  "subscription_user_id": "user_123",
  "subscription_user_email": "[email protected]",
  "payment_url": "https://pay.blockbee.io/subscription/payment/ls25hhRINHptLJPwsqwYNxJOKBItRiq1o",
  "payment_redirect_url": "https://example.com/payment-successful",
  "payment_value": 5,
  "payment_success_token": "sU7EGOlRRxsxJu4zZoYLa69UXrSijzb73eP6nbQQgpJYAfSL3NiI407lpYqsMbR2",
  "payment_currency": "usd",
  "payment_is_paid": 1,
  "payment_paid_amount": 5,
  "payment_paid_amount_fiat": 4.85,
  "payment_received_amount": 5,
  "payment_received_amount_fiat": 4.85,
  "payment_paid_coin": "btc",
  "payment_exchange_rate": 0.97,
  "payment_txid": "0xa1234...,0xa5678...",
  "payment_address": "0xabc123...",
  "payment_type": "payment",
  "payment_status": "done"
}

Expiration Notification Webhook

Sent when a subscription has reached its end date and is no longer active.

Webhook Fields

actionstring•Required

Indicates that the subscription has reached its end date and is no longer active. No further payments will be processed for expired subscriptions.

Example:expired

subscription_idstring•Required

Unique token of the subscription.

Example:I55hhRINHptLJPwsqwYNxJOKBItRiq1o

subscription_urlstring•Required

Link to the subscription page.

Example:https://pay.blockbee.io/subscription/I55hhRINHptLJPwsqwYNxJOKBItRiq1o

subscription_start_date_tsinteger•Required

Timestamp when the subscription started.

Example:1718131200

subscription_end_date_tsinteger•Required

Timestamp when the subscription will expire.

Example:1720723200

subscription_option_slugstring•Required

Slug of the subscription option selected by the user.

Example:pro-plan

subscription_option_duration_tsnumber•Required

Duration of the subscription option selected by the user, in seconds.

Example:2592000

subscription_option_valuenumber•Required

Value of the subscription option in fiat you selected in the Payment Settings.

Example:5

subscription_user_idstring•Required

User identifier of your system provided in the here.

Example:user_123

subscription_user_emailstring•Required

Email address of the user, provided here.

Example Payload

JSON
{
  "action": "expired",
  "subscription_id": "I55hhRINHptLJPwsqwYNxJOKBItRiq1o",
  "subscription_url": "https://pay.blockbee.io/subscription/I55hhRINHptLJPwsqwYNxJOKBItRiq1o",
  "subscription_start_date_ts": 1718131200,
  "subscription_end_date_ts": 1720723200,
  "subscription_option_slug": "pro-plan",
  "subscription_option_duration_ts": 2592000,
  "subscription_option_value": 5,
  "subscription_user_id": "user_123",
  "subscription_user_email": "[email protected]"
}

Webhook Handling

Here are code examples for handling subscription webhooks in different programming languages:

// Express.js webhook handler
app.post('/subscription-webhook', express.json(), (req, res) => {
  // 1. Verify the webhook signature
  if (!verifyWebhookSignature(req)) {
    return res.status(401).send('Unauthorized');
  }

  const { action, subscription_id, subscription_user_id, payment_status } = req.body;

  // Use subscription_id to prevent duplicate processing
  if (isWebhookAlreadyProcessed(subscription_id)) {
    return res.status(200).send('*ok*');
  }

  if (action === 'renew' && payment_status === 'done') {
    // Grant or extend access for the user
    // Update subscription end date in your database
    // Send confirmation email to user
    console.log(`Subscription renewed for user: ${subscription_user_id}`);
  } else if (action === 'expired') {
    // Revoke access for the user
    // Update subscription status in your database
    // Send expiration notification to user
    console.log(`Subscription expired for user: ${subscription_user_id}`);
  }

  // Mark this webhook as processed
  markWebhookAsProcessed(subscription_id);

  // Always respond with *ok*
  res.status(200).send('*ok*');
});

Best Practices

  • Verify Signatures: Always verify webhook signatures to ensure requests are from BlockBee
  • Idempotency: Use the subscription_id to prevent processing the same webhook multiple times
  • Respond Quickly: Always respond with *ok* and a 200 status code to prevent BlockBee from resending the webhook
  • Asynchronous Processing: For long-running tasks, process them in a background job after responding to the webhook
  • Error Handling: Log errors but don't let them prevent the webhook response
  • Database Updates: Update your database with the new subscription end date when processing renewal webhooks

Webhook Verification

Always verify that webhooks are coming from BlockBee by checking the signature. This prevents malicious requests from impersonating BlockBee.

For implementation details, see our Verify Webhook Signature guide.