PodcastPaymentGateway Interface
Benecaster\Payment\PodcastPaymentGateway
The payment gateway contract that all gateway implementations must satisfy. Core ships StripeGateway (slug benecaster_stripe); the PayPal Gateway add-on ships PayPalGateway (slug benecaster_paypal). Third-party developers implement this interface to add custom payment processors.
Phase 2. All implementing classes are registered with PaymentGatewayRegistry.
Interface Methods
get_gateway_slug(): string
Returns the stable slug identifying this gateway. Used by PaymentGatewayRegistry for routing. Must be unique across all registered gateways. Convention: benecaster_{processor} (e.g., benecaster_stripe, benecaster_paypal).
is_test_mode(): bool (mandatory — PHP fatal if omitted)
Returns whether the gateway is currently operating in test mode. This method is mandatory. A concrete class that omits is_test_mode() raises a PHP fatal at class load — the interface declares it with no default body, which is language-level enforcement.
For StripeGateway, this returns the state of the benecaster_stripe_test_mode option (set by the Test Mode toggle in Settings → Membership → Payments).
The return value of is_test_mode() drives:
- The persistent orange TEST MODE badge on all Benecaster admin screens.
- The “Test Mode — payments are not real” banner on the subscriber account page.
- Benecaster’s staging-vs-live safety checks.
If your gateway’s test mode is controlled by an option, read that option here. If your gateway has no test mode concept, return false.
create_subscription(): \Stripe\Subscription
Creates a new subscription for a subscriber. Receives billing details from NativeBridge::on_subscription_created(). Returns the gateway’s subscription object.
cancel_subscription(): \Stripe\Subscription
Cancels an existing subscription. Default behaviour for StripeGateway: cancel_at_period_end = true so feed access continues to the end of the current billing period. Implement immediate cancellation only if your gateway billing model requires it.
update_payment_method(): void
Updates the payment method on a subscriber’s account. For Stripe, this uses a SetupIntent flow. Called from the subscriber account page when the subscriber clicks “Update payment method.”
get_billing_history(): array
Returns a paginated list of invoices or billing events for a subscriber. Displayed on the subscriber account page. Return an array of objects with at minimum: date, amount, currency, status, invoice_url.
handle_webhook( \Stripe\Event $event ): void
Handles a raw event from the payment provider. For StripeGateway, this fires the appropriate benecaster_stripe_membership_* routing action. Implement this to route your gateway’s webhook events into Benecaster’s subscription lifecycle.
Registering a Custom Gateway
Register your implementation via benecaster_boot:
add_action( 'benecaster_boot', function ( \Benecaster\Container $container ): void {
$container
->make( \Benecaster\Payment\PaymentGatewayRegistry::class )
->register( $container->make( My\CustomGateway::class ) );
} );
class CustomGateway implements \Benecaster\Payment\PodcastPaymentGateway {
public function get_gateway_slug(): string { return 'benecaster_custom'; }
public function is_test_mode(): bool { return (bool) get_option( 'my_gateway_sandbox_mode', false ); }
// ... implement remaining methods
}
Once registered, your gateway appears in the Settings → Membership → Payments gateway selector alongside StripeGateway. The TEST MODE badge lights up if is_test_mode() returns true for the active gateway.
Notes
StripeGatewayis registered automatically by core and is always available when Built-in Membership is active. You cannot deregister it.- The PayPal Gateway add-on registers
PayPalGatewayvia the same pattern. See PayPal Gateway. - Subscription lifecycle methods (
create_subscription,cancel_subscription,update_payment_method,get_billing_history) are stubbed in the Foundation batch and wired in the Lifecycle batch. Custom gateways implementing the full interface before Lifecycle ships will have their methods called once Lifecycle is active.