Add an internal wrapper over StoreKit's ExternalPurchaseCustomLink - #7594
Add an internal wrapper over StoreKit's ExternalPurchaseCustomLink#7594ajpallares wants to merge 6 commits into
Conversation
|
| Name | Version | Download | Change | Install | Change | Approval |
|---|---|---|---|---|---|---|
| RevenueCat com.revenuecat.PaywallsTester |
1.0 (1) | 20.3 MB | ⬆️ 13.5 kB (0.07%) | 73.9 MB | ⬆️ 50.7 kB (0.07%) | N/A |
| BinarySizeTest com.revenuecat.binary-size-test.local-source |
1.0 (1) | 4.9 MB | ⬇️ 501 B (-0.01%) | 14.6 MB | ⬆️ 156 B | N/A |
| BinarySizeTest com.revenuecat.binary-size-test.cocoapods |
1.0 (1) | 7.3 MB | ⬆️ 138 B | 31.8 MB | ⬆️ 156 B | N/A |
| BinarySizeTest com.revenuecat.binary-size-test.spm |
1.0 (1) | 4.9 MB | ⬇️ 289 B | 12.7 MB | ⬆️ 156 B | N/A |
RevenueCat 1.0 (1)
com.revenuecat.PaywallsTester
⚖️ Compare build
⏱️ Analyze build performance
Total install size change: ⬆️ 50.7 kB (0.07%)
Total download size change: ⬆️ 13.5 kB (0.07%)
Largest size changes
| Item | Install Size Change |
|---|---|
| DYLD.String Table | ⬆️ 16.8 kB |
| DYLD.Exports | ⬆️ 1.7 kB |
| Code Signature | ⬆️ 1.2 kB |
| DYLD.Fixups | ⬆️ 1.1 kB |
| Other | ⬆️ 29.8 kB |
BinarySizeTest 1.0 (1)
com.revenuecat.binary-size-test.local-source
⚖️ Compare build
📦 Install build
⏱️ Analyze build performance
Total install size change: ⬆️ 156 B
Total download size change: ⬇️ 501 B (-0.01%)
Largest size changes
| Item | Install Size Change |
|---|---|
| Other | ⬆️ 156 B |
BinarySizeTest 1.0 (1)
com.revenuecat.binary-size-test.cocoapods
⚖️ Compare build
📦 Install build
⏱️ Analyze build performance
Total install size change: ⬆️ 156 B
Total download size change: ⬆️ 138 B
Largest size changes
| Item | Install Size Change |
|---|---|
| DYLD.String Table | ⬆️ 608 B |
| Other | ⬇️ -452 B |
BinarySizeTest 1.0 (1)
com.revenuecat.binary-size-test.spm
⚖️ Compare build
📦 Install build
⏱️ Analyze build performance
Total install size change: ⬆️ 156 B
Total download size change: ⬇️ 289 B
Largest size changes
| Item | Install Size Change |
|---|---|
| Other | ⬆️ 156 B |
🛸 Powered by Emerge Tools
9d25064 to
7e985ea
Compare
7e985ea to
649afe0
Compare
Keeps StoreKit's types and their availability out of the protocol's signature, so the token retrieval, disclosure notice and backend reporting built on top of it in later PRs do not each inherit @available(iOS 18.1, *), and mocks stay usable on the older simulators CI runs. The API ships in the iOS 18.1 SDK, so every use of it is gated on compiler(>=6.0.2) as well as the OS version. Nothing calls this yet. Co-authored-by: Cursor <cursoragent@cursor.com>
Apple's implementation checklists for every external purchase flow name isEligible as the runtime gate and never mention canMakePayments; it appears once, as a "for more information, see" cross-reference. AppStore.canMakePayments reports whether the account may pay through Apple's payment system, which an external purchase deliberately does not use, so gating on it would hide a legitimate payment path from a customer whose only restriction is on in-app purchases. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
They asserted that the mock returns what it was stubbed with, so they covered no production code. The mock stays for the token manager built on it in a later PR. Co-authored-by: Cursor <cursoragent@cursor.com>
Apple requires both ExternalPurchaseCustomLink.isEligible and AppStore.canMakePayments before an app may request an external purchase token. The two are orthogonal: the first accounts for the storefront, the second for parental controls, Screen Time and MDM. Rename isEligible() to canMakeExternalPurchases() so it is not mistaken for StoreKit's own property, and have it answer both. Co-authored-by: Cursor <cursoragent@cursor.com>
649afe0 to
666e3d8
Compare




Checklist
purchases-androidand hybridsMotivation
First step towards supporting Apple's external purchase custom links. Nothing calls it yet; later PRs build the token retrieval, disclosure notice and backend reporting on top.
Description
@available(iOS 18.1, *), and mocks stay usable on the iOS 15–17 simulators CI runs.#if compiler(>=6.0.2): the API ships in the iOS 18.1 SDK (Xcode 16.1), and CI still builds with Xcode 14.3.1 and 15.4. Both branches of the gate compile.Note
Low Risk
Internal-only scaffolding with no public API or production call sites yet; availability and compiler gating limit blast radius.
Overview
Introduces an internal
ExternalPurchaselayer under Purchasing as the first step toward Apple’s external purchase custom links. Nothing in the SDK calls it yet; follow-up work is expected to wire tokens, disclosure UI, and backend reporting.The new
ExternalPurchaseCustomLinkTypeprotocol exposes eligibility, token retrieval, and disclosure notice flows using SDK-owned types so upper layers (e.g. future paywall UI) avoid@available(iOS 18.1, *)and tests can use mocks on older simulators.StoreKitExternalPurchaseCustomLinkimplements it via StoreKit’sExternalPurchaseCustomLink, combining StoreKit eligibility with existingPaymentAuthorizationProviderchecks. StoreKit usage is gated on#if compiler(>=6.0.2)and iOS 18.1+ (and aligned OS versions) so older Xcode CI toolchains still compile.Supporting types include forward-compatible
ExternalPurchaseTokenType(IN_APP/LINK_OUT), notice type/result enums, andExternalPurchaseError.apiUnavailable. Unit tests cover mappings, availability behavior, and payment authorization;MockExternalPurchaseCustomLinkis added for future callers.Reviewed by Cursor Bugbot for commit 666e3d8. Bugbot is set up for automated code reviews on this repo. Configure here.