{"lexicon":1,"id":"money.atmosphere.payment.previewSubscriptionChange","defs":{"subscriptionChange":{"type":"object","required":["changeId","subscriptionId","subscriptionRevision","environment","status","direction","fromPaymentId","targetProgram","targetTier","targetListing","targetEntitlements","currentAmount","targetAmount","chargeAmount","currency","interval","intervalCount","requiresPayment","effectiveAt","quoteHash","quoteExpiresAt","createdAt","updatedAt"],"properties":{"changeId":{"type":"string","maxLength":128,"description":"Opaque ATM tier-change id. Apps may persist this id and reconcile only changes they already know."},"subscriptionId":{"type":"string","maxLength":256},"subscriptionRevision":{"type":"integer","minimum":1},"environment":{"type":"string","knownValues":["live","test"],"maxLength":16},"status":{"type":"string","knownValues":["quoted","awaiting_confirmation","awaiting_payment","action_required","scheduled","paid_pending_apply","applied","failed","canceled","superseded","expired"],"maxLength":32},"direction":{"type":"string","knownValues":["upgrade","downgrade","lateral"],"maxLength":16},"fromPaymentId":{"type":"string","maxLength":256},"currentProgram":{"type":"ref","ref":"com.atproto.repo.strongRef"},"currentTier":{"type":"ref","ref":"com.atproto.repo.strongRef"},"currentListing":{"type":"ref","ref":"com.atproto.repo.strongRef"},"targetProgram":{"type":"ref","ref":"com.atproto.repo.strongRef"},"targetTier":{"type":"ref","ref":"com.atproto.repo.strongRef"},"targetListing":{"type":"ref","ref":"com.atproto.repo.strongRef"},"targetEntitlements":{"type":"array","maxLength":50,"items":{"type":"ref","ref":"com.atproto.repo.strongRef"}},"currentAmount":{"type":"integer","minimum":0},"targetAmount":{"type":"integer","minimum":0},"chargeAmount":{"type":"integer","minimum":0,"description":"Amount ATM will attempt immediately after exact hosted confirmation. Upgrades charge the full target amount with no old-tier credit; scheduled changes return zero."},"currency":{"type":"string","minLength":3,"maxLength":3},"interval":{"type":"string","knownValues":["day","week","month","year"],"maxLength":16},"intervalCount":{"type":"integer","minimum":1,"maximum":1095},"requiresPayment":{"type":"boolean","description":"True when confirmation requires an immediate upgrade payment. False for a scheduled change, whose target access still waits for the exact paid renewal."},"effectiveAt":{"type":"string","format":"datetime"},"currentPeriodEnd":{"type":"string","format":"datetime"},"quoteHash":{"type":"string","minLength":64,"maxLength":64,"description":"ATM-authored hash of the exact revision, CIDs, money, cadence, policy, and expiry shown to the payer."},"quoteExpiresAt":{"type":"string","format":"datetime"},"confirmedAt":{"type":"string","format":"datetime"},"paidAt":{"type":"string","format":"datetime"},"appliedAt":{"type":"string","format":"datetime"},"failureCode":{"type":"string","maxLength":64},"createdAt":{"type":"string","format":"datetime"},"updatedAt":{"type":"string","format":"datetime"}}},"main":{"type":"procedure","description":"Create a short-lived ATM-authored membership tier-change quote without changing billing or access. Requires registered requesting-app service auth plus a fresh, single-use payer assertion. The requester must either be the stable subscription originator or hold the creator's current environment-scoped subscription approval; ATM preserves the original originator in either case. ATM validates the target program, tier, and recurring price strongRefs in the creator's repo, requires the same portable membership program/currency/cadence, binds the quote to expectedRevision, and permits only one active change intent per subscription.","input":{"encoding":"application/json","schema":{"type":"object","required":["payerDid","payerAssertion","environment","subscriptionId","expectedRevision","changeAttemptId","targetProgram","targetTier","targetPrice"],"properties":{"payerDid":{"type":"string","format":"did"},"payerAssertion":{"type":"string","maxLength":4096},"environment":{"type":"string","knownValues":["live","test"],"maxLength":16},"subscriptionId":{"type":"string","maxLength":256},"expectedRevision":{"type":"integer","minimum":1},"changeAttemptId":{"type":"string","minLength":1,"maxLength":200,"description":"App-generated idempotency key. Reuse with different semantic input is rejected."},"targetProgram":{"type":"ref","ref":"com.atproto.repo.strongRef"},"targetTier":{"type":"ref","ref":"com.atproto.repo.strongRef"},"targetPrice":{"type":"ref","ref":"com.atproto.repo.strongRef"},"targetAmount":{"type":"integer","minimum":0,"description":"Optional target amount assertion. In v1 tier switching requires a fixed recurring target price and this value, when sent, must equal it."}}}},"output":{"encoding":"application/json","schema":{"type":"object","required":["change"],"properties":{"change":{"type":"ref","ref":"#subscriptionChange"}}}},"errors":[{"name":"FeatureUnavailable"},{"name":"AppNotRegistered"},{"name":"RateLimited"},{"name":"InvalidPayerAssertion"},{"name":"PayerDidMismatch"},{"name":"SubscriptionNotFound"},{"name":"SubscriptionRevisionMismatch"},{"name":"SubscriptionNotEligible"},{"name":"SubscriptionNoticesUnavailable"},{"name":"MembershipContextUnavailable"},{"name":"MembershipTargetInvalid"},{"name":"MembershipProgramMismatch"},{"name":"SubscriptionPeriodUnavailable"},{"name":"TargetChanged"},{"name":"SubscriptionCadenceMismatch"},{"name":"CurrencyMismatch"},{"name":"AlreadyOnTier"},{"name":"VariableAmountTierChangeUnsupported"},{"name":"InvalidAmount"},{"name":"TargetAmountMismatch"},{"name":"TargetProcessorPriceUnavailable"},{"name":"SubscriptionChangeAlreadyPending"},{"name":"IdempotencyConflict"},{"name":"QuoteExpired"},{"name":"SubscriptionChangeWriteFailed"},{"name":"SubscriptionChangeFailed"}]}}}