|
@@ -8,19 +8,31 @@ struct PaywallConfig: Codable, Sendable {
|
|
|
let subtitleTemplate: String
|
|
let subtitleTemplate: String
|
|
|
let trialSubtitleTemplate: String?
|
|
let trialSubtitleTemplate: String?
|
|
|
let ctaTemplate: String
|
|
let ctaTemplate: String
|
|
|
|
|
+ let fallbackPrice: String
|
|
|
|
|
+ let priceSuffix: String?
|
|
|
|
|
+ let fallbackBillingDescription: String
|
|
|
|
|
+ let features: [String]
|
|
|
|
|
|
|
|
init(
|
|
init(
|
|
|
title: String,
|
|
title: String,
|
|
|
badge: String? = nil,
|
|
badge: String? = nil,
|
|
|
subtitleTemplate: String,
|
|
subtitleTemplate: String,
|
|
|
trialSubtitleTemplate: String? = nil,
|
|
trialSubtitleTemplate: String? = nil,
|
|
|
- ctaTemplate: String
|
|
|
|
|
|
|
+ ctaTemplate: String,
|
|
|
|
|
+ fallbackPrice: String,
|
|
|
|
|
+ priceSuffix: String? = nil,
|
|
|
|
|
+ fallbackBillingDescription: String,
|
|
|
|
|
+ features: [String]
|
|
|
) {
|
|
) {
|
|
|
self.title = title
|
|
self.title = title
|
|
|
self.badge = badge
|
|
self.badge = badge
|
|
|
self.subtitleTemplate = subtitleTemplate
|
|
self.subtitleTemplate = subtitleTemplate
|
|
|
self.trialSubtitleTemplate = trialSubtitleTemplate
|
|
self.trialSubtitleTemplate = trialSubtitleTemplate
|
|
|
self.ctaTemplate = ctaTemplate
|
|
self.ctaTemplate = ctaTemplate
|
|
|
|
|
+ self.fallbackPrice = fallbackPrice
|
|
|
|
|
+ self.priceSuffix = priceSuffix
|
|
|
|
|
+ self.fallbackBillingDescription = fallbackBillingDescription
|
|
|
|
|
+ self.features = features
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -91,6 +103,12 @@ struct PaywallConfig: Codable, Sendable {
|
|
|
let retry: String
|
|
let retry: String
|
|
|
let retrying: String
|
|
let retrying: String
|
|
|
let periodFallback: String
|
|
let periodFallback: String
|
|
|
|
|
+ let productsLoadTimeout: String
|
|
|
|
|
+ let subscriptionUnavailable: String
|
|
|
|
|
+ let planUnavailable: String
|
|
|
|
|
+ let noActiveSubscriptions: String
|
|
|
|
|
+ let restoreSyncTimeout: String
|
|
|
|
|
+ let purchaseGeneric: String
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
struct Sidebar: Codable, Sendable {
|
|
struct Sidebar: Codable, Sendable {
|
|
@@ -122,6 +140,8 @@ struct PaywallConfig: Codable, Sendable {
|
|
|
let trialDisclosureTemplate: String
|
|
let trialDisclosureTemplate: String
|
|
|
let lifetimeDisclosure: String
|
|
let lifetimeDisclosure: String
|
|
|
let loadingDisclosure: String
|
|
let loadingDisclosure: String
|
|
|
|
|
+ let securePaymentNote: String
|
|
|
|
|
+ let closeButtonHelp: String
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
extension PaywallConfig {
|
|
extension PaywallConfig {
|
|
@@ -145,10 +165,35 @@ extension PaywallConfig {
|
|
|
subscriptionDisclosureTemplate: subscriptionDisclosureTemplate,
|
|
subscriptionDisclosureTemplate: subscriptionDisclosureTemplate,
|
|
|
trialDisclosureTemplate: trialDisclosureTemplate,
|
|
trialDisclosureTemplate: trialDisclosureTemplate,
|
|
|
lifetimeDisclosure: lifetimeDisclosure,
|
|
lifetimeDisclosure: lifetimeDisclosure,
|
|
|
- loadingDisclosure: loadingDisclosure
|
|
|
|
|
|
|
+ loadingDisclosure: loadingDisclosure,
|
|
|
|
|
+ securePaymentNote: securePaymentNote,
|
|
|
|
|
+ closeButtonHelp: closeButtonHelp
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ func message(for error: PurchaseError) -> String {
|
|
|
|
|
+ switch error {
|
|
|
|
|
+ case .productsLoadTimeout:
|
|
|
|
|
+ messages.productsLoadTimeout
|
|
|
|
|
+ case .subscriptionUnavailable:
|
|
|
|
|
+ messages.subscriptionUnavailable
|
|
|
|
|
+ case .planUnavailable:
|
|
|
|
|
+ messages.planUnavailable
|
|
|
|
|
+ case .purchaseNotVerified:
|
|
|
|
|
+ messages.failedVerification
|
|
|
|
|
+ case .purchasePending:
|
|
|
|
|
+ messages.pendingPurchaseMessage
|
|
|
|
|
+ case .noActiveSubscriptions:
|
|
|
|
|
+ messages.noActiveSubscriptions
|
|
|
|
|
+ case .noActivePurchases:
|
|
|
|
|
+ messages.restoreNotFoundMessage
|
|
|
|
|
+ case .restoreSyncTimeout:
|
|
|
|
|
+ messages.restoreSyncTimeout
|
|
|
|
|
+ case .generic:
|
|
|
|
|
+ messages.purchaseGeneric
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
static func loadBundled() -> PaywallConfig {
|
|
static func loadBundled() -> PaywallConfig {
|
|
|
guard let url = Bundle.main.url(forResource: "paywall", withExtension: "json"),
|
|
guard let url = Bundle.main.url(forResource: "paywall", withExtension: "json"),
|
|
|
let data = try? Data(contentsOf: url),
|
|
let data = try? Data(contentsOf: url),
|