Skip to content
This repository was archived by the owner on Apr 26, 2026. It is now read-only.

feat: sync with openiap v1.3.17#33

Merged
hyochan merged 1 commit into
mainfrom
feat/openiap-sync-1.3.17
Feb 11, 2026
Merged

feat: sync with openiap v1.3.17#33
hyochan merged 1 commit into
mainfrom
feat/openiap-sync-1.3.17

Conversation

@hyochan

@hyochan hyochan commented Feb 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • Sync with OpenIAP v1.3.17
  • Add InstallmentPlanDetailsAndroid data class (Billing Library 7.0+)
  • Add PendingPurchaseUpdateAndroid data class (Billing Library 5.0+)
  • Add purchaseOptionIdAndroid field to DiscountOffer (Billing Library 7.0+)
  • Update llms.txt with new type documentation
  • Add release blog post

Related

OpenIAP Versions

Package Version
openiap-gql 1.3.17
openiap-google 1.3.28
openiap-apple 1.3.14

🤖 Generated with Claude Code

- Update openiap-versions.json (gql: 1.3.17, apple: 1.3.14, google: 1.3.28)
- Add InstallmentPlanDetailsAndroid data class (Billing Library 7.0+)
- Add PendingPurchaseUpdateAndroid data class (Billing Library 5.0+)
- Add purchaseOptionIdAndroid field to DiscountOffer (Billing Library 7.0+)
- Update llms.txt with new type documentation
- Add release blog post

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

coderabbitai Bot commented Feb 10, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@hyochan has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 18 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/openiap-sync-1.3.17

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

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 updates the project to align with OpenIAP v1.3.17, primarily focusing on enhancing Android billing capabilities. It introduces support for advanced Google Play Billing Library features, such as subscription installment plans and pending purchase updates, by adding new data structures and fields. This ensures compatibility with newer billing library versions and provides developers with more granular control and information regarding in-app purchases and subscriptions on the Android platform.

Highlights

  • OpenIAP Sync: Synchronized the project with OpenIAP v1.3.17, ensuring compatibility with the latest features and improvements from the upstream library.
  • New Android Billing Types: Introduced the InstallmentPlanDetailsAndroid data class to support subscription installment plans, relevant for Google Play Billing Library 7.0+.
  • Pending Purchase Updates: Added the PendingPurchaseUpdateAndroid data class to handle details of pending subscription upgrades or downgrades, applicable for Google Play Billing Library 5.0+.
  • Purchase Option ID: Integrated the purchaseOptionIdAndroid field into DiscountOffer and ProductAndroidOneTimePurchaseOfferDetail to identify selected purchase options, supporting Billing Library 7.0+.
  • Documentation Updates: Updated llms.txt to include documentation for the newly added Android-specific types and published a new release blog post detailing these changes.

🧠 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.

Changelog
  • docs/blog/2026-02-11-release-1.3.7.md
    • Added a new blog post for release 1.3.7, detailing the sync with OpenIAP 1.3.17 and new Android billing types.
  • docs/static/llms.txt
    • Added purchaseOptionIdAndroid field to DiscountOffer.
    • Added new data class definitions for InstallmentPlanDetailsAndroid and PendingPurchaseUpdateAndroid.
  • library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt
    • Added purchaseOptionIdAndroid to DiscountOffer and ProductAndroidOneTimePurchaseOfferDetail.
    • Removed '(iOS 17.4+)' from ExternalPurchaseLinkResultIOS documentation.
    • Added InstallmentPlanDetailsAndroid data class with commitmentPaymentsCount and subsequentCommitmentPaymentsCount.
    • Added PendingPurchaseUpdateAndroid data class with products and purchaseToken.
    • Added installmentPlanDetails to ProductSubscriptionAndroidOfferDetails.
    • Added pendingPurchaseUpdateAndroid to PurchaseAndroid.
    • Added installmentPlanDetailsAndroid to SubscriptionOffer.
    • Removed '(iOS 17.4+)' from presentExternalPurchaseLinkIOS function documentation.
  • openiap-versions.json
    • Updated google version from 1.3.27 to 1.3.28.
    • Updated gql version from 1.3.16 to 1.3.17.
