Skip to content

fix(apple): allow subscription tier changes and cancellations#44

Merged
hyochan merged 1 commit into
mainfrom
fix/43
Nov 18, 2025
Merged

fix(apple): allow subscription tier changes and cancellations#44
hyochan merged 1 commit into
mainfrom
fix/43

Conversation

@hyochan
Copy link
Copy Markdown
Member

@hyochan hyochan commented Nov 18, 2025

Fixes #43 - Users can now cancel or modify scheduled subscription changes. Previously blocked when trying to revert to current subscription after scheduling a different tier.

Now checks autoRenewPreference to detect scheduled changes and allows modification/cancellation.

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of subscription renewal requests when the same product is already active with refined decision logic based on renewal status.
  • New Features

    • Added enhanced tracking for scheduled subscription renewal changes.
    • Improved renewal preference management for better user control over active subscriptions.

Fixes #43 - Users can now cancel or modify scheduled subscription changes.
Previously blocked when trying to revert to current subscription after
scheduling a different tier.

Now checks autoRenewPreference to detect scheduled changes and allows
modification/cancellation.
@hyochan hyochan added the 📱 iOS Related to iOS label Nov 18, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 18, 2025

Walkthrough

Modified subscription purchase logic in requestPurchase to track autoRenewPreference from renewal info and determine if a scheduled renewal change exists. When a scheduled change is detected, the function now permits modification instead of blocking. Otherwise, the previous behavior is retained.

Changes

Cohort / File(s) Summary
Subscription Purchase Blocking Logic
packages/apple/Sources/OpenIapModule.swift
Modified requestPurchase to introduce autoRenewPreference tracking from verified renewal info and compute hasScheduledChange based on mismatch between autoRenewPreference and current transaction.productID. If a scheduled change exists, allows modification with additional logging; otherwise, retains existing blocking behavior. Added renewal status checks and adjusted comments to reflect scheduling-change scenarios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas requiring extra attention:
    • Logic for determining hasScheduledChange based on autoRenewPreference comparison and its interaction with existing willAutoRenew checks
    • Verification that the scheduled-change path correctly permits purchase modifications and doesn't inadvertently relax intended restrictions
    • Edge cases around renewal info verification, autoRenewPreference extraction, and state consistency between transaction.productID and preference values

Possibly related issues

  • #41: Previous issue on subscription blocking; this change builds upon the same autoRenewPreference handling framework to address the follow-up scenario.
  • #36: Related change to requestPurchase logic that checks subscription state and renewal info.

Possibly related PRs

  • #42: Also modifies subscription purchase-blocking logic in OpenIapModule.swift to handle auto-renew preference and scheduled-change scenarios.
  • #34: Modifies requestPurchase in the same file to change subscription purchase flow behavior.
  • #40: Modifies requestPurchase in the same file, addressing error mapping and renewal status handling.

Suggested labels

🛠 bugfix

Poem

🐰 A hop, a skip, a scheduled change,
No more blocks that felt so strange,
When subscriptions swap and shift about,
The preference now resolves the doubt!
Let users choose what serves them best,
While old transitions pass the test.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: allowing subscription tier changes and cancellations, which directly addresses the blocking issue described in the PR objectives.
Linked Issues check ✅ Passed The code changes implement the core requirement from issue #43 by detecting scheduled changes via autoRenewPreference and allowing modifications when detected, resolving the unintended blocking scenario.
Out of Scope Changes check ✅ Passed All changes focus on fixing the subscription change blocking logic in requestPurchase and are directly related to issue #43 objectives with no extraneous modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/43

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b76dc1 and d03b636.

📒 Files selected for processing (1)
  • packages/apple/Sources/OpenIapModule.swift (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test Android
🔇 Additional comments (4)
packages/apple/Sources/OpenIapModule.swift (4)

219-221: LGTM! Clear variable declaration for tracking scheduled changes.

The addition of autoRenewPreference to detect scheduled subscription changes is well-placed and properly typed.


240-242: Correct logic for detecting scheduled subscription changes.

The hasScheduledChange calculation accurately identifies when a user has scheduled a change to a different product by checking if autoRenewPreference is both non-nil and different from the current transaction.productID. This directly addresses the issue #43 scenario.


244-276: Excellent fix that correctly addresses issue #43 while preserving existing behavior.

The new control flow properly handles the scheduled subscription change scenario:

  1. Lines 244-252 (NEW): When a scheduled change is detected, allows the user to modify or cancel it — directly fixing the issue where reverting to the current SKU was incorrectly blocked.

  2. Lines 253-267: Preserves the original blocking behavior when the user has an active auto-renewing subscription with no scheduled changes.

  3. Lines 268-276: Preserves the ability to repurchase a cancelled subscription.

The implementation correctly resolves the issue where transaction.productID comparison was insufficient. By checking autoRenewPreference, the code now accurately detects when a user has scheduled a different tier and allows modification accordingly.


222-238: Verify error handling defaults and inconsistency with subscription status checks.

The error handling defaults may not be as safe as stated. When subscription.status fetch fails (lines 235–237), the code leaves willAutoRenew = true (initialized at line 220), which causes the logic at line 253 to throw .alreadyOwned and block the purchase request. This prevents users from reactivating cancelled subscriptions when renewal info is temporarily unavailable.

Additionally, this conflicts with the pattern in StoreKitTypesBridge.swift (line 110), which defaults willAutoRenew to false when renewal info is unavailable. Verify which default is intended and align both paths, or document why they should differ.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hyochan hyochan added the 🛠 bugfix All kinds of bug fixes label Nov 18, 2025
@hyochan hyochan merged commit 5e29fec into main Nov 18, 2025
4 of 5 checks passed
@hyochan hyochan deleted the fix/43 branch November 18, 2025 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠 bugfix All kinds of bug fixes 📱 iOS Related to iOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unintended blocking when changing subscription

1 participant