UNPKG

react-native-purchases

Version:

React Native in-app purchases and subscriptions made easy. Supports iOS and Android.

834 lines 95.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.STOREKIT_VERSION = exports.LOG_LEVEL = exports.REFUND_REQUEST_STATUS = exports.BILLING_FEATURE = exports.PURCHASES_ARE_COMPLETED_BY_TYPE = exports.PURCHASE_TYPE = void 0; var react_native_1 = require("react-native"); var purchases_typescript_internal_1 = require("@revenuecat/purchases-typescript-internal"); // This export is kept to keep backwards compatibility to any possible users using this file directly var purchases_typescript_internal_2 = require("@revenuecat/purchases-typescript-internal"); Object.defineProperty(exports, "PURCHASE_TYPE", { enumerable: true, get: function () { return purchases_typescript_internal_2.PURCHASE_TYPE; } }); Object.defineProperty(exports, "PURCHASES_ARE_COMPLETED_BY_TYPE", { enumerable: true, get: function () { return purchases_typescript_internal_2.PURCHASES_ARE_COMPLETED_BY_TYPE; } }); Object.defineProperty(exports, "BILLING_FEATURE", { enumerable: true, get: function () { return purchases_typescript_internal_2.BILLING_FEATURE; } }); Object.defineProperty(exports, "REFUND_REQUEST_STATUS", { enumerable: true, get: function () { return purchases_typescript_internal_2.REFUND_REQUEST_STATUS; } }); Object.defineProperty(exports, "LOG_LEVEL", { enumerable: true, get: function () { return purchases_typescript_internal_2.LOG_LEVEL; } }); Object.defineProperty(exports, "STOREKIT_VERSION", { enumerable: true, get: function () { return purchases_typescript_internal_2.STOREKIT_VERSION; } }); var react_native_2 = require("react-native"); var RNPurchases = react_native_1.NativeModules.RNPurchases; var eventEmitter = new react_native_1.NativeEventEmitter(RNPurchases); var customerInfoUpdateListeners = []; var shouldPurchasePromoProductListeners = []; var customLogHandler; eventEmitter.addListener("Purchases-CustomerInfoUpdated", function (customerInfo) { customerInfoUpdateListeners.forEach(function (listener) { return listener(customerInfo); }); }); eventEmitter.addListener("Purchases-ShouldPurchasePromoProduct", function (_a) { var callbackID = _a.callbackID; shouldPurchasePromoProductListeners.forEach(function (listener) { return listener(function () { return RNPurchases.makeDeferredPurchase(callbackID); }); }); }); eventEmitter.addListener("Purchases-LogHandlerEvent", function (_a) { var logLevel = _a.logLevel, message = _a.message; var logLevelEnum = purchases_typescript_internal_1.LOG_LEVEL[logLevel]; customLogHandler(logLevelEnum, message); }); var Purchases = /** @class */ (function () { function Purchases() { } /** * Sets up Purchases with your API key and an app user id. * @param {String} apiKey RevenueCat API Key. Needs to be a String * @param {String?} appUserID An optional unique id for identifying the user. Needs to be a string. * @param {PurchasesAreCompletedBy} [purchasesAreCompletedBy=PURCHASES_ARE_COMPLETED_BY_TYPE.REVENUECAT] Set this to an instance of PurchasesAreCompletedByMyApp if you have your own IAP implementation and want to use only RevenueCat's backend. Default is PURCHASES_ARE_COMPLETED_BY_TYPE.REVENUECAT. * @param {STOREKIT_VERSION} [storeKitVersion=DEFAULT] iOS-only. Defaults to STOREKIT_2. StoreKit 2 is only available on iOS 16+. StoreKit 1 will be used for previous iOS versions regardless of this setting. * @param {ENTITLEMENT_VERIFICATION_MODE} [entitlementVerificationMode=ENTITLEMENT_VERIFICATION_MODE.DISABLED] Sets the entitlement verifciation mode to use. For more details, check https://rev.cat/trusted-entitlements * @param {boolean} [useAmazon=false] An optional boolean. Android-only. Set this to true to enable Amazon on compatible devices. * @param {String?} userDefaultsSuiteName An optional string. iOS-only, will be ignored for Android. * Set this if you would like the RevenueCat SDK to store its preferences in a different NSUserDefaults suite, otherwise it will use standardUserDefaults. * Default is null, which will make the SDK use standardUserDefaults. * @param {boolean} [pendingTransactionsForPrepaidPlansEnabled=false] An optional boolean. Android-only. Set this to true to enable pending transactions for prepaid subscriptions in Google Play. * @param {boolean} [diagnosticsEnabled=false] An optional boolean. Set this to true to enable SDK diagnostics. * * @warning If you use purchasesAreCompletedBy=PurchasesAreCompletedByMyApp, you must also provide a value for storeKitVersion. */ Purchases.configure = function (_a) { var apiKey = _a.apiKey, _b = _a.appUserID, appUserID = _b === void 0 ? null : _b, _c = _a.purchasesAreCompletedBy, purchasesAreCompletedBy = _c === void 0 ? purchases_typescript_internal_1.PURCHASES_ARE_COMPLETED_BY_TYPE.REVENUECAT : _c, userDefaultsSuiteName = _a.userDefaultsSuiteName, _d = _a.storeKitVersion, storeKitVersion = _d === void 0 ? purchases_typescript_internal_1.STOREKIT_VERSION.DEFAULT : _d, _e = _a.useAmazon, useAmazon = _e === void 0 ? false : _e, _f = _a.shouldShowInAppMessagesAutomatically, shouldShowInAppMessagesAutomatically = _f === void 0 ? true : _f, _g = _a.entitlementVerificationMode, entitlementVerificationMode = _g === void 0 ? purchases_typescript_internal_1.ENTITLEMENT_VERIFICATION_MODE.DISABLED : _g, _h = _a.pendingTransactionsForPrepaidPlansEnabled, pendingTransactionsForPrepaidPlansEnabled = _h === void 0 ? false : _h, _j = _a.diagnosticsEnabled, diagnosticsEnabled = _j === void 0 ? false : _j; if (apiKey === undefined || typeof apiKey !== "string") { throw new Error('Invalid API key. It must be called with an Object: configure({apiKey: "key"})'); } if (appUserID !== null && typeof appUserID !== "undefined" && typeof appUserID !== "string") { throw new Error("appUserID needs to be a string"); } var purchasesCompletedByToUse = purchases_typescript_internal_1.PURCHASES_ARE_COMPLETED_BY_TYPE.REVENUECAT; var storeKitVersionToUse = storeKitVersion; if (Purchases.isPurchasesAreCompletedByMyApp(purchasesAreCompletedBy)) { purchasesCompletedByToUse = purchases_typescript_internal_1.PURCHASES_ARE_COMPLETED_BY_TYPE.MY_APP; storeKitVersionToUse = purchasesAreCompletedBy.storeKitVersion; if (storeKitVersion !== purchases_typescript_internal_1.STOREKIT_VERSION.DEFAULT && storeKitVersionToUse !== storeKitVersion) { // Typically, console messages aren't used in TS libraries, but in this case it's worth calling out the difference in // StoreKit versions, and since the difference isn't possible farther down the call chain, we should go ahead // and log it here. // tslint:disable-next-line:no-console console.warn("Warning: The storeKitVersion in purchasesAreCompletedBy does not match the function's storeKitVersion parameter. We will use the value found in purchasesAreCompletedBy."); } if (storeKitVersionToUse === purchases_typescript_internal_1.STOREKIT_VERSION.DEFAULT) { // tslint:disable-next-line:no-console console.warn("Warning: You should provide the specific StoreKit version you're using in your implementation when configuring PURCHASES_ARE_COMPLETED_BY_TYPE.MY_APP, and not rely on the DEFAULT."); } } RNPurchases.setupPurchases(apiKey, appUserID, purchasesCompletedByToUse, userDefaultsSuiteName, storeKitVersionToUse, useAmazon, shouldShowInAppMessagesAutomatically, entitlementVerificationMode, pendingTransactionsForPrepaidPlansEnabled, diagnosticsEnabled); }; /** * @deprecated, configure behavior through the RevenueCat dashboard (app.revenuecat.com) instead. * If an user tries to purchase a product that is active on the current app store account, * we will treat it as a restore and alias the new ID with the previous id. * If you have configured the Legacy restore behavior in the RevenueCat dashboard * and are currently setting this to true, keep this setting active. * @param {boolean} allowSharing Set this to true if you are passing in an appUserID but it is anonymous, * this is true by default if you didn't pass an appUserID * @returns {Promise<void>} The promise will be rejected if configure has not been called yet. */ Purchases.setAllowSharingStoreAccount = function (allowSharing) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); RNPurchases.setAllowSharingStoreAccount(allowSharing); return [2 /*return*/]; } }); }); }; /** * iOS only. * @param {boolean} simulatesAskToBuyInSandbox Set this property to true *only* when testing the ask-to-buy / SCA * purchases flow. More information: http://errors.rev.cat/ask-to-buy * @returns {Promise<void>} The promise will be rejected if configure has not been called yet. */ Purchases.setSimulatesAskToBuyInSandbox = function (simulatesAskToBuyInSandbox) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { if (react_native_2.Platform.OS === "ios") { RNPurchases.setSimulatesAskToBuyInSandbox(simulatesAskToBuyInSandbox); } return [2 /*return*/]; }); }); }; /** * Sets a function to be called on updated customer info * @param {CustomerInfoUpdateListener} customerInfoUpdateListener CustomerInfo update listener */ Purchases.addCustomerInfoUpdateListener = function (customerInfoUpdateListener) { if (typeof customerInfoUpdateListener !== "function") { throw new Error("addCustomerInfoUpdateListener needs a function"); } customerInfoUpdateListeners.push(customerInfoUpdateListener); }; /** * Removes a given CustomerInfoUpdateListener * @param {CustomerInfoUpdateListener} listenerToRemove CustomerInfoUpdateListener reference of the listener to remove * @returns {boolean} True if listener was removed, false otherwise */ Purchases.removeCustomerInfoUpdateListener = function (listenerToRemove) { if (customerInfoUpdateListeners.includes(listenerToRemove)) { customerInfoUpdateListeners = customerInfoUpdateListeners.filter(function (listener) { return listenerToRemove !== listener; }); return true; } return false; }; /** * Sets a function to be called on purchases initiated on the Apple App Store. This is only used in iOS. * @param {ShouldPurchasePromoProductListener} shouldPurchasePromoProductListener Called when a user initiates a * promotional in-app purchase from the App Store. If your app is able to handle a purchase at the current time, run * the deferredPurchase function. If the app is not in a state to make a purchase: cache the deferredPurchase, then * call the deferredPurchase when the app is ready to make the promotional purchase. * If the purchase should never be made, you don't need to ever call the deferredPurchase and the app will not * proceed with promotional purchases. */ Purchases.addShouldPurchasePromoProductListener = function (shouldPurchasePromoProductListener) { if (typeof shouldPurchasePromoProductListener !== "function") { throw new Error("addShouldPurchasePromoProductListener needs a function"); } shouldPurchasePromoProductListeners.push(shouldPurchasePromoProductListener); }; /** * Removes a given ShouldPurchasePromoProductListener * @param {ShouldPurchasePromoProductListener} listenerToRemove ShouldPurchasePromoProductListener reference of * the listener to remove * @returns {boolean} True if listener was removed, false otherwise */ Purchases.removeShouldPurchasePromoProductListener = function (listenerToRemove) { if (shouldPurchasePromoProductListeners.includes(listenerToRemove)) { shouldPurchasePromoProductListeners = shouldPurchasePromoProductListeners.filter(function (listener) { return listenerToRemove !== listener; }); return true; } return false; }; /** * Gets the map of entitlements -> offerings -> products * @returns {Promise<PurchasesOfferings>} Promise of entitlements structure. The promise will be rejected if configure * has not been called yet. */ Purchases.getOfferings = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.getOfferings()]; } }); }); }; /** * Retrieves a current offering for a placement identifier, use this to access offerings defined by targeting * placements configured in the RevenueCat dashboard. * @param {String} placementIdentifier The placement identifier to fetch a current offeringn for * @returns {Promise<PurchasesOffering | null>} Promise of an optional offering. The promise will be rejected if configure * has not been called yet. */ Purchases.getCurrentOfferingForPlacement = function (placementIdentifier) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.getCurrentOfferingForPlacement(placementIdentifier)]; } }); }); }; /** * Syncs subscriber attributes and then fetches the configured offerings for this user. This method is intended to * be called when using Targeting Rules with Custom Attributes. Any subscriber attributes should be set before * calling this method to ensure the returned offerings are applied with the latest subscriber attributes. * @returns {Promise<PurchasesOfferings>} Promise of entitlements structure. The promise will be rejected if configure * has not been called yet. */ Purchases.syncAttributesAndOfferingsIfNeeded = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.syncAttributesAndOfferingsIfNeeded()]; } }); }); }; /** * Fetch the product info * @param {String[]} productIdentifiers Array of product identifiers * @param {String} type Optional type of products to fetch, can be SUBSCRIPTION or NON_SUBSCRIPTION. SUBSCRIPTION by default * @returns {Promise<PurchasesStoreProduct[]>} A promise containing an array of products. The promise will be rejected * if the products are not properly configured in RevenueCat or if there is another error retrieving them. * Rejections return an error code, and a userInfo object with more information. The promise will also be rejected * if configure has not been called yet. */ Purchases.getProducts = function (productIdentifiers_1) { return __awaiter(this, arguments, void 0, function (productIdentifiers, type) { if (type === void 0) { type = purchases_typescript_internal_1.PRODUCT_CATEGORY.SUBSCRIPTION; } return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.getProductInfo(productIdentifiers, type)]; } }); }); }; /** * Make a purchase * * @param {String} productIdentifier The product identifier of the product you want to purchase * @param {UpgradeInfo} upgradeInfo Android only. Optional UpgradeInfo you wish to upgrade from containing the oldSKU * and the optional prorationMode. * @param {String} type Optional type of product, can be inapp or subs. Subs by default * @deprecated, use purchaseStoreProduct instead */ Purchases.purchaseProduct = function (productIdentifier_1, upgradeInfo_1) { return __awaiter(this, arguments, void 0, function (productIdentifier, upgradeInfo, type) { if (type === void 0) { type = purchases_typescript_internal_1.PURCHASE_TYPE.SUBS; } return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.purchaseProduct(productIdentifier, upgradeInfo, type, null, null, null).catch(function (error) { error.userCancelled = error.code === purchases_typescript_internal_1.PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; })]; } }); }); }; /** * Make a purchase * * @param {PurchasesStoreProduct} product The product you want to purchase * @param {GoogleProductChangeInfo} googleProductChangeInfo Android only. Optional GoogleProductChangeInfo you * wish to upgrade from containing the oldProductIdentifier and the optional prorationMode. * @param {boolean} googleIsPersonalizedPrice Android and Google only. Optional boolean indicates personalized pricing on products available for purchase in the EU. * For compliance with EU regulations. User will see "This price has been customize for you" in the purchase dialog when true. * See https://developer.android.com/google/play/billing/integrate#personalized-price for more info. * @returns {Promise<{ productIdentifier: string, customerInfo:CustomerInfo }>} A promise of an object containing * a customer info object and a product identifier. Rejections return an error code, * a boolean indicating if the user cancelled the purchase, and an object with more information. The promise will * also be rejected if configure has not been called yet. */ Purchases.purchaseStoreProduct = function (product, googleProductChangeInfo, googleIsPersonalizedPrice) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.purchaseProduct(product.identifier, googleProductChangeInfo, product.productCategory, null, googleIsPersonalizedPrice == null ? null : { isPersonalizedPrice: googleIsPersonalizedPrice }, product.presentedOfferingContext).catch(function (error) { error.userCancelled = error.code === purchases_typescript_internal_1.PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; })]; } }); }); }; /** * iOS only. Purchase a product applying a given discount. * * @param {PurchasesStoreProduct} product The product you want to purchase * @param {PurchasesPromotionalOffer} discount Discount to apply to this package. Retrieve this discount using getPromotionalOffer. * @param {boolean} googleIsPersonalizedPrice Android and Google only. Optional boolean indicates personalized pricing on products available for purchase in the EU. * For compliance with EU regulations. User will see "This price has been customize for you" in the purchase dialog when true. * See https://developer.android.com/google/play/billing/integrate#personalized-price for more info. * @returns {Promise<{ productIdentifier: string, customerInfo:CustomerInfo }>} A promise of an object containing * a customer info object and a product identifier. Rejections return an error code, * a boolean indicating if the user cancelled the purchase, and an object with more information. The promise will be * rejected if configure has not been called yet. */ Purchases.purchaseDiscountedProduct = function (product, discount) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); if (typeof discount === "undefined" || discount == null) { throw new Error("A discount is required"); } return [2 /*return*/, RNPurchases.purchaseProduct(product.identifier, null, null, discount.timestamp.toString(), null, product.presentedOfferingContext).catch(function (error) { error.userCancelled = error.code === purchases_typescript_internal_1.PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; })]; } }); }); }; /** * Make a purchase * * @param {PurchasesPackage} aPackage The Package you wish to purchase. You can get the Packages by calling getOfferings * @param {UpgradeInfo} upgradeInfo DEPRECATED. Use googleProductChangeInfo. * @param {GoogleProductChangeInfo} googleProductChangeInfo Android only. Optional GoogleProductChangeInfo you * wish to upgrade from containing the oldProductIdentifier and the optional prorationMode. * @param {boolean} googleIsPersonalizedPrice Android and Google only. Optional boolean indicates personalized pricing on products available for purchase in the EU. * For compliance with EU regulations. User will see "This price has been customize for you" in the purchase dialog when true. * See https://developer.android.com/google/play/billing/integrate#personalized-price for more info. * @returns {Promise<{ productIdentifier: string, customerInfo: CustomerInfo }>} A promise of an object containing * a customer info object and a product identifier. Rejections return an error code, a boolean indicating if the * user cancelled the purchase, and an object with more information. The promise will be also be rejected if configure * has not been called yet. */ Purchases.purchasePackage = function (aPackage, upgradeInfo, googleProductChangeInfo, googleIsPersonalizedPrice) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.purchasePackage(aPackage.identifier, aPackage.presentedOfferingContext, googleProductChangeInfo || upgradeInfo, null, googleIsPersonalizedPrice == null ? null : { isPersonalizedPrice: googleIsPersonalizedPrice }).catch(function (error) { error.userCancelled = error.code === purchases_typescript_internal_1.PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; })]; } }); }); }; /** * Google only. Make a purchase of a subscriptionOption * * @param {SubscriptionOption} subscriptionOption The SubscriptionOption you wish to purchase. You can get the SubscriptionOption from StoreProducts by calling getOfferings * @param {GoogleProductChangeInfo} googleProductChangeInfo Android only. Optional GoogleProductChangeInfo you * wish to upgrade from containing the oldProductIdentifier and the optional prorationMode. * @param {boolean} googleIsPersonalizedPrice Android and Google only. Optional boolean indicates personalized pricing on products available for purchase in the EU. * For compliance with EU regulations. User will see "This price has been customize for you" in the purchase dialog when true. * See https://developer.android.com/google/play/billing/integrate#personalized-price for more info. * @returns {Promise<{ productIdentifier: string, customerInfo: CustomerInfo }>} A promise of an object containing * a customer info object and a product identifier. Rejections return an error code, a boolean indicating if the * user cancelled the purchase, and an object with more information. The promise will be also be rejected if configure * has not been called yet. */ Purchases.purchaseSubscriptionOption = function (subscriptionOption, googleProductChangeInfo, googleIsPersonalizedPrice) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [4 /*yield*/, Purchases.throwIfIOSPlatform()]; case 2: _a.sent(); return [2 /*return*/, RNPurchases.purchaseSubscriptionOption(subscriptionOption.productId, subscriptionOption.id, googleProductChangeInfo, null, googleIsPersonalizedPrice == null ? null : { isPersonalizedPrice: googleIsPersonalizedPrice }, subscriptionOption.presentedOfferingContext).catch(function (error) { error.userCancelled = error.code === purchases_typescript_internal_1.PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; })]; } }); }); }; /** * iOS only. Purchase a package applying a given discount. * * @param {PurchasesPackage} aPackage The Package you wish to purchase. You can get the Packages by calling getOfferings * @param {PurchasesPromotionalOffer} discount Discount to apply to this package. Retrieve this discount using getPromotionalOffer. * @returns {Promise<{ productIdentifier: string, customerInfo: CustomerInfo }>} A promise of an object containing * a customer info object and a product identifier. Rejections return an error code, a boolean indicating if the * user cancelled the purchase, and an object with more information. The promise will be also be rejected if configure * has not been called yet. */ Purchases.purchaseDiscountedPackage = function (aPackage, discount) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); if (typeof discount === "undefined" || discount == null) { throw new Error("A discount is required"); } return [2 /*return*/, RNPurchases.purchasePackage(aPackage.identifier, aPackage.presentedOfferingContext, null, discount.timestamp.toString(), null).catch(function (error) { error.userCancelled = error.code === purchases_typescript_internal_1.PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; })]; } }); }); }; /** * Restores a user's previous purchases and links their appUserIDs to any user's also using those purchases. * @returns {Promise<CustomerInfo>} A promise of a customer info object. Rejections return an error code, and an * userInfo object with more information. The promise will be also be rejected if configure has not been called yet. */ Purchases.restorePurchases = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.restorePurchases()]; } }); }); }; /** * Get the appUserID * @returns {Promise<string>} The app user id in a promise */ Purchases.getAppUserID = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.getAppUserID()]; } }); }); }; /** * This function will logIn the current user with an appUserID. Typically this would be used after a log in * to identify a user without calling configure. * @param {String} appUserID The appUserID that should be linked to the currently user * @returns {Promise<LogInResult>} A promise of an object that contains the customerInfo after logging in, as well * as a boolean indicating whether the user has just been created for the first time in the RevenueCat backend. The * promise will be rejected if configure has not been called yet or if there's an issue logging in. */ Purchases.logIn = function (appUserID) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); // noinspection SuspiciousTypeOfGuard if (typeof appUserID !== "string") { throw new Error("appUserID needs to be a string"); } return [2 /*return*/, RNPurchases.logIn(appUserID)]; } }); }); }; /** * Logs out the Purchases client clearing the saved appUserID. This will generate a random user id and save it in the cache. * @returns {Promise<CustomerInfo>} A promise of a customer info object. Rejections return an error code, * and a userInfo object with more information. The promise will be rejected if configure has not been called yet or if * there's an issue logging out. */ Purchases.logOut = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.logOut()]; } }); }); }; /** * Enables/Disables debugs logs * @param {boolean} enabled Enable or not debug logs * @deprecated, use setLogLevel instead */ Purchases.setDebugLogsEnabled = function (enabled) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { RNPurchases.setDebugLogsEnabled(enabled); return [2 /*return*/]; }); }); }; /** * Used to set the log level. Useful for debugging issues with the lovely team @RevenueCat. * The default is {LOG_LEVEL.INFO} in release builds and {LOG_LEVEL.DEBUG} in debug builds. * @param {LOG_LEVEL} level */ Purchases.setLogLevel = function (level) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { RNPurchases.setLogLevel(level); return [2 /*return*/]; }); }); }; /** * Set a custom log handler for redirecting logs to your own logging system. * By default, this sends info, warning, and error messages. * If you wish to receive Debug level messages, see [setLogLevel]. * @param {LogHandler} logHandler It will get called for each log event. * Use this function to redirect the log to your own logging system */ Purchases.setLogHandler = function (logHandler) { customLogHandler = logHandler; RNPurchases.setLogHandler(); }; /** * Gets current customer info * @returns {Promise<CustomerInfo>} A promise of a customer info object. Rejections return an error code, and an * userInfo object with more information. The promise will be rejected if configure has not been called yet or if * there's an issue getting the customer information. */ Purchases.getCustomerInfo = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.getCustomerInfo()]; } }); }); }; /** * This method will send all the purchases to the RevenueCat backend. Call this when using your own implementation * for subscriptions anytime a sync is needed, like after a successful purchase. * * @warning This function should only be called if you're not calling purchaseProduct/purchaseStoreProduct/purchasePackage/purchaseSubscriptionOption. * @returns {Promise<void>} The promise will be rejected if configure has not been called yet or if there's an error * syncing purchases. */ Purchases.syncPurchases = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); RNPurchases.syncPurchases(); return [2 /*return*/]; } }); }); }; /** * This method will send a purchase to the RevenueCat backend. This function should only be called if you are * in Amazon observer mode or performing a client side migration of your current users to RevenueCat. * * The receipt IDs are cached if successfully posted so they are not posted more than once. * * @param {string} productID Product ID associated to the purchase. * @param {string} receiptID ReceiptId that represents the Amazon purchase. * @param {string} amazonUserID Amazon's userID. This parameter will be ignored when syncing a Google purchase. * @param {(string|null|undefined)} isoCurrencyCode Product's currency code in ISO 4217 format. * @param {(number|null|undefined)} price Product's price. * @returns {Promise<void>} The promise will be rejected if configure has not been called yet or if there's an error * syncing purchases. */ Purchases.syncAmazonPurchase = function (productID, receiptID, amazonUserID, isoCurrencyCode, price) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfIOSPlatform()]; case 1: _a.sent(); return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 2: _a.sent(); RNPurchases.syncAmazonPurchase(productID, receiptID, amazonUserID, isoCurrencyCode, price); return [2 /*return*/]; } }); }); }; /** * @deprecated, use syncAmazonPurchase instead. * * This method will send a purchase to the RevenueCat backend. This function should only be called if you are * in Amazon observer mode or performing a client side migration of your current users to RevenueCat. * * The receipt IDs are cached if successfully posted so they are not posted more than once. * * @param {string} productID Product ID associated to the purchase. * @param {string} receiptID ReceiptId that represents the Amazon purchase. * @param {string} amazonUserID Amazon's userID. This parameter will be ignored when syncing a Google purchase. * @param {(string|null|undefined)} isoCurrencyCode Product's currency code in ISO 4217 format. * @param {(number|null|undefined)} price Product's price. * @returns {Promise<void>} The promise will be rejected if configure has not been called yet or if there's an error * syncing purchases. */ Purchases.syncObserverModeAmazonPurchase = function (productID, receiptID, amazonUserID, isoCurrencyCode, price) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfIOSPlatform()]; case 1: _a.sent(); return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 2: _a.sent(); RNPurchases.syncObserverModeAmazonPurchase(productID, receiptID, amazonUserID, isoCurrencyCode, price); return [2 /*return*/]; } }); }); }; /** * iOS only. Always returns an error on iOS < 15. * * Use this method only if you already have your own IAP implementation using StoreKit 2 and want to use * RevenueCat's backend. If you are using StoreKit 1 for your implementation, you do not need this method. * * You only need to use this method with *new* purchases. Subscription updates are observed automatically. * * Important: This should only be used if you have set PurchasesAreCompletedBy to MY_APP during SDK configuration. * * @warning You need to finish the transaction yourself after calling this method. * * @param {string} productID Product ID that was just purchased * @returns {Promise<PurchasesStoreTransaction>} If there was a transacton found and handled for the provided product ID. */ Purchases.recordPurchase = function (productID) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfAndroidPlatform()]; case 1: _a.sent(); return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 2: _a.sent(); return [2 /*return*/, RNPurchases.recordPurchaseForProductID(productID)]; } }); }); }; /** * Enable automatic collection of Apple Search Ad attribution on iOS. Disabled by default * @returns {Promise<void>} The promise will be rejected if configure has not been called yet. */ Purchases.enableAdServicesAttributionTokenCollection = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(react_native_2.Platform.OS === "ios")) return [3 /*break*/, 2]; return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); RNPurchases.enableAdServicesAttributionTokenCollection(); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }; /** * @returns { Promise<boolean> } If the `appUserID` has been generated by RevenueCat or not. * @returns {Promise<void>} The promise will be rejected if configure has not been called yet. */ Purchases.isAnonymous = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.isAnonymous()]; } }); }); }; /** * iOS only. Computes whether or not a user is eligible for the introductory pricing period of a given product. * You should use this method to determine whether or not you show the user the normal product price or the * introductory price. This also applies to trials (trials are considered a type of introductory pricing). * * @note Subscription groups are automatically collected for determining eligibility. If RevenueCat can't * definitively compute the eligibility, most likely because of missing group information, it will return * `INTRO_ELIGIBILITY_STATUS_UNKNOWN`. The best course of action on unknown status is to display the non-intro * pricing, to not create a misleading situation. To avoid this, make sure you are testing with the latest version of * iOS so that the subscription group can be collected by the SDK. Android always returns INTRO_ELIGIBILITY_STATUS_UNKNOWN. * * @param productIdentifiers Array of product identifiers for which you want to compute eligibility * @returns { Promise<[productId: string]: IntroEligibility> } A map of IntroEligility per productId. The promise * will be rejected if configure has not been called yet or if there's in an error checking eligibility. */ Purchases.checkTrialOrIntroductoryPriceEligibility = function (productIdentifiers) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); return [2 /*return*/, RNPurchases.checkTrialOrIntroductoryPriceEligibility(productIdentifiers)]; } }); }); }; /** * iOS only. Use this function to retrieve the `PurchasesPromotionalOffer` for a given `PurchasesPackage`. * * @param product The `PurchasesStoreProduct` the user intends to purchase. * @param discount The `PurchasesStoreProductDiscount` to apply to the product. * @returns { Promise<PurchasesPromotionalOffer> } Returns when the `PurchasesPaymentDiscount` is returned. * Null is returned for Android and incompatible iOS versions. The promise will be rejected if configure has not been * called yet or if there's an error getting the payment discount. */ Purchases.getPromotionalOffer = function (product, discount) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); if (react_native_2.Platform.OS === "android") { return [2 /*return*/, Promise.resolve(undefined)]; } if (typeof discount === "undefined" || discount == null) { throw new Error("A discount is required"); } return [2 /*return*/, RNPurchases.getPromotionalOffer(product.identifier, discount.identifier)]; } }); }); }; /** * iOS only. Use this function to retrieve the eligible `PurchasesWinBackOffer`s that a subscriber * is eligible for for a given `PurchasesProduct`. * * @param product The `PurchasesStoreProduct` the user intends to purchase. * @returns { Promise<[PurchasesWinBackOffer]> } Returns an array of win-back offers that the subscriber is eligible for. * Null is returned for Android and incompatible iOS versions. The promise will be rejected if configure has not been * called yet or if there's an error getting the payment discount. */ Purchases.getEligibleWinBackOffersForProduct = function (product) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Purchases.throwIfNotConfigured()]; case 1: _a.sent(); if (react_native_2.Platform.OS === "android") { return [2 /*return*/, Promise.resolve(undefined)]; } return [2 /*return*/, RNPurchases.eligibleWinBackOffersForProductIdentifier(product.identifier)]; } }); }); }; /** * iOS only. Use this function to retrieve the eligible `PurchasesWinBackOffer`s that a subscriber * is eligible for for a given `PurchasesPackage`. * * @param aPackag