Use this page with AI

Copy this into your coding assistant and add your request.

Read https://openiap.dev/docs/types/subscription-offer and https://openiap.dev/llms.txt. Follow the reading instructions, detailed reference, and linked guides relevant to my task before making changes.
Inspect my existing project and reuse its framework and conventions. Ask me for missing product decisions. Implement the requested behavior and run the applicable checks.
Show the working result, the commands and actual test results, and any remaining limitations. Keep your explanation brief.

My request: [describe what customers should be able to do]
See an example request →

SubscriptionOffer

SubscriptionOffer#

Standardized type for subscription promotional offers. Supported on both iOS (introductory and promotional offers) and Android (offer tokens with pricing phases).

Cross-platform subscription-offer envelope. iOS: maps to Product.SubscriptionOffer (Apple docs). Android: maps to SubscriptionOfferDetails (Google docs).

Common Fields#

FieldTypeDescription
idID!Unique identifier for the offer
displayPriceString!Formatted display price (e.g., "$9.99/month")
priceFloat!Numeric price value
currencyStringCurrency code (ISO 4217)
typeDiscountOfferType!introductory or promotional
periodSubscriptionPeriodSubscription period (unit + value)
periodCountIntNumber of periods the offer applies
paymentModePaymentModeFreeTrial, PayAsYouGo, or PayUpFront

iOS-Specific Fields#

FieldTypeDescription
keyIdentifierIOSStringKey ID for server-side signature validation
nonceIOSStringCryptographic nonce (UUID) for signature
signatureIOSStringServer-generated signature for validation
timestampIOSFloatTimestamp when signature was generated
numberOfPeriodsIOSIntNumber of billing periods for this discount
localizedPriceIOSStringLocalized price string

Android-Specific Fields#

FieldTypeDescription
basePlanIdAndroidStringBase plan identifier
offerTokenAndroidStringRequired for purchase. Pass to requestPurchase()
offerTagsAndroid[String!]Tags associated with this offer
pricingPhasesAndroidPricingPhasesAndroidPricing phases (trial, intro, regular)
installmentPlanDetailsAndroidInstallmentPlanDetailsAndroidInstallment plan details for subscription commitments (7.0+)

Type Definition#

swift
struct SubscriptionOffer: Codable {
    // Common fields
    let id: String
    let displayPrice: String
    let price: Double
    let currency: String?
    let type: DiscountOfferType
    let period: SubscriptionPeriod?
    let periodCount: Int?
    let paymentMode: PaymentMode?

    // iOS-specific fields
    let keyIdentifierIOS: String?
    let nonceIOS: String?
    let signatureIOS: String?
    let timestampIOS: Double?
    let numberOfPeriodsIOS: Int?
    let localizedPriceIOS: String?

    // Android-specific fields
    let basePlanIdAndroid: String?
    let offerTokenAndroid: String?
    let offerTagsAndroid: [String]?
    let pricingPhasesAndroid: PricingPhasesAndroid?
    let installmentPlanDetailsAndroid: InstallmentPlanDetailsAndroid?
}

struct InstallmentPlanDetailsAndroid: Codable {
    let commitmentPaymentsCount: Int
    let subsequentCommitmentPaymentsCount: Int
}

struct SubscriptionPeriod: Codable {
    let unit: SubscriptionPeriodUnit
    let value: Int
}

enum SubscriptionPeriodUnit: String, Codable {
    case day = "day"
    case week = "week"
    case month = "month"
    case year = "year"
    case unknown = "unknown"
}

enum PaymentMode: String, Codable {
    case freeTrial = "free-trial"
    case payAsYouGo = "pay-as-you-go"
    case payUpFront = "pay-up-front"
    case unknown = "unknown"
}