Skip to content

feat: sync with openiap v1.3.16 - ExternalPurchaseCustomLink API (iOS 18.1+)#613

Merged
hyochan merged 3 commits intomainfrom
feat/openiap-sync-1.3.16
Jan 25, 2026
Merged

feat: sync with openiap v1.3.16 - ExternalPurchaseCustomLink API (iOS 18.1+)#613
hyochan merged 3 commits intomainfrom
feat/openiap-sync-1.3.16

Conversation

@hyochan
Copy link
Copy Markdown
Owner

@hyochan hyochan commented Jan 25, 2026

Summary

  • Sync with OpenIAP v1.3.16 (gql: 1.3.16, apple: 1.3.14, google: 1.3.27)
  • Add support for Apple's ExternalPurchaseCustomLink API (iOS 18.1+)
    • isEligibleForExternalPurchaseCustomLinkIOS() - Check eligibility
    • getExternalPurchaseCustomLinkTokenIOS(tokenType) - Get token for reporting
    • showExternalPurchaseCustomLinkNoticeIOS(noticeType) - Show disclosure notice

Changes

  • Update openiap-versions.json
  • Regenerate Dart types with ExternalPurchaseCustomLink types
  • Add iOS native implementation (FlutterInappPurchasePlugin.swift)
  • Add Dart API wrappers (flutter_inapp_purchase.dart)
  • Update queryHandlers and mutationHandlers with new APIs
  • Add release blog post for v8.2.5
  • Update llms.txt and llms-full.txt

OpenIAP Versions

Package Version
openiap-gql 1.3.16
openiap-apple 1.3.14
openiap-google 1.3.27

Test plan

  • flutter analyze passes
  • flutter test passes (198 tests)
  • Verified iOS native code compiles

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Expanded public API surface for iOS 18.1+ to support ExternalPurchaseCustomLink flows: eligibility checks, token retrieval, and disclosure notices.
  • Documentation

    • Added detailed docs with end-to-end guidance, examples, and installation notes for external purchase custom link integration.
  • Tests

    • Added unit tests covering the new iOS external purchase custom link APIs and platform behaviors.
  • Chores

    • Updated related version metadata for platform integrations.

✏️ Tip: You can customize this high-level summary in your review settings.

… 18.1+)

- Update openiap-versions.json (gql: 1.3.16, apple: 1.3.14, google: 1.3.27)
- Regenerate Dart types with ExternalPurchaseCustomLink types
- Add iOS native implementation for 3 new APIs:
  - isEligibleForExternalPurchaseCustomLinkIOS()
  - getExternalPurchaseCustomLinkTokenIOS(tokenType)
  - showExternalPurchaseCustomLinkNoticeIOS(noticeType)
- Add Dart API wrappers in flutter_inapp_purchase.dart
- Update queryHandlers and mutationHandlers with new APIs
- Add release blog post for v8.2.5
- Update llms.txt and llms-full.txt with new APIs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 25, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

This PR adds iOS ExternalPurchaseCustomLink support (iOS 18.1+) to flutter_inapp_purchase: new APIs for eligibility, token retrieval, and notice display; Dart types and wiring; native Swift handlers; tests; docs; and OpenIAP version bumps.

Changes

