Skip to content

Commit 770c67a

Browse files
committed
Merge branch 'fix-store-payments-on-prod-builds' into ios-release-2025.8
2 parents 67e59a8 + 010a995 commit 770c67a

File tree

3 files changed

+11
-88
lines changed

3 files changed

+11
-88
lines changed

ios/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ Line wrap the file at 100 chars. Th
2323

2424
## UNRELEASED
2525

26+
### Fixed
27+
- Fix in-app purchases.
28+
2629
## [2025.6 - 2025-09-23]
2730
### Added
2831
- Add support for obfuscating WireGuard tunnel traffic as the QUIC protocol. This helps

ios/MullvadREST/MullvadAPI/APIHandlers/MullvadAPIProxy.swift

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ public protocol APIQuerying: Sendable {
2323
completionHandler: @escaping @Sendable ProxyCompletionHandler<REST.ServerRelaysCacheResponse>
2424
) -> Cancellable
2525

26-
func createApplePayment(
27-
accountNumber: String,
28-
receiptString: Data
29-
) -> any RESTRequestExecutor<REST.CreateApplePaymentResponse>
30-
3126
func legacyStorekitPayment(
3227
accountNumber: String,
3328
request: LegacyStorekitRequest,
@@ -156,16 +151,6 @@ extension REST {
156151
AnyCancellable()
157152
}
158153

159-
/// Not implemented. Use `RESTAPIProxy` instead.
160-
public func createApplePayment(
161-
accountNumber: String,
162-
receiptString: Data
163-
) -> any RESTRequestExecutor<REST.CreateApplePaymentResponse> {
164-
RESTRequestExecutorStub<REST.CreateApplePaymentResponse>(success: {
165-
.timeAdded(0, .now)
166-
})
167-
}
168-
169154
public func checkApiAvailability(
170155
retryStrategy: REST.RetryStrategy,
171156
accessMethod: PersistentAccessMethod,
@@ -328,35 +313,3 @@ extension REST {
328313
let newExpiry: Date
329314
}
330315
}
331-
332-
// TODO: Remove when Mullvad API is production ready.
333-
private struct RESTRequestExecutorStub<Success: Sendable>: RESTRequestExecutor {
334-
var success: (() -> Success)?
335-
336-
func execute(completionHandler: @escaping (Result<Success, Error>) -> Void) -> Cancellable {
337-
if let result = success?() {
338-
completionHandler(.success(result))
339-
}
340-
return AnyCancellable()
341-
}
342-
343-
func execute(
344-
retryStrategy: REST.RetryStrategy,
345-
completionHandler: @escaping (Result<Success, Error>) -> Void
346-
) -> Cancellable {
347-
if let result = success?() {
348-
completionHandler(.success(result))
349-
}
350-
return AnyCancellable()
351-
}
352-
353-
func execute() async throws -> Success {
354-
try await execute(retryStrategy: .noRetry)
355-
}
356-
357-
func execute(retryStrategy: REST.RetryStrategy) async throws -> Success {
358-
guard let success = success else { throw POSIXError(.EINVAL) }
359-
360-
return success()
361-
}
362-
}

ios/MullvadVPN/StorePaymentManager/SendStoreReceiptOperation.swift

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -132,45 +132,12 @@ class SendStoreReceiptOperation: ResultOperation<REST.CreateApplePaymentResponse
132132
}
133133
}
134134

135-
#if DEBUG
136-
private func sendReceipt(_ receiptData: Data) {
137-
submitReceiptTask = apiProxy.legacyStorekitPayment(
138-
accountNumber: accountNumber,
139-
request: LegacyStorekitRequest(receiptString: receiptData),
140-
retryStrategy: .default,
141-
completionHandler: { result in
142-
switch result {
143-
case let .success(response):
144-
self.logger.info(
145-
"""
146-
AppStore receipt was processed. \
147-
Time added: \(response.timeAdded), \
148-
New expiry: \(response.newExpiry.logFormatted)
149-
"""
150-
)
151-
self.finish(result: .success(response))
152-
153-
case let .failure(error):
154-
if error.isOperationCancellationError {
155-
self.logger.debug("Receipt submission cancelled.")
156-
self.finish(result: .failure(error))
157-
} else {
158-
self.logger.error(
159-
error: error,
160-
message: "Failed to send the AppStore receipt."
161-
)
162-
self.finish(result: .failure(StorePaymentManagerError.sendReceipt(error)))
163-
}
164-
}
165-
}
166-
)
167-
}
168-
#else
169-
private func sendReceipt(_ receiptData: Data) {
170-
submitReceiptTask = apiProxy.createApplePayment(
171-
accountNumber: accountNumber,
172-
receiptString: receiptData
173-
).execute(retryStrategy: .noRetry) { result in
135+
private func sendReceipt(_ receiptData: Data) {
136+
submitReceiptTask = apiProxy.legacyStorekitPayment(
137+
accountNumber: accountNumber,
138+
request: LegacyStorekitRequest(receiptString: receiptData),
139+
retryStrategy: .default,
140+
completionHandler: { result in
174141
switch result {
175142
case let .success(response):
176143
self.logger.info(
@@ -195,8 +162,8 @@ class SendStoreReceiptOperation: ResultOperation<REST.CreateApplePaymentResponse
195162
}
196163
}
197164
}
198-
}
199-
#endif
165+
)
166+
}
200167
}
201168

202169
struct StoreReceiptNotFound: LocalizedError {

0 commit comments

Comments
 (0)