Table of Contents

Interface IBillingProvider

Namespace
VpnHood.AppLib.Abstractions.Billing
Assembly
VpnHood.AppLib.Abstractions.dll

The calls that take the window get null where none is open, as in the desktop service: a store whose sheet needs one fails then, and the web store, whose checkout the UI opens, needs none.

public interface IBillingProvider : IDisposable
Inherited Members

Properties

IsSubscriptionManagementSupported

Whether this device can show the store's own manage-subscriptions surface (cancel, change plan, payment method). A runtime question, not a constant: a TV carries a store that cannot show that screen, and answering false there is what lets the UI say "manage it where you bought it" instead of offering a control that does nothing.

bool IsSubscriptionManagementSupported { get; }

Property Value

bool

ProviderId

Which store this is (see StoreIds), in the vocabulary the account backend speaks. Declared here because the provider is the one thing that cannot be wrong about it — so nothing that wires a store has to state it a second time and risk disagreeing.

string ProviderId { get; }

Property Value

string

PurchaseState

Gets where the store's payment flow stands.

PurchaseState PurchaseState { get; }

Property Value

PurchaseState

Methods

FinishPurchase(PurchaseProof, CancellationToken)

Tells the store the purchase behind this proof is delivered: the account backend has redeemed it. Called only then, so a purchase whose redeeming failed stays open where the store keeps one open (StoreKit's unfinished transaction), and a later Restore presents it again. A store whose backend closes the purchase itself (Play's acknowledgement) has nothing to do here.

Task FinishPurchase(PurchaseProof purchaseProof, CancellationToken cancellationToken)

Parameters

purchaseProof PurchaseProof

The proof the account backend has redeemed.

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task

A task that represents the asynchronous operation.

Exceptions

BillingException

The store failed; its Code says how.

ArgumentException

The proof is not one this provider answered, as the App Store's checks.

OperationCanceledException

cancellationToken was canceled.

GetSubscriptionPlans(IReadOnlyList<string>, CancellationToken)

Prices the given products. The store is not asked WHICH products exist — it cannot answer that (neither StoreKit nor Play Billing can list an app's own catalog) and it is not the authority on it either: the account backend decides what may be sold, this prices and localizes it.

Task<IReadOnlyList<SubscriptionPlan>> GetSubscriptionPlans(IReadOnlyList<string> productIds, CancellationToken cancellationToken)

Parameters

productIds IReadOnlyList<string>

The product IDs the account backend gives (GetProductIds(CancellationToken)).

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task<IReadOnlyList<SubscriptionPlan>>

A task whose result is the plans the store prices for them.

Exceptions

ApiException

For the web store, the account backend refused the request.

BillingException

The store failed; its Code says how.

OperationCanceledException

cancellationToken was canceled.

OpenSubscriptionManagement(IUiContext?, CancellationToken)

Shows that surface. The store does it its own way — an in-app sheet, its own app — so no URL crosses to the UI and no browser has to exist. Only ever called for a subscription THIS store billed, and only while IsSubscriptionManagementSupported: the app refuses the call otherwise, so an implementation need not re-check its own answer.

Task OpenSubscriptionManagement(IUiContext? uiContext, CancellationToken cancellationToken)

Parameters

uiContext IUiContext

The window, or null where none is open.

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task

A task that completes once the store's surface is shown.

Exceptions

NotSupportedException

The store has no such surface here, as the web store's.

UiContextNotAvailableException

uiContext is null, and the store needs a window.

OperationCanceledException

cancellationToken was canceled.

Purchase(IUiContext?, PurchaseParams, PurchaseAttribution, CancellationToken)

Runs the store's payment flow and answers its proof of purchase.

Two arguments because they have two owners: purchaseParams is the buyer's choice, attribution is the app's answer to whose account is paying.

Task<PurchaseProof> Purchase(IUiContext? uiContext, PurchaseParams purchaseParams, PurchaseAttribution attribution, CancellationToken cancellationToken)

Parameters

uiContext IUiContext

The window, or null where none is open.

purchaseParams PurchaseParams

The plan the buyer chose.

attribution PurchaseAttribution

Whose account the purchase is for.

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task<PurchaseProof>

A task whose result is the store's proof of purchase.

Exceptions

BillingException

The store failed, or the person closed its payment flow (Cancelled); its Code says how.

NotSupportedException

The store sells outside the app, as the web store, on its checkout page.

InvalidOperationException

A purchase is under way already, or the account's ID does not fit the store, as the App Store's, which takes a UUID.

ArgumentException

The plan names a product the store does not have.

UiContextNotAvailableException

uiContext is null, and the store needs a window.

OperationCanceledException

cancellationToken was canceled.

RestorePurchase(IUiContext?, CancellationToken)

The proof for a subscription this store account already owns, or null when it owns none. Silent: it reads what the device already knows and never prompts.

Task<PurchaseProof?> RestorePurchase(IUiContext? uiContext, CancellationToken cancellationToken)

Parameters

uiContext IUiContext

The window, or null where none is open.

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task<PurchaseProof>

A task whose result is the proof, or null where the store account owns no subscription.

Exceptions

BillingException

The store failed; its Code says how.

OperationCanceledException

cancellationToken was canceled.