Skip to main content

SubscriptionBillingService

Struct SubscriptionBillingService 

Source
pub struct SubscriptionBillingService { /* private fields */ }
Expand description

High-level provider-neutral billing facade for authorized host commands.

The service owns orchestration and retry classification. Hosts retain authentication, authorization, offer rows, credentials, abuse admission, and the transaction/outbox boundary supplied at construction.

Implementations§

Source§

impl SubscriptionBillingService

Source

pub async fn enroll( &self, command: EnrollSubscription, ) -> Result<SubscriptionEnrollmentPaymentResult, SubscriptionBillingServiceError>

Runs one complete initial-subscription payment boundary.

Matching replay and conflict are resolved before host admission. No database transaction or lock is held across host admission, gateway resolution, readiness I/O, or the one provider mutation.

Source§

impl SubscriptionBillingService

Source

pub async fn charge_host_target( &self, command: ChargeHostTarget, ) -> Result<HostChargePaymentResult, SubscriptionBillingServiceError>

Charges one host-owned target through the canonical attempt ledger.

Target eligibility and economics are supplied by the configured host extension. No transaction or target lock spans gateway I/O.

Source

pub async fn apply_reconciled_host_charge_outcome( &self, billing_scope_id: BillingScopeId, attempt_id: PaymentAttemptId, outcome: &GatewayPaymentOutcome, ) -> Result<HostChargePaymentResult, SubscriptionBillingServiceError>

Applies an exact-query outcome to one host charge without resubmission.

Source§

impl SubscriptionBillingService

Source

pub async fn replace_payment_method( &self, command: ReplaceSubscriptionPaymentMethod, ) -> Result<SubscriptionEnrollmentPaymentResult, SubscriptionBillingServiceError>

Runs one complete stored payment-method replacement boundary.

Source§

impl SubscriptionBillingService

Source

pub async fn apply_reconciled_outcome( &self, billing_scope_id: BillingScopeId, attempt_id: PaymentAttemptId, outcome: &GatewayPaymentOutcome, ) -> Result<SubscriptionEnrollmentPaymentResult, SubscriptionBillingServiceError>

Applies an already-observed provider outcome without another submission.

Reconciliation enters the same application authority as foreground enrollment but reconstructs its secret-free reservation from the exact durable attempt and canonical gateway account.

Source§

impl SubscriptionBillingService

Source

pub async fn recover( &self, command: RecoverSubscriptionPayment, ) -> Result<SubscriptionEnrollmentPaymentResult, SubscriptionBillingServiceError>

Runs one complete subscriber-initiated recovery payment boundary.

The command carries only the owner, requested plan/configuration, and memory-only token/contact. Reservation derives the exact due period, amount, subscription, and payment-state snapshot under lock.

Source§

impl SubscriptionBillingService

Source

pub async fn renew( &self, command: ChargeRenewal, ) -> Result<SubscriptionRenewalOutcome, SubscriptionBillingServiceError>

Runs one complete automatic recurring-renewal boundary.

Stale, future, canceled, paced, and contended work is a successful no-op. A dispatch routed to a service with the wrong durable gateway account mode fails with GatewayConfigurationChanged; callers must route it to the matching service rather than silently discard it. The operation never invokes end-user admission or the live offer store and never holds a database lock across provider I/O.

Source§

impl SubscriptionBillingService

Source

pub async fn cancel( &self, command: CancelSubscription, ) -> Result<CancelSubscriptionOutcome, SubscriptionBillingServiceError>

Cancels one exact subscriber-owned subscription lifecycle.

Admission runs before any database work. When cancellation changes canonical state, its event is appended on the same host-prepared transaction before that transaction commits. Replays and semantic blockers commit without an event. This operation performs no provider resolution or provider I/O.

Source

pub async fn claim_discount( &self, command: SubscriptionDiscountClaim, ) -> Result<SubscriptionDiscountClaimOutcome, SubscriptionBillingServiceError>

Claims an eligible discount code for one exact subscriber aggregate.

Admission happens before database work and the offer lock, claim, and commit use one local transaction. The operation does not resolve a gateway or perform provider I/O.

Source

pub async fn clear_discount( &self, command: ClearSubscriptionDiscount, ) -> Result<SubscriptionDiscountClearOutcome, SubscriptionBillingServiceError>

Clears the saved discount claim for one exact subscriber aggregate.

Admission happens before database work. The command has no provider identity and this operation performs neither gateway resolution nor provider I/O.

Source§

impl SubscriptionBillingService

Source

pub fn new( pool: PgPool, offers: Arc<dyn SubscriptionOfferStore>, resolver: Arc<dyn GatewayResolver>, admission: Arc<dyn EndUserMutationAdmission>, coordinator: Arc<dyn BillingTransactionCoordinator>, ) -> Self

Creates a service without the optional host-charge target capability.

Source

pub fn with_required_gateway_account_mode( self, mode: GatewayAccountMode, ) -> Self

Requires an exact gateway account mode before any provider mutation.

The default is GatewayAccountMode::Live. Selecting GatewayAccountMode::Test permits test-mode mutations and rejects a live account before submission. Hosts should bind this requirement to their trusted deployment environment, never to end-user input.

This service setting does not automatically partition entitlement or billing-portal reads. Test-mode subscriptions are ordinary paid subscriptions to the domain model and can satisfy Entitlement::permits_product_access; constrain EntitlementQuery and EntitlementGuard separately when modes share a database, and enforce any remaining environment isolation before granting production access.

Source

pub fn with_host_charge_targets( self, targets: Arc<dyn HostChargeTargetStore>, ) -> Self

Adds the optional host-charge target store to this service instance.

Trait Implementations§

Source§

impl Clone for SubscriptionBillingService

Source§

fn clone(&self) -> SubscriptionBillingService

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more