Cohort / File(s) Summary
Type Definitions
lib/types.dart
Adds ExternalPurchaseCustomLinkNoticeTypeIOS, ExternalPurchaseCustomLinkTokenTypeIOS, ExternalPurchaseCustomLinkNoticeResultIOS, ExternalPurchaseCustomLinkTokenResultIOS; extends ExternalPurchaseNoticeResultIOS with externalPurchaseToken; adds resolver methods and handler typedefs; updates handler maps.
Dart API Layer
lib/flutter_inapp_purchase.dart
Adds isEligibleForExternalPurchaseCustomLinkIOS, getExternalPurchaseCustomLinkTokenIOS, showExternalPurchaseCustomLinkNoticeIOS; platform guards, wiring into builder/query/mutation handler maps, and error handling.
Swift Implementation
ios/Classes/FlutterInappPurchasePlugin.swift
Adds Flutter method handlers and private implementations for eligibility check, token retrieval, and notice display with iOS 18.1+ availability guards and OpenIapModule integration; consistent error mapping for unsupported platforms.
Tests
test/ios_methods_test.dart
New test group for ExternalPurchaseCustomLink APIs covering success, non-iOS behavior, and platform error cases; channel argument assertions and PurchaseError mapping.
Documentation
docs/blog/2026-01-26-8.2.5-external-purchase-custom-link.md, docs/static/llms-full.txt, docs/static/llms.txt
Adds release notes and examples describing the ExternalPurchaseCustomLink APIs, flows, and installation/usage guidance.
Dependencies / Versions
openiap-versions.json
Bumps apple 1.3.13 → 1.3.14 and gql 1.3.15 → 1.3.16.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(220,240,255,0.5)
    participant App as Flutter App
    participant Dart as Dart API
    participant iOS as iOS Plugin (Swift)
    participant OpenIAP as OpenIapModule / StoreKit
    participant Server as ExternalPurchase Server
    end

    App->>Dart: isEligibleForExternalPurchaseCustomLinkIOS()
    Dart->>iOS: invoke method channel
    iOS->>OpenIAP: check eligibility (StoreKit API)
    OpenIAP-->>iOS: eligibility result
    iOS-->>Dart: bool
    Dart-->>App: bool

    Note right of App: If eligible, flow continues

    App->>Dart: getExternalPurchaseCustomLinkTokenIOS(tokenType)
    Dart->>iOS: invoke method channel with tokenType
    iOS->>OpenIAP: request token
    OpenIAP-->>iOS: token
    iOS-->>Dart: token result
    Dart-->>App: token

    App->>Dart: showExternalPurchaseCustomLinkNoticeIOS(noticeType)
    Dart->>iOS: invoke method channel
    iOS->>OpenIAP: present notice sheet (returns externalPurchaseToken)
    OpenIAP-->>iOS: externalPurchaseToken
    iOS-->>Dart: notice result (including externalPurchaseToken)
    Dart-->>App: notice result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

$ openiap

Poem

🐰 I hopped on iOS meadow, ears all perked and bright,

Tokens, notices, checks — I stitched the path just right.
Three tiny hops to link the outside cart,
A carrot for users, and a leap for the heart. 🥕🐇

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: syncing the repository with OpenIAP v1.3.16 and adding the ExternalPurchaseCustomLink API for iOS 18.1+, which matches the primary focus of the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @hyochan, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request integrates the latest OpenIAP updates and introduces robust support for Apple's new ExternalPurchaseCustomLink API for iOS 18.1+. This functionality allows apps with the appropriate entitlement to manage custom external purchase links, including checking eligibility, generating tokens for Apple's reporting server, and displaying required disclosure notices, thereby providing a complete and compliant flow for external purchases.

Highlights

  • OpenIAP Version Sync: Synchronized the plugin with OpenIAP v1.3.16, which includes updates to openiap-gql (1.3.16) and openiap-apple (1.3.14).
  • Apple ExternalPurchaseCustomLink API Support: Introduced comprehensive support for Apple's new ExternalPurchaseCustomLink API, available for iOS 18.1+ and macOS 15.0+, allowing apps with the necessary entitlement to manage custom external purchase links.
  • New Dart APIs for External Purchases: Added three new Dart APIs: isEligibleForExternalPurchaseCustomLinkIOS() to check eligibility, getExternalPurchaseCustomLinkTokenIOS(tokenType) to retrieve tokens for reporting, and showExternalPurchaseCustomLinkNoticeIOS(noticeType) to display disclosure notices.
  • Enhanced External Purchase Notice Sheet: The existing presentExternalPurchaseNoticeSheetIOS() method has been updated to now return an externalPurchaseToken when a user chooses to continue to an external purchase, improving reporting capabilities.
  • Updated Documentation and Examples: New documentation, including a release blog post and updates to llms.txt and llms-full.txt, provides detailed guidance and code examples for implementing the new external purchase features.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 25, 2026

Codecov Report

