Skip to content

feat: ship 6.2.0 with emit, token promo offer signing and refundHandling - #169

Merged
kherembourg merged 24 commits into
mainfrom
feat/6.2.0-native-apis
Oct 9, 2026
Merged

kherembourg merged 24 commits into
mainfrom
feat/6.2.0-native-apis

Conversation

@kherembourg

@kherembourg kherembourg commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

What

Why

Release 6.2.0 of the bridge, on top of the published native iOS and Android 6.2.0. #162 failed iOS CI because the bridge pinned iOS 6.1.2, which has no refundHandling; the 6.2.0 pin fixes it. Linear: MOB-581 (refundHandling), MOB-593 (token signing).

How to verify

Run locally on the branch by the builder (full suites):

  • dart format --set-exit-if-changed . with Dart 3.5.4 in the three packages: 0 files changed (HEAD 6dc288b).
  • flutter analyze --no-fatal-infos --no-fatal-warnings in the three packages: no issues (HEAD 6dc288b).
  • cd purchasely && flutter test --coverage: 368 passed (HEAD 6dc288b). purchasely_google, purchasely_android_player: 2 passed each.
  • cd purchasely/example/android && ./gradlew :purchasely_flutter:testDebugUnitTest --rerun-tasks: 33 tests, 0 failed.
  • cd purchasely/example/ios && xcodebuild test -workspace Runner.xcworkspace -scheme Runner -only-testing:RunnerTests: 46 tests, 0 failures (HEAD cbda9c5).
  • Example flutter build apk --debug|--release, flutter build appbundle --release, extension apps ./gradlew assembleRelease, xcodebuild build -scheme Runner: all succeed.
  • Version Consistency and minSdk = 23 guards: pass.

The native Android and iOS suites ran on 2cf57f1. The only change after it is three doc/comment lines.

Notes

  • Pre-PR review: a Herdr reviewer (Claude Opus, high) reviewed head 2cf57f1 against the plan and the native 6.2.0 sources. No blocker, no major finding. Three doc fixes (native pin line, consent doc, podspec comment) are folded in at 6dc288b. The plan had a cross-CLI review (Codex) before implementation.
  • Dismissed: the copied "only available for iOS 15.0" message in the new iOS method. The #available guard says 12.2, the same as the existing method. The message stays identical to the existing one.
  • Three small iOS seams: SwiftPurchaselyFlutterPlugin.purchaseContextToken(from:), SwiftPurchaselyFlutterPlugin.dataProcessingPurposes(from:) (both internal and pure) and PLYOfferSignature.toMap(purchaseContextToken:). Production code uses all three.
  • Greptile (first pass): the consent mapping had no native test. Fixed in cbda9c5 with XCTests for both input orders, [] and an unknown value. The second pass gives 5/5 with no finding.
  • CI E2E iOS: ci_run_e2e_ios.sh now runs the StoreKit suite last (66e71c9). Since feat: prepare the bridge for native 6.1.0 (anonymous user id, proxy, Web2App redemption) #153 two suites ran after it, and on the next launch StoreKit returned no usable product, so redemption_identity (R2 allProducts) failed on attempt 1 in every run and passed only on the retry. The script header already said StoreKit runs last. No Dart test or production code changes.
  • Not covered by unit tests: the native success callback and error forwarding of the iOS token sign, and iOS emit (native class methods cannot be stubbed). The Android emit test uses mockkStatic, because emit is @JvmStatic.
  • Local limits: flutter build ios and pod lib lint fail on this Xcode 27 host; a direct xcodebuild build succeeds. E2E runs on CI only.
  • Supersedes feat(privacy): add the refundHandling data processing purpose #162 (closed).

Greptile

Requested: public SDK API (emit, signPromotionalOfferWithToken) and promotional offer signing (payments) in purchasely/lib/purchasely_flutter.dart and the iOS/Android plugins

🤖 Generated with Claude Code

