NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
BillDog SDK for Flutter — monetization, paywalls, subscriptions and BillDog Auth sign-in. Thin bridge over the native iOS/Android SDKs with inline native paywall rendering.
Last release 5 days ago
03 Oct 2026
Ships fairly regularly
a new release about every 5 weeks
Unknown
no stable releases
Nothing withdrawn
no release was ever pulled
2 months old
3 releases · first in 2026
One column per month.
PurchaseController.restorePurchases returns RestoreResult. The deprecated RestorationResult alias is removed.
StoreEvidence (with fromInAppPurchase, which maps a StoreKit 1 restore to
the original transaction id), PurchaseRecording, BillDog.recordPurchase,
syncStorePurchases, purchaseRecordingIssues, storeAccountToken, and
observePurchaseResult(evidence:, transactionId:).PurchaseController.purchase(PurchaseRequest) and restore(), defaulted to
the per-store methods, return PurchaseOutcome / RestoreOutcome with the
purchase's evidence. capabilities and storeKitVersion declare what the
controller can honour.Pending, not a failure or a hang.PurchaseController subclass may no longer declare its own members named
purchase, restore, capabilities or storeKitVersion.OfferingResult carries the placement as the server describes it:
placementInfo (PlacementInfo), presentation (PlacementPresentation:
gated, holdout, withheld, withheldReason), experiment
(PlacementExperiment, with variantName) and campaign
(PlacementCampaign), on every outcome. gated, placementId,
experimentId and variantId are read from them. The plugins used to send
null for every display field, the variant name and the campaign.BillDogError carrying the
server's wire code: PlacementError.error, PresentError.error,
RestoreFailed.error, WebCheckoutResult.failure, Failed.error;
getCustomerInfo, getPaywall, identify, setUserAttributes and
hasAccessForPlacement throw one; BillDogAuth.deleteAccount() throws
ReauthRequiredError / ProofRequiredError / ProofInvalidError.
BillDogDelegate.onPurchaseFailed receives a BillDogError, not a string.restorePurchases
(RestoreFailed), register (PlacementError) and getPresentationResult
(PresentError); an empty native answer to getOffering is OfferingFailed.
These used to read as an empty restore, a dismissal, "no paywall" and
"nothing configured".presentSurvey on an unconfigured SDK is an error, not a silent success.showInAppMessages returns whether they were shown (false on iOS, which
has no equivalent); it used to answer as if it had worked everywhere.setSandboxMode is removed: it was a no-op on both platforms (sandbox is
decided by the API-key prefix).getOffering(placement) returns an OfferingResult (OfferingAvailable,
OfferingHoldout, OfferingWithheld, OfferingNotConfigured,
OfferingFailed) instead of Offering?. A holdout, a withheld placement and
a refusal are reported as themselves; no other offering is substituted.hasAccessForPlacement is asynchronous and asks the native SDK. It used to
read a value nothing wrote, and answered true for every placement.PurchaseController.restorePurchases returns RestoreResult. The deprecated
RestorationResult alias is removed.paywall_id. placement_identifier holds
the placement identifier; placement_id is sent only when the placement's
server id is known.getOfferings(): the project's default offering. No placement identifier is
sent.purchase(productId), purchasePackage(package), purchaseViaWeb(productId)
and completeWebCheckout(uri).BillDogAuth.deleteAccount().ProofRequiredError, ProofInvalidError (proof),
ReauthRequiredError (maxAgeSeconds), AccessDeniedError (selector),
PurchaseOwnerConflictError (retryable), PlacementAccessWithheldError,
PlacementNotFoundError.BillDogDelegate.onWebCheckoutRedeemed(RedemptionOutcome): the native
onDidRedeemLink, every outcome included (RedemptionRefused carries the
server's typed refusal).integrations/billdog_superwall: an optional Superwall purchase controller
backed by BillDog.BillDogAuth and BillDogOrganizations call threw
MissingPluginException: Dart invoked them on the billdog channel while
both plugins handle them on io.billdog.flutter/sdk.reset() tore the native SDK down (it called native reset()); every
call after a logout failed until configure ran again. It now calls native
logOut(), as Android does.pigeons/billdog_api.dart) and the pigeon
dev-dependency. No generated code existed; the channels are hand-written.checkPendingActions and
completeAction, which neither plugin handled. The native SDKs fetch,
execute and report journey actions themselves.Fixes iOS dependency resolution. The published podspec declared s.dependency 'BillDog' — a pod that has never existed on the CocoaPods trunk — so pod
Fixes iOS dependency resolution. The published podspec declared
s.dependency 'BillDog' — a pod that has never existed on the CocoaPods trunk —
so pod install failed with "Unable to find a specification for BillDog".
It now depends on BillDogFull (which the Swift sources already imported) with a
version floor naming the pre-release (>= 1.0.0-beta.2), since CocoaPods will not
select a pre-release for an unversioned or ~> requirement.
No Dart API or behaviour changes.
Initial public beta. Thin bridge over the native BillDog iOS/Android SDKs, with inline native paywall rendering via a PlatformView.
Initial public beta. Thin bridge over the native BillDog iOS/Android SDKs, with
inline native paywall rendering via a PlatformView.
PaywallView).PurchaseController bridge.logIn / logOut / identify with attribute support and
persistence across configure.MethodChannel bridge (io.billdog.flutter/sdk) to the native
SDKs. (This entry used to claim pigeon-generated channels; no pigeon output
was ever generated or consumed, and the unused schema has been removed.)Your coding agent can read these notes before it upgrades. Set up the MCP server →