Drupal is a registered trademark of Dries Buytaert
cms 2.1.0 Update released for Drupal core (2.1.0)! menu_link_attributes 8.x-1.7 Minor update available for module menu_link_attributes (8.x-1.7). ai 1.2.13 Minor update available for module ai (1.2.13). ai 1.3.2 Minor update available for module ai (1.3.2). moderated_content_bulk_publish 2.0.51 Minor update available for module moderated_content_bulk_publish (2.0.51). moderated_content_bulk_publish 2.0.50 Minor update available for module moderated_content_bulk_publish (2.0.50). editoria11y 2.2.21 Minor update available for module editoria11y (2.2.21). eca 3.1.0 Minor update available for module eca (3.1.0). sophron 3.1.1 Minor update available for module sophron (3.1.1). ai 1.3.1 Minor update available for module ai (1.3.1). seven 2.0.0-beta6 New beta version released for theme seven (2.0.0-beta6). seven 1.0.1-beta1 First beta version released for theme seven (1.0.1-beta1). miniorange_saml 3.1.4 Minor update available for module miniorange_saml (3.1.4). eca_tamper 2.0.10 Minor update available for module eca_tamper (2.0.10). modeler_api 1.1.1 Minor update available for module modeler_api (1.1.1). turnstile 1.1.26 Minor update available for module turnstile (1.1.26). email_tfa 2.0.8 Minor update available for module email_tfa (2.0.8). paragraphs_entity_embed 4.0.0 Major update available for module paragraphs_entity_embed (4.0.0). bootstrap_italia 2.17.4 Minor update available for theme bootstrap_italia (2.17.4). bootstrap_italia 2.17.6 Minor update available for theme bootstrap_italia (2.17.6).

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
21 hours ago
Release cadence
Stability
0% stable

Releases

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