dependabot Bot and others added 12 commits September 14, 2026 00:34
Bumps [org.robolectric:robolectric](https://github.com/robolectric/robolectric) from 4.11.1 to 4.17.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](robolectric/robolectric@robolectric-4.11.1...robolectric-4.17)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-version: '4.17'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps com.android.application from 9.4.0 to 9.4.1.

---
updated-dependencies:
- dependency-name: com.android.application
  dependency-version: 9.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.7.1 to 9.8.0.
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](gradle/gradle@v9.7.1...v9.8.0)

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.21.0 to 5.24.0.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](mockito/mockito@v5.21.0...v5.24.0)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-core
  dependency-version: 5.24.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.6.1 to 9.8.0.
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](gradle/gradle@v9.6.1...v9.8.0)

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
- Create AGENTS.md from CLAUDE.md, verified against the repo at 6.1.1
- Fix the iOS source path, add SwiftPM, extra channels, Dart src/ layout
- Document Flutter/Java/Kotlin versions, minSdk pin and E2E workflows
- Delete CLAUDE.md (AGENTS.md is the single source)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Add signPromotionalOfferWithToken and deprecate signPromotionalOffer, which
signs over the anonymous user id. Android resolves with an empty map.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@kherembourg
kherembourg marked this pull request as ready for review October 8, 2026 17:35
@kherembourg

Copy link
Copy Markdown
Collaborator Author

@greptile review

@greptile-apps

greptile-apps Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[High impact] The PR appears safe to merge, with the previous consent-test finding addressed and no new blocking issue found.

Summary

Releases the three Flutter packages at 6.2.0 with matching native SDK versions, custom events, token-based promotional offer signing, and iOS refund consent support.

  • Adds native consent tests that address the previous review finding.
  • Updates Android build and test dependencies, contributor guidance, and Observer-mode purchase instructions.
  • No new actionable issue was found in the changes since the previous review.
  • kherembourg explicitly retained the copied availability error message because it matches the existing method; the actual guard remains iOS 12.2.

Reviews (2) · Last reviewed commit: "docs: say where the purchase context tok..." · Reviewed by Greptile

Comment thread purchasely/ios/purchasely_flutter/Classes/SwiftPurchaselyFlutterPlugin.swift Outdated
…android/org.robolectric-robolectric-4.17

deps(android): bump org.robolectric:robolectric from 4.11.1 to 4.17 in /purchasely/android
…example/android/com.android.application-9.4.1

deps(android): bump com.android.application from 9.4.0 to 9.4.1 in /purchasely/example/android
…android/gradle-wrapper-9.8.0

deps(android): bump gradle-wrapper from 9.7.1 to 9.8.0 in /purchasely/android
…android/org.mockito-mockito-core-5.24.0

deps(android): bump org.mockito:mockito-core from 5.21.0 to 5.24.0 in /purchasely/android
…example/android/gradle-wrapper-9.8.0

deps(android): bump gradle-wrapper from 9.6.1 to 9.8.0 in /purchasely/example/android

Copilot AI left a comment

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.

🔵 Needs a closer look

The purchase-signing success and failure callbacks lack automated coverage and need final human validation.

1 open finding
What changed in this PR

Releases Purchasely Flutter SDK 6.2.0 with custom events, token-based promotional offer signing, and the refund-handling consent support from #162.

Changes:

  • Aligns all packages and native SDK dependencies to 6.2.0.
  • Adds emit, iOS token signing, and refund-handling consent; preserves combined iOS consent purposes.
  • Updates documentation, examples, tests, and Android tooling.
