Skip to content

Add offering_id to custom paywall impression event#3230

Merged
rickvdl merged 2 commits into
mainfrom
rickvdl/add-offering-id-to-custom-paywall-impression-event
Mar 16, 2026
Merged

Add offering_id to custom paywall impression event#3230
rickvdl merged 2 commits into
mainfrom
rickvdl/add-offering-id-to-custom-paywall-impression-event

Conversation

@rickvdl

@rickvdl rickvdl commented Mar 13, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds offering_id field to the custom paywall impression event, populated from the current cached offering identifier
  • Exposes cachedCurrentOfferingIdentifier through OfferingsManager and PurchasesOrchestrator
  • Field is omitted from the JSON payload when no offering is cached

Related PRs

Test plan

  • Unit tests for event creation with and without offering ID
  • Unit tests for backend event conversion with offering ID
  • Unit tests for JSON serialization (key present when set, omitted when null)
  • Unit tests for JSON roundtrip with offering ID

Note

Low Risk
Low risk: this is an additive analytics/event-schema change that threads an optional offering_id through existing custom paywall impression tracking, with unit tests covering serialization and null handling.

Overview
Custom paywall impression tracking now includes an optional offering_id field in the stored/serialized backend event payload.

CustomPaywallImpressionParams gains an offeringId parameter, and Purchases.trackCustomPaywallImpression will default it from the cached current offering identifier when not explicitly provided (plumbed via new cachedCurrentOfferingIdentifier accessors on OfferingsManager/PurchasesOrchestrator). API tester fixtures and unit tests are updated to cover creation, backend conversion, and JSON behavior (key present when set, omitted when null).

Written by Cursor Bugbot for commit a2a1f96. This will update automatically on new commits. Configure here.

@codecov

codecov Bot commented Mar 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.40%. Comparing base (9768055) to head (a2a1f96).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
.../com/revenuecat/purchases/PurchasesOrchestrator.kt 0.00% 1 Missing ⚠️
...cat/purchases/common/offerings/OfferingsManager.kt 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3230      +/-   ##
==========================================
- Coverage   79.41%   79.40%   -0.01%     
==========================================
  Files         356      356              
  Lines       14342    14348       +6     
  Branches     1958     1959       +1     
==========================================
+ Hits        11389    11393       +4     
- Misses       2149     2151       +2     
  Partials      804      804              

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

@rickvdl rickvdl marked this pull request as ready for review March 13, 2026 10:29
@rickvdl rickvdl requested review from a team as code owners March 13, 2026 10:29

@tonidero tonidero 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.

It looks good, just a question. But I think we can add that later if needed.

data = CustomPaywallEvent.Impression.Data(paywallId = params.paywallId),
data = CustomPaywallEvent.Impression.Data(
paywallId = params.paywallId,
offeringId = purchasesOrchestrator.cachedCurrentOfferingIdentifier,

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.

Should we also add the offering as an optional parameter to the CustomPaywallImpressionParams, and if it's null, then we default to the currentOffering? Though this might be more of a question for @borjafv. Probably not needed since as we discussed, experiments should always use the current offering. But might be good to add at some point, depending on how we recommend using this API.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is precisely what I implemented on Friday to be able to test with the released SDK versions that are not sending the offering_id. But still I think the SDK should always have the offering_id and sending it will be better, so not sure if its good to make it optional.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@borjafv I think @tonidero's proposal was to have the parameter be optional, and if not provided by the developer fallback to sending the current offering id. Wdyt?

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.

Indeed, the thought is whether we should allow the developer to pass us the offering. So we could potentially check whether they used the current offering, or used a different one (effectively bypassing the experiment I guess)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Oh yeah that would be great, initially I proposed the developer passing the offering_id 👍

It's great if we allow them to do that and if not the SDK can send the current one.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added :)

rickvdl added 2 commits March 16, 2026 11:47
Pass the cached current offering identifier when tracking custom paywall
impressions. The field is serialized as `offering_id` in the JSON sent
to the backend and is nullable since offerings may not be cached yet.
Adds optional offeringId parameter to CustomPaywallImpressionParams.
If not provided, falls back to the cached current offering identifier.
@rickvdl rickvdl force-pushed the rickvdl/add-offering-id-to-custom-paywall-impression-event branch from 6af4fc5 to a2a1f96 Compare March 16, 2026 10:52
@rickvdl rickvdl requested a review from tonidero March 16, 2026 11:04

@tonidero tonidero 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.

LGTM!

@rickvdl rickvdl added this pull request to the merge queue Mar 16, 2026
Merged via the queue into main with commit 27ebb7b Mar 16, 2026
32 checks passed
@rickvdl rickvdl deleted the rickvdl/add-offering-id-to-custom-paywall-impression-event branch March 16, 2026 11:26
github-merge-queue Bot pushed a commit that referenced this pull request Mar 16, 2026
**This is an automatic release.**

## RevenueCat SDK
### 🐞 Bugfixes
* Fix & Standardize Galaxy Date Parsing Edge Cases (#3216) via Will
Taylor (@fire-at-will)
* Fix addSuccessfullyPostedToken for new purchases in
PostPendingTransactionsHelper (#3239) via Facundo Menzella
(@facumenzella)
* [Galaxy]: Fix race condition when fetching Galaxy products (#3213) via
Will Taylor (@fire-at-will)
* Fixes double padding in PaywallActivity on Android 15+ when
`edgeToEdge` parameter is false (#3227) via Cesar de la Vega (@vegaro)

## RevenueCatUI SDK
### 🐞 Bugfixes
* Fix bold text not rendering in Markdown lists (#3228) via Cesar de la
Vega (@vegaro)
* Fix: Clear in-memory offerings cache on locale override to prevent
stale paywall data (#3225) via Antonio Pallares (@ajpallares)
### Paywallv2
#### ✨ New Features
* Feature: Update default paywall (#3133) via Jacob Rakidzich
(@JZDesign)
#### 🐞 Bugfixes
* Fix V2 paywall safe area in landscape mode (#3221) via Cesar de la
Vega (@vegaro)

### 🔄 Other Changes
* Run integration tests on all branches (#3242) via Toni Rico
(@tonidero)
* Migrate Firebase Test Lab jobs to CircleCI emulators (#3238) via Toni
Rico (@tonidero)
* Run metalava on galaxy module in test-galaxy job (#3235) via Will
Taylor (@fire-at-will)
* Add offering_id to custom paywall impression event (#3230) via Rick
(@rickvdl)
* Cache isAutoRenewing to detect subscription changes without
syncPurchases (#3198) via Facundo Menzella (@facumenzella)
* Bump fastlane-plugin-revenuecat_internal from `e146447` to `3e8c384`
(#3233) via dependabot[bot] (@dependabot[bot])

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk release housekeeping: version string bumps and
documentation/deployment path updates with no functional runtime logic
changes beyond the exposed version constant.
> 
> **Overview**
> Publishes the `9.26.0` release by removing `-SNAPSHOT` across
build/version metadata (root `VERSION_NAME`, `.version`,
`Config.frameworkVersion`, and sample/test app dependency pins).
> 
> Updates release documentation artifacts by adding the `9.26.0` notes
to `CHANGELOG.md`/`CHANGELOG.latest.md`, switching docs deployment in
CircleCI to sync `docs/9.26.0` to S3, and updating `docs/index.html` to
redirect to the new version.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0a30a45. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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.

3 participants