This repository was archived by the owner on Oct 16, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathOpenIapSerialization.swift
More file actions
122 lines (116 loc) · 5.45 KB
/
OpenIapSerialization.swift
File metadata and controls
122 lines (116 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import Foundation
/// Utilities to serialize OpenIAP models into dictionary payloads
/// for easy bridging to JavaScript/React Native or analytics.
/// These functions are pure and not MainActor-isolated.
@available(iOS 15.0, macOS 12.0, *)
public enum OpenIapSerialization {
/// Serialize a product into a dictionary reflecting the OpenIAP spec fields
@inlinable
public static func product(_ product: OpenIapProduct) -> [String: Any?] {
return [
"platform": "ios",
"id": product.id,
"title": product.title,
"description": product.description,
"price": product.price ?? 0,
"localizedPrice": product.displayPrice,
"currency": product.currency,
"type": product.type,
"displayPrice": product.displayPrice,
"displayName": product.displayName,
"jsonRepresentationIOS": product.jsonRepresentationIOS,
"isFamilyShareable": product.isFamilyShareableIOS,
// Subscription fields (iOS)
"subscriptionPeriodNumberIOS": product.subscriptionInfoIOS?.subscriptionPeriod.value ?? 0,
"subscriptionPeriodUnitIOS": product.subscriptionInfoIOS?.subscriptionPeriod.unit.rawValue,
"introductoryPricePaymentModeIOS": product.subscriptionInfoIOS?.introductoryOffer?.paymentMode.rawValue,
"introductoryPriceNumberOfPeriodsIOS": product.subscriptionInfoIOS?.introductoryOffer?.periodCount ?? 0,
"introductoryPriceSubscriptionPeriodIOS": product.subscriptionInfoIOS?.introductoryOffer?.period.unit.rawValue,
// Android placeholders kept for schema parity
"subscriptionPeriodAndroid": nil,
"subscriptionPeriodUnitAndroid": nil,
"introductoryPriceCyclesAndroid": nil,
"introductoryPricePeriodAndroid": nil,
"freeTrialPeriodAndroid": nil,
// Discounts list (iOS)
"discounts": product.discountsIOS?.map { discount in
[
"identifier": discount.identifier,
"type": discount.type,
"numberOfPeriods": discount.numberOfPeriods,
"price": discount.priceAmount,
"localizedPrice": discount.price,
"paymentMode": discount.paymentMode,
"subscriptionPeriod": discount.subscriptionPeriod
]
}
]
}
/// Serialize a purchase into a dictionary reflecting the OpenIAP spec fields
@inlinable
public static func purchase(_ purchase: OpenIapPurchase) -> [String: Any?] {
return [
"platform": "ios",
"id": purchase.id,
"productId": purchase.productId,
"transactionDate": purchase.transactionDate,
"transactionReceipt": purchase.transactionReceipt,
"purchaseToken": purchase.purchaseToken,
"quantity": purchase.quantity,
"purchaseState": purchase.purchaseState.rawValue,
"isAutoRenewing": purchase.isAutoRenewing,
// iOS specific fields
"quantityIOS": purchase.quantityIOS,
"originalTransactionDateIOS": purchase.originalTransactionDateIOS,
"originalTransactionIdentifierIOS": purchase.originalTransactionIdentifierIOS,
"appAccountToken": purchase.appAccountToken,
"expirationDateIOS": purchase.expirationDateIOS,
"webOrderLineItemIdIOS": purchase.webOrderLineItemIdIOS,
"environmentIOS": purchase.environmentIOS,
"storefrontCountryCodeIOS": purchase.storefrontCountryCodeIOS,
"appBundleIdIOS": purchase.appBundleIdIOS,
"productTypeIOS": purchase.productTypeIOS,
"subscriptionGroupIdIOS": purchase.subscriptionGroupIdIOS,
"isUpgradedIOS": purchase.isUpgradedIOS,
"ownershipTypeIOS": purchase.ownershipTypeIOS,
"reasonIOS": purchase.reasonIOS,
"reasonStringRepresentationIOS": purchase.reasonStringRepresentationIOS,
"transactionReasonIOS": purchase.transactionReasonIOS,
"revocationDateIOS": purchase.revocationDateIOS,
"revocationReasonIOS": purchase.revocationReasonIOS,
"offerIOS": purchase.offerIOS.map { [
"id": $0.id,
"type": $0.type,
"paymentMode": $0.paymentMode
]},
"currencyCodeIOS": purchase.currencyCodeIOS,
"currencySymbolIOS": purchase.currencySymbolIOS,
"countryCodeIOS": purchase.countryCodeIOS
]
}
/// Serialize a list of products
@inlinable
public static func products(_ items: [OpenIapProduct]) -> [[String: Any?]] {
return items.map { product($0) }
}
/// Serialize a list of purchases
@inlinable
public static func purchases(_ items: [OpenIapPurchase]) -> [[String: Any?]] {
return items.map { purchase($0) }
}
/// Error code map for bridging to JavaScript/TypeScript constants
@inlinable
public static func errorCodes() -> [String: String] {
return OpenIapError.errorCodes()
}
/// Default messages for each error code (code -> message)
@inlinable
public static func errorMessages() -> [String: String] {
let codes = OpenIapError.errorCodes().values
var map: [String: String] = [:]
for code in codes {
map[code] = OpenIapError.defaultMessage(for: code)
}
return map
}
}