❌ Patch coverage is 90.62500% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.68%. Comparing base (f60c34f) to head (4638113).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
lib/flutter_inapp_purchase.dart 90.62% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #613      +/-   ##
==========================================
+ Coverage   67.17%   67.68%   +0.50%     
==========================================
  Files           7        7              
  Lines        1447     1479      +32     
==========================================
+ Hits          972     1001      +29     
- Misses        475      478       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for Apple's ExternalPurchaseCustomLink API for iOS 18.1+, including native Swift implementation, Dart wrappers, and documentation updates. The changes are well-structured and follow the existing patterns in the codebase. I have identified a couple of issues. One is an inconsistency in error handling for one of the new APIs, where errors are silently swallowed. The other is a more significant issue regarding incorrect and inconsistent iOS version documentation for some existing external purchase APIs. I've provided suggestions to address these points to improve robustness and correctness.

lib/types.dart Outdated
Comment on lines 4651 to 4654
/// Present external purchase notice sheet (iOS 15.4+).
/// Uses ExternalPurchase.presentNoticeSheet() which returns a token when user continues.
/// Reference: https://developer.apple.com/documentation/storekit/externalpurchase/presentnoticesheet()
Future<ExternalPurchaseNoticeResultIOS> presentExternalPurchaseNoticeSheetIOS();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There are significant inconsistencies in the documented iOS versions for presentExternalPurchaseNoticeSheetIOS and the related canPresentExternalPurchaseNoticeIOS.

  • presentExternalPurchaseNoticeSheetIOS:

    • This Dart documentation states iOS 15.4+.
    • The native Swift implementation in FlutterInappPurchasePlugin.swift checks for iOS 18.2+.
    • Apple's official documentation states ExternalPurchase.presentNoticeSheet() is available from iOS 17.5+.
  • canPresentExternalPurchaseNoticeIOS (line 4702):

    • The Dart documentation states iOS 17.4+.
    • The native Swift implementation also checks for iOS 18.2+.
    • Apple's official documentation for ExternalPurchase.canPresent states iOS 17.5+.

These discrepancies are misleading and can cause runtime errors. Please correct the version numbers in both the Dart documentation and the Swift availability checks to align with Apple's official documentation (iOS 17.5+).

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The iOS version numbers in lib/types.dart are auto-generated from the OpenIAP schema and cannot be edited manually (per CLAUDE.md guidelines). The Swift implementation uses iOS 18.2+ because that's when the OpenIAP native module requires this feature.

The version discrepancy between Dart docs and Apple's official documentation is an upstream issue in the openiap-dart package that generates these types. This should be addressed in the OpenIAP schema repository rather than in this Flutter package.

For this PR, the implementation follows the native OpenIAP library's requirements (iOS 18.2+).

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After researching Apple's official documentation and developer forums:

The correct iOS version appears to be iOS 17.4+, not iOS 17.5+.

According to Apple Developer Forums and SDK release notes:

  • ExternalPurchase.canPresent and ExternalPurchase.presentNoticeSheet() became fully functional with token support starting iOS 17.4
  • On iOS 15.4 - 17.3, these APIs exist but don't provide tokens and return false
  • The linkToExternalPurchase() API is available on iOS 17.4+ for EU DMA compliance

Sources:

The types are auto-generated from the OpenIAP schema. I've opened an issue to verify the exact version requirements with Apple's documentation team, but based on current evidence, iOS 17.4+ is more accurate than iOS 17.5+.

Could you share the source for iOS 17.5+? I'd like to verify if there's a specific API change between 17.4 and 17.5.

hyochan and others added 2 commits January 26, 2026 04:10
…eCustomLink

- Throw PurchaseError instead of returning false on error in
  isEligibleForExternalPurchaseCustomLinkIOS for clearer error handling
- Add comprehensive test coverage for ExternalPurchaseCustomLink APIs:
  - isEligibleForExternalPurchaseCustomLinkIOS
  - getExternalPurchaseCustomLinkTokenIOS
  - showExternalPurchaseCustomLinkNoticeIOS

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@hyochan hyochan merged commit 8c0e294 into main Jan 25, 2026
6 checks passed
@hyochan hyochan deleted the feat/openiap-sync-1.3.16 branch January 25, 2026 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant