feat!: mParticle SDK v9, Shoppable Ads, Rokt payment extension & placement events#84
Conversation
PR SummaryHigh Risk Overview Rokt JS surface (additive): Integrator/docs/example: Large README Rokt section; example wires payment extension, Swift Reviewed by Cursor Bugbot for commit f003727. Bugbot is set up for automated code reviews on this repo. Configure here. |
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ension (#93) * chore: bump native deps to mParticle-Apple-SDK 9.2 / android-core 5.79.0 Aligns the Cordova plugin's pinned native versions with what the sibling RN and Flutter wrappers shipped at the same release line: - iOS `mParticle-Apple-SDK` ~> 9.0 → ~> 9.2 - iOS `mParticle-Rokt` ~> 9.0 → ~> 9.2 - Android `android-core` 5.71.0 → 5.79.0 - Android `android-rokt-kit` 5.71.0 → 5.79.0 - README Podfile note bumped to 9.2.0 or later Apple SDK 9.2 widens the MPRokt surface (registerPaymentExtension:, handleURLCallback:, setSessionId:/getSessionId, expanded RoktEvent hierarchy) and stops the partner from having to thread stripeKey through Cordova JS — the Rokt kit now reads stripePublishableKey from kit configuration in the mParticle dashboard. Follow-up commits in this branch bridge the new methods and rename the Stripe-named payment kit to the unified RoktPaymentExtension. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor: rename Rokt Stripe payment kit to unified RoktPaymentExtension `RoktStripePaymentExtension 0.1.x` was the Stripe-only iOS Rokt payment extension. Upstream Rokt has since unified its providers into a single `RoktPaymentExtension` package (`~> 2.0`) that internally routes to Stripe for Apple Pay / card / Afterpay / Clearpay / PayPal — partner code no longer needs to pick a provider at integration time. - `Kits/RoktStripePayment/` → `Kits/RoktPaymentExtension/` - npm + Cordova id `@mparticle/cordova-rokt-stripe-payment-kit` → `@mparticle/cordova-rokt-payment-extension` - pod `RoktStripePaymentExtension ~> 0.1` → `RoktPaymentExtension ~> 2.0` - `example/config.xml` plugin reference updated to the new id / path - `example/platform_overrides/ios/RoktPaymentSetup.swift` imports the unified module and constructs `RoktPaymentExtension(applePayMerchantId:)` instead of `RoktStripePaymentExtension(applePayMerchantId:)`. - AppDelegate comment + copy-hook comment updated. The Swift helper still calls `MParticle.sharedInstance().rokt.register(_:)` (which is the Swift form of `[[MParticle sharedInstance].rokt registerPaymentExtension:]`). The Rokt kit on mParticle Apple SDK 9.2 pulls `stripePublishableKey` from kit configuration in the mParticle dashboard and forwards it to Rokt at registration time, so the host app only needs to provide the Apple Pay merchant identifier. README still references the old Stripe-named symbols — fixed in the docs commit later in this branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: bridge setSessionId / getSessionId / handleURLCallback on Rokt mParticle Apple SDK 9.2 widened MPRokt with three pass-through APIs that the Cordova bridge can now forward: - `setSessionId:` / `-getSessionId` — let JS share a session id with a WebView leg of the same flow, matching the standalone Rokt SDK and the React Native wrapper. - `handleURLCallback:` — receive deep-link return URLs from redirect-based Rokt payment methods (AfterPay, PayPal) and ask the registered payment extension(s) to claim them. Returns BOOL so the host can fall back to its own URL routing on no-claim. `registerPaymentExtension:` is intentionally NOT exposed in JS. The concrete extension class has a Swift failable initializer that isn't `@objc`-exported, so partners need a Swift bridge file in their app target anyway; once they have it, registering from AppDelegate is one line. A JS API would only add plumbing without removing the native setup, encourage per-call registration footguns, and diverge from how the RN and Flutter wrappers handle it. - iOS: real selectors against `[[MParticle sharedInstance].rokt …]`. - Android: `setSessionId` and `getSessionId` are real calls (`MParticle.getInstance().Rokt().setSessionId / .getSessionId`); `handleURLCallback` is a logged no-op matching the RN/Flutter pattern until the Android SDK ships the same API. - JS: `setSessionId` is fire-and-forget, `getSessionId` and `handleURLCallback` accept a completion that receives the session-id string and a BOOL `handled`, respectively. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: align README + CHANGELOG with 9.2 / unified payment-extension flow README's Shoppable Ads section was wired up against the old Stripe-named plugin (`@mparticle/cordova-rokt-stripe-payment-kit`, `RoktStripePaymentExtension`). Rewrite it for the unified `@mparticle/cordova-rokt-payment-extension` kit and quote the Swift bridge example partners need in their app target. - Step 1: install the unified payment-extension kit instead of the Stripe-named one. - Step 2: full Swift bridge snippet (RoktPaymentSetup.swift) plus the AppDelegate call. Notes that the Rokt kit on mParticle Apple SDK 9.2 reads `stripePublishableKey` from the mParticle dashboard, so partners no longer need to ship a Stripe key from JS. - New step 4 covers `handleURLCallback` for redirect-based payments (AfterPay, PayPal). - New step 5 covers `setSessionId` / `getSessionId` for WebView session continuity. - CHANGELOG `[Unreleased]` documents the three native bumps, the Stripe → unified rename, and the three new bridged JS methods. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: wire example app for Shoppable Ads testing Register the unified Rokt payment extension in the example AppDelegate, randomize the selectShoppableAds confirmation ref / email per tap so Rokt's dedup doesn't suppress repeat requests during local testing, and disable the response cache. Adds patched mParticle 9.2 podspecs that bump the RoktContracts requirement to ~> 1.0 so the example resolves cleanly against current Rokt-Widget. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address review feedback and fix red example CI on Shoppable Ads 9.2 - Sync example/package-lock.json with package.json so `npm ci` passes (was missing @mparticle/cordova-rokt-payment-extension → EUSAGE, failing both example build jobs before any build ran). - Remove orphaned patched-podspecs (pinned 9.0.1, violating the plugin's ~> 9.2 constraint). Published mParticle-Apple-SDK 9.2.0 already declares RoktContracts (~> 2.0), so a clean pod install resolves to RoktContracts 2.0.2 / RoktPaymentExtension 2.0.3 with no overrides. Verified end-to-end: example builds on cordova-ios 7.1.1, Rokt kit 9.2.0 inits, payment extension registers, selectShoppableAds renders. - Remove the 'Strip before commit' globalEvents diagnostic from the example AppDelegate. - Use file: prefix for the cordova-rokt-payment-extension dev dependency. - Bump android-core / android-rokt-kit to 5.79.1 (latest stable 5.x). Addresses all three Cursor Bugbot comments on #93. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: James Newman <james.newman@rokt.com>
Add mparticle.Rokt.events(identifier, onEvent) — a standalone subscriber mirroring the native events API shape (not folded into selectPlacements) — plus mparticle.Rokt.EventType constants. iOS (CDVMParticle.m): roktEvents: forwards to MPRokt events:onEvent:; dictionaryFromRoktEvent: serializes every RoktEvent subclass from RoktContracts 2.0.2 to a dict and streams via CDVPluginResult with setKeepCallback:YES for multi-shot delivery. Android (MParticleCordovaPlugin.java): roktEvents subscribes to the events(identifier) Flow via onEach/launchIn, serializes each event to JSON, and streams with keepCallback. Each placement's collection scope is tracked in a map keyed by identifier: re-subscribing the same identifier cancels the prior scope instead of stacking a second collector, and onDestroy cancels every active scope so collectors stop running and never deliver through a callbackContext bound to a destroyed WebView. README + example: Placement Events section and a Subscribe to Events button. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
There are 6 total unresolved issues (including 4 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 61277b8. Configure here.
- Android selectShoppableAds/purchaseFinalized now accept a callbackContext and send a PluginResult, so the JS promises resolve instead of dangling (#3). - purchaseFinalized is a no-op + warning on Android, matching selectShoppableAds (unsupported) and handleURLCallback — avoids calling the Rokt SDK with no active shoppable session (#2). - Quote iosPath/script path in the platform-add hook so project roots containing spaces don't break `cordova platform add ios` (#1). - Make configure_xcode_swift.rb idempotent: reuse an existing RoktPaymentSetup.swift reference and skip re-adding it, so re-runs don't create duplicate compile sources (#5). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lease flow (#95) The release workflow only ever versioned/published the plugin and Rokt kit, leaving two gaps: - CDVMParticle.m reported an empty wrapper version to mParticle (_setWrapperSdk_internal version:@""). Seed it with the current version and add a release-workflow step that bumps it alongside plugin.xml, so it tracks every release instead of going stale. - Kits/RoktPaymentExtension (new this release) was not managed by the release flow at all, so it had drifted to 3.0.0 and would never be version-bumped or published. Add version-bump + plugin.xml + dry-run-publish steps mirroring the Rokt kit, align it to 3.0.1, and list the extra files in the release PR body. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md # example/package-lock.json

Background
Long-running feature branch merging into
main. It bundles the previously reviewed work plus follow-up hardening:CDVMParticle.mv9 API changes, Android target-dir fix, CI JDK fix.selectShoppableAds/purchaseFinalizedAPIs and the unifiedRoktPaymentExtensionkit (replacing the Stripe-specific kit), example app + README.Rokt.events(identifier, onEvent)+Rokt.EventType.dd86530) — AndroidselectShoppableAds/purchaseFinalizednow resolve their JS callbacks;purchaseFinalizedis a safe no-op on Android (no shoppable session to finalize); the platform-add hook quotes paths (spaces in project root); the Xcode Swift hook is idempotent (no duplicate compile sources on re-run).RoktPaymentExtensionkit is version-bumped and dry-run-published by the release workflow (it was previously unmanaged).Raises the iOS minimum deployment target to 15.6 — apps below 15.6 cannot adopt this release. Driven by the native upgrade to mParticle Apple SDK v9 / Rokt kit v9 (from v8). iOS integrators must also adopt the renamed RoktPaymentExtension kit and the AppDelegate registration pattern. Android native deps are only a minor bump (
android-core/rokt-kit5.71.0 → 5.79.1).The plugin's own JS/Cordova API is otherwise backward compatible — all surface changes are additive.
What's new (JS API)
Rokt.selectShoppableAds,Rokt.purchaseFinalized(iOS; Android no-op + warning for now)@mparticle/cordova-rokt-payment-extension(replaces the Stripe-specific kit, which never shipped tomain)Rokt.setSessionId/getSessionId/handleURLCallbackRokt.events(identifier, onEvent)+Rokt.EventTypeRokt.ColorModeconfigVerification
ShowLoadingIndicator → HideLoadingIndicator → PlacementReady → PlacementInteractivedelivered to the JS callback, overlay rendered interactively.Notes
selectShoppableAds/purchaseFinalized) is not yet supported — no-op + warning.draft-release-publish.yml, major bump).Reference Issue (For employees only. Ignore if you are an outside contributor)