Help us shape the future of Go! Take the 2026 Go Developer Survey

dawl

module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2026 License: MIT

README

dawl

Subscriptions from every store, in one vocabulary. dawl verifies what Stripe, the App Store and Google Play report about a subscription and normalises it into a single subscription.State, with one rule for how long it grants access.

It is the store-facing half of billing, shared by Rondo and Invaris. Plans, limits, storage and what an app does when a plan changes stay in each app.

Package What it does
subscription Provider, Status, State with Until and Entitles, the Gateway and Renewer interfaces, Webhook, and the errors gateways return. Standard library only, so apps can use it from their domain layer.
stripe Customers, Checkout, the customer portal, webhook verification, subscription state, renewal off and on.
appstore StoreKit 2 transactions and App Store Server Notifications V2, verified against Apple's root certificate; subscription status from the App Store Server API (production, then sandbox).
googleplay Subscription state and acknowledgement from the Android Publisher API; Real-time Developer Notifications verified from their Pub/Sub push.

Every gateway is a subscription.Gateway: Verify checks proof from an app's purchase, and Notification reads a store's notification. Stores deliver notifications late and out of order, so Notification always returns the subscription as the store has it now: saving it is safe in any order. subscription.Webhook serves notifications for any gateway:

var gw subscription.Gateway = stripe.New(stripe.Config{SecretKey: key, WebhookSecret: whsec, AccountMetadataKey: "app_account"})

http.Handle("POST /webhooks/stripe", subscription.Webhook(gw, func(ctx context.Context, s subscription.State) error {
	return save(ctx, s.Account, s) // then: s.Until() or s.Entitles(time.Now())
}))

state, err := appStore.Verify(ctx, signedTransaction) // from StoreKit 2, in an app's request

State.Until is when a subscription stops granting access: its period end, plus subscription.Grace while the store may still renew it. An app that keeps "access until" stores the latest Until of a person's subscriptions; access it grants itself (gifts, codes) fits as an active subscription with renewal off.

A gateway that can turn renewal off and on from the server is also a subscription.Renewer (Stripe's is; the App Store and Google Play leave that to the person):

if r, ok := gw.(subscription.Renewer); ok {
	err = r.SetAutoRenew(ctx, state.ProviderRef, false) // the paid period stays
}

Every gateway wraps failures in one of the subscription.Err* values (ErrUnverified, ErrNotSubscription, ErrInvalidNotification, ErrMalformed, ErrNotFound, ErrUnavailable), so an app maps them onto its own errors with errors.Is. State.Account is the app's account id as the store carries it (Stripe metadata, appAccountToken, obfuscatedExternalAccountId); dawl never interprets it.

Development

golangci-lint run && go test -race ./...

Contributing

Issues and pull requests are welcome; see CONTRIBUTING.md. Contributions are accepted under the Contributor License Agreement.

License

dawl is released under the MIT License.

Directories

Path Synopsis
Package appstore is the App Store gateway for subscriptions bought in iOS and macOS apps: it verifies StoreKit 2 transactions and App Store Server Notifications V2, and reads a subscription's current status from the App Store Server API.
Package appstore is the App Store gateway for subscriptions bought in iOS and macOS apps: it verifies StoreKit 2 transactions and App Store Server Notifications V2, and reads a subscription's current status from the App Store Server API.
Package googleplay is the Google Play billing gateway: subscription state from the Android Publisher API and Real-time Developer Notifications delivered by Pub/Sub push.
Package googleplay is the Google Play billing gateway: subscription state from the Android Publisher API and Real-time Developer Notifications delivered by Pub/Sub push.
internal
jwks
Package jwks resolves JWT verification keys from a provider's published JSON Web Key Set (Google's OIDC tokens on Play notifications).
Package jwks resolves JWT verification keys from a provider's published JSON Web Key Set (Google's OIDC tokens on Play notifications).
Package stripe is the Stripe gateway for web subscriptions: Checkout to subscribe, the customer portal to manage, webhooks to stay in sync, and renewal turned off and on from the server.
Package stripe is the Stripe gateway for web subscriptions: Checkout to subscribe, the customer portal to manage, webhooks to stay in sync, and renewal turned off and on from the server.
Package subscription is the vocabulary every store is translated into: where a subscription was bought (Provider), where it stands (Status), its verified state as the store reports it (State), and the one rule for how long it grants access (State.Until).
Package subscription is the vocabulary every store is translated into: where a subscription was bought (Provider), where it stands (Status), its verified state as the store reports it (State), and the one rule for how long it grants access (State.Until).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL