iap

package
v1.8.0 Latest Latest
Warning

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

Go to latest
Published: Sep 24, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package iap holds the Apple and Google in-app-purchase verifiers. They live outside the cashier package so their heavier crypto and HTTP dependencies do not weigh on callers who only use card gateways.

Index

Constants

View Source
const (
	// FreeTierMicros is the tracked transaction volume that is free, in micros
	// (2000 * 1_000_000). Past this, transactions are billable.
	FreeTierMicros int64 = 2000 * 1_000_000
	// FeeRatePerMille is the fee beyond the free tier, in parts per thousand:
	// 10‰ = 1%.
	FeeRatePerMille int64 = 10
)

Variables

This section is empty.

Functions

func Metered

Metered wraps a verifier so its entitlements are gated by a meter. Registering the result with IAPManager is what turns a raw verifier into the paid feature.

Types

type AppleConfig

type AppleConfig struct {
	BundleID     string
	AllowSandbox bool
	// RootCertsPEM is Apple's root certificate(s) in PEM. Required: without a
	// pinned root there is nothing to anchor the chain to. Apple publishes the
	// "Apple Root CA - G3" certificate for this.
	RootCertsPEM []byte
}

AppleConfig configures the Apple verifier.

type AppleVerifier

type AppleVerifier struct {
	// contains filtered or unexported fields
}

AppleVerifier verifies StoreKit 2 JWS transactions and V2 notifications.

func NewApple

func NewApple(cfg AppleConfig) (*AppleVerifier, error)

NewApple builds the Apple verifier.

func (*AppleVerifier) ParseNotification

func (a *AppleVerifier) ParseNotification(payload []byte) (*contracts.StoreNotification, error)

ParseNotification verifies an App Store Server Notification V2 and reduces it to the canonical shape.

func (*AppleVerifier) Platform

func (a *AppleVerifier) Platform() contracts.IAPPlatform

func (*AppleVerifier) VerifyReceipt

VerifyReceipt verifies a StoreKit 2 signed transaction and returns the entitlement it proves.

type CloudMeter

type CloudMeter struct {
	// contains filtered or unexported fields
}

CloudMeter reports transactions to Nimbus Cloud and enforces its decisions.

func NewCloudMeter

func NewCloudMeter(cfg CloudMeterConfig) (*CloudMeter, error)

NewCloudMeter builds a meter backed by Nimbus Cloud.

func (*CloudMeter) Authorize

func (m *CloudMeter) Authorize(ctx context.Context, t MeteredTransaction) (Decision, error)

Authorize reports a transaction and returns Cloud's decision.

type CloudMeterConfig

type CloudMeterConfig struct {
	// APIKey authenticates the developer's Nimbus Cloud account. Required —
	// without it there is no account to meter, so the gate fails closed.
	APIKey string
	// Endpoint overrides the metering URL. Defaults to Nimbus Cloud.
	Endpoint string
	// HTTPClient overrides the client (tests point it at a mock server).
	HTTPClient *http.Client
	// FailClosed makes a Cloud outage deny access instead of granting it. Off
	// by default; see the failure policy above before turning it on.
	FailClosed bool
}

CloudMeterConfig configures the Cloud meter.

type Decision

type Decision struct {
	// Allowed is whether the entitlement may be returned to the app.
	Allowed bool
	// Reason explains a denial, for logs and errors.
	Reason string
	// TrackedVolumeMicros is the account's cumulative tracked volume after this
	// transaction, as the meter understands it.
	TrackedVolumeMicros int64
	// FeeMicros is what this transaction cost (0 within the free tier).
	FeeMicros int64
	// OverFreeTier is whether the account has exhausted the free allowance.
	OverFreeTier bool
	// Reconcile is set when the decision was made locally after a Cloud outage
	// and must be re-reported later. The entitlement was still granted.
	Reconcile bool
}

Decision is the meter's ruling on a transaction.

type GoogleConfig

type GoogleConfig struct {
	// PackageName is the app's package; a purchase is looked up under it.
	PackageName string
	// ServiceAccountJSON is the Google Cloud service-account key with access to
	// the Play Developer API, as downloaded from the console.
	ServiceAccountJSON []byte
}

GoogleConfig configures the Google verifier.

type GoogleVerifier

type GoogleVerifier struct {
	// contains filtered or unexported fields
}

GoogleVerifier verifies Google Play purchases via the Android Publisher API.

func NewGoogle

func NewGoogle(cfg GoogleConfig) (*GoogleVerifier, error)

NewGoogle builds the Google verifier.

func (*GoogleVerifier) ParseNotification

func (g *GoogleVerifier) ParseNotification(payload []byte) (*contracts.StoreNotification, error)

ParseNotification decodes a Real-time Developer Notification.

Google's RTDNs are not signed the way Apple's are — authenticity comes from the Pub/Sub push being authenticated at the transport, not from a signature in the body — so this decodes and canonicalises rather than verifying a signature. The entitlement itself must still be confirmed by calling VerifyReceipt with the token inside.

func (*GoogleVerifier) Platform

func (g *GoogleVerifier) Platform() contracts.IAPPlatform

func (*GoogleVerifier) VerifyReceipt

VerifyReceipt looks a purchase up against the Android Publisher API.

type LocalMeter

type LocalMeter struct {
	// contains filtered or unexported fields
}

LocalMeter is a process-local Meter: it applies the exact tier and fee rules without a network call. It is the default for development and the reference the Cloud meter is tested against, and it always allows — enforcement of an unpaid account is Nimbus Cloud's job, not a local cache's.

func NewLocalMeter

func NewLocalMeter() *LocalMeter

NewLocalMeter builds an in-memory meter for one tenant.

func (*LocalMeter) Authorize

Authorize records the transaction locally and computes its fee.

func (*LocalMeter) TrackedVolume

func (m *LocalMeter) TrackedVolume() int64

TrackedVolume returns the tenant's accumulated volume, for tests and reports.

type Meter

type Meter interface {
	// Authorize records a transaction and rules on whether its entitlement may
	// be granted. It must fail open on transient errors (see the package note).
	Authorize(ctx context.Context, t MeteredTransaction) (Decision, error)
}

Meter authorises and records IAP transactions for billing.

type MeteredTransaction

type MeteredTransaction struct {
	Platform      contracts.IAPPlatform
	TransactionID string
	ProductID     string
	Subject       string
	PriceMicros   int64
	Currency      string
	Environment   string // "sandbox" transactions are never metered
}

MeteredTransaction is one verified purchase reported for metering.

func (MeteredTransaction) Billable

func (t MeteredTransaction) Billable() bool

Billable reports whether a transaction counts toward volume and fees at all. A sandbox purchase or a zero-price event never does.

Jump to

Keyboard shortcuts

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