Skip to content
This repository was archived by the owner on Oct 16, 2025. It is now read-only.

Commit 6c5df56

Browse files
committed
fix: Enforce correct type for purchase vs subscription requests
- requestPurchaseWithSku now always uses .inApp type - Added requestSubscriptionWithSku for subscription purchases with .subs type - Prevents precondition failure when type doesn't match request kind
1 parent d7037c0 commit 6c5df56

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

Sources/OpenIapModule+ObjC.swift

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ import StoreKit
9797
) {
9898
Task {
9999
do {
100-
let productType = type.flatMap { ProductQueryType(rawValue: $0) } ?? .inApp
100+
// For purchase request, type must be .inApp
101101
let iosProps = RequestPurchaseIosProps(
102102
andDangerouslyFinishTransactionAutomatically: nil,
103103
appAccountToken: nil,
@@ -109,7 +109,66 @@ import StoreKit
109109
request: .purchase(
110110
RequestPurchasePropsByPlatforms(android: nil, ios: iosProps)
111111
),
112-
type: productType
112+
type: .inApp
113+
)
114+
115+
let result = try await requestPurchase(props)
116+
117+
switch result {
118+
case .purchase(let purchase):
119+
if let purchase = purchase {
120+
let dictionary = OpenIapSerialization.purchase(purchase)
121+
completion(dictionary, nil)
122+
} else {
123+
completion(nil, nil)
124+
}
125+
case .purchases(let purchases):
126+
if let firstPurchase = purchases?.first {
127+
let dictionary = OpenIapSerialization.purchase(firstPurchase)
128+
completion(dictionary, nil)
129+
} else {
130+
completion(nil, nil)
131+
}
132+
case .none:
133+
completion(nil, nil)
134+
}
135+
} catch {
136+
completion(nil, error)
137+
}
138+
}
139+
}
140+
141+
@objc func requestSubscriptionWithSku(
142+
_ sku: String,
143+
offer: [String: Any]?,
144+
completion: @escaping (Any?, Error?) -> Void
145+
) {
146+
Task {
147+
do {
148+
// For subscription request, type must be .subs
149+
let subscriptionOffer: SubscriptionOfferIOS? = if let offer = offer {
150+
SubscriptionOfferIOS(
151+
id: offer["id"] as? String,
152+
keyIdentifier: offer["keyIdentifier"] as? String,
153+
nonce: (offer["nonce"] as? String).flatMap { UUID(uuidString: $0) },
154+
signature: offer["signature"] as? String,
155+
timestamp: offer["timestamp"] as? Int64 ?? 0
156+
)
157+
} else {
158+
nil
159+
}
160+
161+
let iosProps = RequestSubscriptionIosProps(
162+
andDangerouslyFinishTransactionAutomatically: nil,
163+
appAccountToken: nil,
164+
sku: sku,
165+
withOffer: subscriptionOffer
166+
)
167+
let props = RequestPurchaseProps(
168+
request: .subscription(
169+
RequestPurchasePropsByPlatforms(android: nil, ios: iosProps)
170+
),
171+
type: .subs
113172
)
114173

115174
let result = try await requestPurchase(props)

0 commit comments

Comments
 (0)