Activity
  • No human activity has been recorded on this pull request yet.
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.

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

Copy link
Copy Markdown

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 syncs the project with OpenIAP v1.3.17, introducing new data classes for recent Google Play Billing Library features. However, a medium-severity vulnerability was identified where the PendingPurchaseUpdateAndroid data class insecurely deserializes the purchaseToken, defaulting to an empty string for invalid input, which could lead to logic errors or security bypasses. Additionally, there's a minor correction needed for the date in the new release blog post and a suggestion to improve the robustness of JSON parsing for the new PendingPurchaseUpdateAndroid type to prevent potential issues with invalid data.

Comment on lines +1893 to +1920
public data class PendingPurchaseUpdateAndroid(
/**
* Product IDs for the pending purchase update.
* These are the new products the user is switching to.
*/
val products: List<String>,
/**
* Purchase token for the pending transaction.
* Use this token to track or manage the pending purchase update.
*/
val purchaseToken: String
) {

companion object {
fun fromJson(json: Map<String, Any?>): PendingPurchaseUpdateAndroid {
return PendingPurchaseUpdateAndroid(
products = (json["products"] as? List<*>)?.mapNotNull { it as? String } ?: emptyList(),
purchaseToken = json["purchaseToken"] as? String ?: "",
)
}
}

fun toJson(): Map<String, Any?> = mapOf(
"__typename" to "PendingPurchaseUpdateAndroid",
"products" to products,
"purchaseToken" to purchaseToken,
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

The purchaseToken field in PendingPurchaseUpdateAndroid.fromJson is a critical security identifier. Defaulting it to an empty string ("") upon invalid input creates a medium-severity vulnerability, potentially leading to authentication bypasses or incorrect resource access. It's crucial to handle invalid or missing tokens securely, ideally by making the field nullable (String?) and assigning null to ensure downstream logic correctly handles its absence, rather than masking issues with an empty string.

public data class PendingPurchaseUpdateAndroid(
    /**
     * Product IDs for the pending purchase update.
     * These are the new products the user is switching to.
     */
    val products: List<String>,
    /**
     * Purchase token for the pending transaction.
     * Use this token to track or manage the pending purchase update.
     */
    val purchaseToken: String?
) {

    companion object {
        fun fromJson(json: Map<String, Any?>): PendingPurchaseUpdateAndroid {
            return PendingPurchaseUpdateAndroid(
                products = (json["products"] as? List<*>)?.mapNotNull { it as? String } ?: emptyList(),
                purchaseToken = json["purchaseToken"] as? String,
            )
        }
    }

    fun toJson(): Map<String, Any?> = mapOf(
        "__typename" to "PendingPurchaseUpdateAndroid",
        "products" to products,
        "purchaseToken" to purchaseToken,
    )
}

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.

This type is auto-generated from the OpenIAP GraphQL specification, where purchaseToken is defined as String! (non-nullable).

The OpenIAP spec follows Google Play Billing Library's contract where PendingPurchaseUpdate.getPurchaseToken() never returns null - it always returns a valid token when a pending update exists. The parent field pendingPurchaseUpdateAndroid is already nullable, so if there's no pending update, the entire object is null rather than having a null token.

Changes to this type should be proposed upstream at the OpenIAP specification: https://github.com/hyodotdev/openiap.dev/discussions

Comment thread docs/blog/2026-02-11-release-1.3.7.md
@hyochan hyochan merged commit 7efece4 into main Feb 11, 2026
4 checks passed
@hyochan hyochan deleted the feat/openiap-sync-1.3.17 branch February 11, 2026 02:37
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant