Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Fetching and Redeeming Win-Back Offers on Custom Paywall #1134

Merged
merged 9 commits into from
Dec 2, 2024

Conversation

fire-at-will
Copy link
Contributor

@fire-at-will fire-at-will commented Nov 25, 2024

This PR exposes four new functions to allow developers to fetch & redeem win-back offers that a subscriber is eligible for in their custom paywalls. These functions only function on iOS 18.0+ and require StoreKit 2 to be used.

Fetching Eligible Win-Back Offers

public static async getEligibleWinBackOffersForProduct(
    product: PurchasesStoreProduct
  ): Promise<[PurchasesWinBackOffer] | undefined>

public static async getEligibleWinBackOffersForPackage(
    aPackage: PurchasesPackage
  ): Promise<[PurchasesWinBackOffer] | undefined>

Redeeming Win-Back Offers

public static async purchaseProductWithWinBackOffer(
    product: PurchasesStoreProduct,
    winBackOffer: PurchasesWinBackOffer
  ): Promise<MakePurchaseResult>

public static async purchasePackageWithWinBackOffer(
    aPackage: PurchasesPackage,
    winBackOffer: PurchasesWinBackOffer
  ): Promise<MakePurchaseResult>

Other Changes

The PurchaseTester app was updated with a new screen to support testing these flows

Testing

All flows were tested manually through the new screen in the PurchaseTester app.

@fire-at-will fire-at-will added the pr:feat A new feature label Nov 25, 2024
@fire-at-will fire-at-will self-assigned this Nov 25, 2024
@fire-at-will fire-at-will marked this pull request as ready for review November 25, 2024 17:23
@fire-at-will fire-at-will requested review from MarkVillacampa and a team November 25, 2024 17:24
}

return RNPurchases.eligibleWinBackOffersForProductIdentifier(
aPackage.product.identifier
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here, we call the eligibleWinBackOffersForProductIdentifier for the package's product ID. We do this so that we only have to implement the offer caching logic in PHC once instead of twice for both functions

}];
} else {
NSString *description = @"iOS win-back offers are only available on iOS 18.0 or greater.";
NSError *error = [[NSError alloc] initWithDomain:@"RCPurchasesErrorCodeDomain"
Copy link
Member

Choose a reason for hiding this comment

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

I think RCPurchasesErrorCodeDomain should be a symbol reference, not a string.

RCPurchasesErrorCodeDomain is auto-generated in the Objc bridging header in purchases-ios as RevenueCat.ErrorCode from:

https://github.com/RevenueCat/purchases-ios/blob/51dd267dc5e60c59bae90b4413368f9caf030b94/Sources/Error%20Handling/ErrorCode.swift#L20

Copy link
Member

Choose a reason for hiding this comment

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

This might be a good candidate to extract as a helper that builds an "unsupported" error with a custom message

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Love this! Made these changes here: e2f467a

}
}

RCT_EXPORT_METHOD(purchaseProductWithWinBackOffer:(nonnull NSString *)productID
Copy link
Member

Choose a reason for hiding this comment

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

Objc conventions make me think this WithWinBackOffer expect the next parameter to be the winback offer. I think it might be clearer without that part, and it more closely follows the method signature in PHC.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried changing the name of this function to purchaseProduct, but then I started seeing namespace collisions with the other purchaseProduct function:

RNPurchases.purchaseProduct was called with 6 arguments but expects 2 arguments. If you haven't changed this method yourself, this usually means that your versions of the native code and JavaScript code are out of sync. Updating both should make this error go away.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Update in case anyone reads this later: we decided not to make this change since Typescript doesn't have named parameters and since this is an internal API

Copy link
Member

@MarkVillacampa MarkVillacampa left a comment

Choose a reason for hiding this comment

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

Left some minor comments but functionality looks solid 👍

@fire-at-will fire-at-will merged commit d6fdd82 into main Dec 2, 2024
4 checks passed
@fire-at-will fire-at-will deleted the support-redeeming-and-fetching-winbacks branch December 2, 2024 16:17
fire-at-will pushed a commit that referenced this pull request Dec 2, 2024
**This is an automatic release.**

## RevenueCat SDK
### 📦 Dependency Updates
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 13.12.0 (#1136)
via RevenueCat Git Bot (@RCGitBot)
* [Android
8.10.3](https://github.com/RevenueCat/purchases-android/releases/tag/8.10.3)
* [iOS
5.12.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.12.0)
* [iOS
5.11.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.11.0)
* [iOS
5.10.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.10.0)
* [iOS
5.9.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.9.0)
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 13.11.0 (#1133)
via RevenueCat Git Bot (@RCGitBot)
* [Android
8.10.3](https://github.com/RevenueCat/purchases-android/releases/tag/8.10.3)
* [iOS
5.12.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.12.0)
* [iOS
5.11.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.11.0)
* [iOS
5.10.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.10.0)
* [iOS
5.9.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.9.0)
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 13.10.0 (#1132)
via RevenueCat Git Bot (@RCGitBot)
* [Android
8.10.3](https://github.com/RevenueCat/purchases-android/releases/tag/8.10.3)
* [iOS
5.12.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.12.0)
* [iOS
5.11.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.11.0)
* [iOS
5.10.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.10.0)
* [iOS
5.9.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.9.0)
### Win-back Offers
#### ✨ New Features
* Support Fetching and Redeeming Win-Back Offers on Custom Paywall
(#1134) via Will Taylor (@fire-at-will)

---------

Co-authored-by: RevenueCat CI <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants