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]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).
Native references: Apple · Product.SubscriptionOffer · Google · ProductDetails.SubscriptionOfferDetails
Common Fields#
| Field | Type | Description |
|---|---|---|
id | ID! | Unique identifier for the offer |
displayPrice | String! | Formatted display price (e.g., "$9.99/month") |
price | Float! | Numeric price value |
currency | String | Currency code (ISO 4217) |
type | DiscountOfferType! | introductory or promotional |
period | SubscriptionPeriod | Subscription period (unit + value) |
periodCount | Int | Number of periods the offer applies |
paymentMode | PaymentMode | FreeTrial, PayAsYouGo, or PayUpFront |
iOS-Specific Fields#
| Field | Type | Description |
|---|---|---|
keyIdentifierIOS | String | Key ID for server-side signature validation |
nonceIOS | String | Cryptographic nonce (UUID) for signature |
signatureIOS | String | Server-generated signature for validation |
timestampIOS | Float | Timestamp when signature was generated |
numberOfPeriodsIOS | Int | Number of billing periods for this discount |
localizedPriceIOS | String | Localized price string |
Android-Specific Fields#
| Field | Type | Description |
|---|---|---|
basePlanIdAndroid | String | Base plan identifier |
offerTokenAndroid | String | Required for purchase. Pass to requestPurchase() |
offerTagsAndroid | [String!] | Tags associated with this offer |
pricingPhasesAndroid | PricingPhasesAndroid | Pricing phases (trial, intro, regular) |
installmentPlanDetailsAndroid | InstallmentPlanDetailsAndroid | Installment 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"
}