File Description
VERSIONS.md Records native SDK compatibility.
sdk_public_doc.md Documents new APIs and release dependencies.
README.md Updates installation version.
purchasely/​test/​purchasely_flutter_test.dart Tests refund-handling consent mapping.
purchasely/​test/​platform_channel_test.dart Tests new channel methods.
purchasely/​pubspec.yaml Sets version 6.2.0.
purchasely/​lib/​purchasely_flutter.dart Exposes new APIs and consent purpose.
purchasely/​ios/​purchasely_flutter/​Package.swift Pins iOS SDK 6.2.0.
purchasely/​ios/​purchasely_flutter/​Classes/​SwiftPurchaselyFlutterPlugin.swift Implements iOS APIs and consent mapping.
purchasely/​ios/​purchasely_flutter/​Classes/​PLYOfferSignature+ToMap.swift Serializes lowercase purchase tokens.
purchasely/​ios/​purchasely_flutter.podspec Updates plugin and native versions.
purchasely/​example/​pubspec.lock Locks example to plugin 6.2.0.
purchasely/​example/​lib/​main.dart Demonstrates token-based signing.
purchasely/​example/​ios/​RunnerTests/​SwiftPurchaselyFlutterPluginTests.swift Tests token validation and serialization.
purchasely/​example/​ios/​Podfile.lock Locks updated iOS dependencies.
purchasely/​example/​ios/​Podfile Updates dependency comments only.
purchasely/​example/​android/​settings.gradle Updates Android application plugin.
purchasely/​example/​android/​gradle/​wrapper/​gradle-wrapper.properties Updates example Gradle version.
purchasely/​example/​android/​app/​build.gradle Aligns native extension dependencies.
purchasely/​CHANGELOG.md Documents features, deprecation, and consent fix.
purchasely/​android/​src/​test/​kotlin/​io/​purchasely/​purchasely_flutter/​PurchaselyFlutterPluginTest.kt Tests events, signing fallback, and store ordinal.
purchasely/​android/​src/​main/​kotlin/​io/​purchasely/​purchasely_flutter/​PurchaselyFlutterPlugin.kt Adds event forwarding and signing fallback; adopts STRIPE.
purchasely/​android/​gradle/​wrapper/​gradle-wrapper.properties Updates plugin Gradle version.
purchasely/​android/​build.gradle Updates native SDK and test dependencies.
purchasely_google/​pubspec.yaml Sets version 6.2.0.
purchasely_google/​CHANGELOG.md Records extension release.
purchasely_google/​android/​build.gradle Pins Google Play SDK 6.2.0.
purchasely_android_player/​pubspec.yaml Sets version 6.2.0.
purchasely_android_player/​CHANGELOG.md Records extension release.
purchasely_android_player/​android/​build.gradle Pins Player SDK 6.2.0.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@kherembourg kherembourg added the run-ci Trigger the E2E / CI build against the current PR head label Oct 8, 2026
@github-actions github-actions Bot removed the run-ci Trigger the E2E / CI build against the current PR head label Oct 8, 2026
kherembourg and others added 2 commits October 8, 2026 20:21
docs(agents): merge CLAUDE.md into AGENTS.md as single source
Extract the purpose-string mapping into an internal static function so a
native test can pin that combined purposes keep every entry.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@kherembourg kherembourg added the run-ci Trigger the E2E / CI build against the current PR head label Oct 8, 2026
@github-actions github-actions Bot removed the run-ci Trigger the E2E / CI build against the current PR head label Oct 8, 2026
@kherembourg

Copy link
Copy Markdown
Collaborator Author

@greptile review

redemption_identity failed attempt 1 in every E2E iOS run since abb0008
appended it after the StoreKit suite: the first plain launch after the
SKTestSession run got an empty App Store catalogue, so allProducts failed
with "Unable to find the product." It passed on attempt 2, and the same
call passes in batch 1 (T5) and in proxy_invalid.

The runner header already says the StoreKit suite runs last. Move it back
to the end, after redemption_identity and proxy_invalid. Side effect:
those two suites now get the 300s TIMEOUT, not the 600s STOREKIT_TIMEOUT
that leaked into them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kherembourg kherembourg added the run-ci Trigger the E2E / CI build against the current PR head label Oct 8, 2026
@greptile-apps

greptile-apps Bot commented Oct 8, 2026

Copy link
Copy Markdown

Automatic reviews are disabled for this repository.

@github-actions github-actions Bot removed the run-ci Trigger the E2E / CI build against the current PR head label Oct 8, 2026
kherembourg and others added 3 commits October 9, 2026 11:11
Take the icon from purchasely.com (512 px, resized to 256 px) and fix the root README path, which pointed to a file that does not exist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The bridge tests its own code, the format of each call to the native SDK, and the completion it can see. The native SDK tests what it does after the call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kherembourg kherembourg added the run-ci Trigger the E2E / CI build against the current PR head label Oct 9, 2026
@github-actions github-actions Bot removed the run-ci Trigger the E2E / CI build against the current PR head label Oct 9, 2026
@kherembourg
kherembourg merged commit 8499366 into main Oct 9, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants