Drupal is a registered trademark of Dries Buytaert
drupal 10.6.8 Update released for Drupal core (10.6.8)! drupal 11.3.9 Update released for Drupal core (11.3.9)! drupal 11.3.8 Update released for Drupal core (11.3.8)! drupal 11.3.7 Update released for Drupal core (11.3.7)! drupal 11.2.11 Update released for Drupal core (11.2.11)! drupal 10.6.7 Update released for Drupal core (10.6.7)! drupal 10.5.9 Update released for Drupal core (10.5.9)! cms 2.1.1 Update released for Drupal core (2.1.1)! drupal 11.3.6 Update released for Drupal core (11.3.6)! drupal 10.6.6 Update released for Drupal core (10.6.6)! cms 2.1.0 Update released for Drupal core (2.1.0)! linkit 7.0.15 Minor update available for module linkit (7.0.15). views_data_export 8.x-1.10 Minor update available for module views_data_export (8.x-1.10). linkit 7.0.14 Minor update available for module linkit (7.0.14). migrate_tools 6.1.4 Minor update available for module migrate_tools (6.1.4). diff 2.0.0 Major update available for module diff (2.0.0). masquerade 8.x-2.2 Minor update available for module masquerade (8.x-2.2). video_embed_field 3.1.0 Minor update available for module video_embed_field (3.1.0). bootstrap 8.x-3.40 Minor update available for theme bootstrap (8.x-3.40). menu_link_attributes 8.x-1.7 Minor update available for module menu_link_attributes (8.x-1.7).

billing_hub

No security coverage
View on drupal.org
Billing Hub

Gateway-agnostic billing layer for Drupal 10 / 11. Manages subscriptions,
invoices, tax, and dunning. Integrates with Membership Manager for access
control. Supports Stripe, PayPal, Braintree, and custom payment gateways via a Plugin API.

Requirements

  • Drupal 10.2+ or Drupal 11
  • PHP 8.2+
  • drupal:user (core)
  • membership_manager module

Gateway dependencies

# Stripe
composer require stripe/stripe-php

# PayPal
composer require paypal/paypal-server-sdk

Installation

composer require drupal/billing_hub
drush en billing_hub billing_hub_stripe
drush cr

Visit /admin/billing to configure.

Architecture Overview

CheckoutService → BillingManagerService → GatewayPlugin
BillingPortalController → BillingManagerService → SubscriptionService
WebhookController → WebhookDispatcherService → BillingManagerService
DunningService → Queue → DunningQueueWorker → GatewayPlugin::retryInvoice()
TaxService ← BillingPlan + TaxRate
AnalyticsService ← billing_subscription + billing_invoice tables

BillingManagerService is the central entry point.

Billing Plans

Field Description Machine name Used in code Gateway Gateway plugin Price Base price Currency ISO 4217 Interval day / week / month / year Interval count Billing frequency Trial days Trial duration Proration Enable credits Dunning policy cancel / downgrade / suspend Tax mode exclusive / inclusive / none Membership plan Linked membership

Gateway Configuration

Field Description Plugin ID stripe / paypal / braintree Test mode Sandbox mode Settings API keys

Stripe example

secret_key: sk_live_...
publishable_key: pk_live_...
webhook_secret: whsec_...
test_mode: false

Checkout Flow

PHP Example

$checkout = \Drupal::service('billing_hub.checkout');

$preview = $checkout->preview(
  plan_id: 'pro_monthly',
  country_code: 'DE',
  tax_id: 'DE123456789'
);

$result = $checkout->checkout(
  user: $user,
  plan_id: 'pro_monthly'
);

AJAX Preview

fetch('/billing/checkout/pro_monthly/preview', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({ country_code: 'DE' })
});

Subscription Lifecycle

active → canceled
active → paused → active
active → past_due → unpaid
trialing → active

Webhooks

Gateway URL Stripe /billing/webhook/stripe PayPal /billing/webhook/paypal Braintree /billing/webhook/braintree

Dunning

Retry schedule: 0, 1, 3, 7, 14 days

Policy Effect cancel Subscription canceled downgrade Assign fallback plan suspend Keep record

Tax

Modes

Mode Description exclusive Tax added inclusive Tax included none No tax

VAT validation hook

function mymodule_billing_hub_vat_validate(string $vat_number): bool {
  return my_vies_client()->validate($vat_number);
}

Analytics

$analytics = \Drupal::service('billing_hub.analytics');

$analytics->getMRR();
$analytics->getARR();
$analytics->getChurnRate(30);

User Billing Portal

Route Description /billing/portal Overview /billing/portal/invoices Invoices /billing/portal/cancel/{id} Cancel /billing/portal/change-plan/{id} Change plan

Membership Integration

BillingPlan.membership_plan_id → assignMembership()
→ MembershipManagerService::assign()

Custom Gateway

/**
 * @Gateway(
 *   id = "my_gateway",
 *   label = @Translation("My Gateway")
 * )
 */
class MyGateway extends GatewayPluginBase {}

Hooks

Coupon

function mymodule_billing_hub_coupon_validate(string $code): float {
  return 10.0;
}

Redirect

function mymodule_billing_hub_checkout_success_url(...) {
  return '/members/welcome';
}

Maintainers

Dmytro Porokhnya

License

GPL-2.0-or-later

Activity

Total releases
1
First release
Apr 2026
Latest release
1 month ago
Release cadence
Stability
0% stable

Releases

Version Type Release date
1.0.0-alpha1 Pre-release Apr 1, 2026