@virex-tech/paywallo-sdk 2.2.3 → 2.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +5 -3
- package/android/src/main/AndroidManifest.xml +7 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloFirebaseMessagingService.kt +33 -5
- package/android/src/main/java/com/paywallo/sdk/PaywalloNotificationsModule.kt +47 -30
- package/android/src/main/java/com/paywallo/sdk/PaywalloStoreKitModule.kt +7 -3
- package/android/src/main/java/com/paywallo/sdk/PaywalloWebViewEvent.kt +4 -2
- package/dist/index.d.mts +74 -9
- package/dist/index.d.ts +74 -9
- package/dist/index.js +306 -193
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +325 -210
- package/dist/index.mjs.map +1 -1
- package/ios/PaywalloWebView.m +5 -0
- package/package.json +6 -2
package/dist/index.mjs
CHANGED
|
@@ -1052,7 +1052,7 @@ var init_sessionTracking = __esm({
|
|
|
1052
1052
|
|
|
1053
1053
|
// src/domains/session/SessionManager.ts
|
|
1054
1054
|
import { AppState } from "react-native";
|
|
1055
|
-
var SESSION_ID_KEY, SESSION_START_KEY,
|
|
1055
|
+
var SESSION_ID_KEY, SESSION_START_KEY, LEGACY_SESSION_ID_KEY, LEGACY_SESSION_START_KEY, SESSION_TIMEOUT_MS, SessionManager, sessionManager;
|
|
1056
1056
|
var init_SessionManager = __esm({
|
|
1057
1057
|
"src/domains/session/SessionManager.ts"() {
|
|
1058
1058
|
"use strict";
|
|
@@ -1063,11 +1063,9 @@ var init_SessionManager = __esm({
|
|
|
1063
1063
|
init_sessionTracking();
|
|
1064
1064
|
SESSION_ID_KEY = "@paywallo:current_session_id";
|
|
1065
1065
|
SESSION_START_KEY = "@paywallo:session_start";
|
|
1066
|
-
EMERGENCY_PAYWALL_SHOWN_KEY = "@paywallo:emergency_paywall_shown";
|
|
1067
1066
|
LEGACY_SESSION_ID_KEY = "current_session_id";
|
|
1068
1067
|
LEGACY_SESSION_START_KEY = "session_start";
|
|
1069
1068
|
SESSION_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
1070
|
-
BACKGROUND_FLUSH_TIMEOUT_MS = 2e3;
|
|
1071
1069
|
SessionManager = class {
|
|
1072
1070
|
constructor() {
|
|
1073
1071
|
this.sessionId = null;
|
|
@@ -1129,8 +1127,7 @@ var init_SessionManager = __esm({
|
|
|
1129
1127
|
this.emergencyPaywallShownInSession = false;
|
|
1130
1128
|
await Promise.all([
|
|
1131
1129
|
this.secureStorage.set(SESSION_ID_KEY, this.sessionId),
|
|
1132
|
-
this.secureStorage.set(SESSION_START_KEY, this.sessionStartedAt.toISOString())
|
|
1133
|
-
this.secureStorage.remove(EMERGENCY_PAYWALL_SHOWN_KEY)
|
|
1130
|
+
this.secureStorage.set(SESSION_START_KEY, this.sessionStartedAt.toISOString())
|
|
1134
1131
|
]);
|
|
1135
1132
|
await this.trackSessionStart();
|
|
1136
1133
|
return this.sessionId;
|
|
@@ -1140,10 +1137,10 @@ var init_SessionManager = __esm({
|
|
|
1140
1137
|
if (!this.sessionId || !this.sessionStartedAt) {
|
|
1141
1138
|
return;
|
|
1142
1139
|
}
|
|
1140
|
+
await this.trackSessionEnd();
|
|
1143
1141
|
if (this.apiClient) {
|
|
1144
1142
|
await this.apiClient.flushEventBatch();
|
|
1145
1143
|
}
|
|
1146
|
-
await this.trackSessionEnd();
|
|
1147
1144
|
this.sessionId = null;
|
|
1148
1145
|
this.sessionStartedAt = null;
|
|
1149
1146
|
await Promise.all([
|
|
@@ -1228,7 +1225,6 @@ var init_SessionManager = __esm({
|
|
|
1228
1225
|
async handleBackground() {
|
|
1229
1226
|
this.backgroundTimestamp = Date.now();
|
|
1230
1227
|
await this.trackAppBackground();
|
|
1231
|
-
await this.flushEventsWithTimeout(BACKGROUND_FLUSH_TIMEOUT_MS);
|
|
1232
1228
|
await this.endSession();
|
|
1233
1229
|
}
|
|
1234
1230
|
async flushEventsWithTimeout(timeoutMs) {
|
|
@@ -1247,7 +1243,6 @@ var init_SessionManager = __esm({
|
|
|
1247
1243
|
const response = await this.apiClient.getEmergencyPaywall().catch(() => null);
|
|
1248
1244
|
if (response?.enabled && response.paywallId) {
|
|
1249
1245
|
this.emergencyPaywallShownInSession = true;
|
|
1250
|
-
await this.secureStorage.set(EMERGENCY_PAYWALL_SHOWN_KEY, "true");
|
|
1251
1246
|
await this.emergencyPaywallHandler(response.paywallId);
|
|
1252
1247
|
}
|
|
1253
1248
|
}
|
|
@@ -1547,7 +1542,7 @@ var init_MetaBridge = __esm({
|
|
|
1547
1542
|
try {
|
|
1548
1543
|
await NativeBridge.logEvent(name, params);
|
|
1549
1544
|
} catch (error) {
|
|
1550
|
-
|
|
1545
|
+
console.error("[Paywallo:MetaBridge] logEvent failed", { name, error });
|
|
1551
1546
|
}
|
|
1552
1547
|
}
|
|
1553
1548
|
async logPurchase(amount, currency, params = {}) {
|
|
@@ -1555,7 +1550,7 @@ var init_MetaBridge = __esm({
|
|
|
1555
1550
|
try {
|
|
1556
1551
|
await NativeBridge.logPurchase(amount, currency, params);
|
|
1557
1552
|
} catch (error) {
|
|
1558
|
-
|
|
1553
|
+
console.error("[Paywallo:MetaBridge] logPurchase failed", { amount, currency, error });
|
|
1559
1554
|
}
|
|
1560
1555
|
}
|
|
1561
1556
|
setUserID(userId) {
|
|
@@ -1563,7 +1558,7 @@ var init_MetaBridge = __esm({
|
|
|
1563
1558
|
try {
|
|
1564
1559
|
NativeBridge.setUserID(userId);
|
|
1565
1560
|
} catch (error) {
|
|
1566
|
-
|
|
1561
|
+
console.error("[Paywallo:MetaBridge] setUserID failed", { error });
|
|
1567
1562
|
}
|
|
1568
1563
|
}
|
|
1569
1564
|
flush() {
|
|
@@ -1571,7 +1566,7 @@ var init_MetaBridge = __esm({
|
|
|
1571
1566
|
try {
|
|
1572
1567
|
NativeBridge.flush();
|
|
1573
1568
|
} catch (error) {
|
|
1574
|
-
|
|
1569
|
+
console.error("[Paywallo:MetaBridge] flush failed", { error });
|
|
1575
1570
|
}
|
|
1576
1571
|
}
|
|
1577
1572
|
};
|
|
@@ -1787,7 +1782,7 @@ var init_InstallTracker = __esm({
|
|
|
1787
1782
|
screenWidth: deviceData.screenWidth,
|
|
1788
1783
|
screenHeight: deviceData.screenHeight,
|
|
1789
1784
|
timezone: deviceData.timezone,
|
|
1790
|
-
|
|
1785
|
+
language: deviceData.locale,
|
|
1791
1786
|
fbAnonId: anonId,
|
|
1792
1787
|
installTimestamp: new Date(installedAt).toISOString()
|
|
1793
1788
|
}),
|
|
@@ -2013,13 +2008,21 @@ var init_NativePushBridge = __esm({
|
|
|
2013
2008
|
if (!raw || typeof raw !== "object") return null;
|
|
2014
2009
|
const r = raw;
|
|
2015
2010
|
const notification = r["notification"];
|
|
2011
|
+
const asString = (v) => typeof v === "string" ? v : void 0;
|
|
2016
2012
|
return {
|
|
2017
|
-
messageId:
|
|
2013
|
+
messageId: asString(r["messageId"]),
|
|
2018
2014
|
data: typeof r["data"] === "object" && r["data"] !== null ? r["data"] : void 0,
|
|
2019
2015
|
notification: notification && typeof notification === "object" ? {
|
|
2020
|
-
title:
|
|
2021
|
-
body:
|
|
2016
|
+
title: asString(notification["title"]),
|
|
2017
|
+
body: asString(notification["body"]),
|
|
2018
|
+
imageUrl: asString(notification["imageUrl"])
|
|
2022
2019
|
} : void 0,
|
|
2020
|
+
// Pass through top-level title/body/imageUrl emitted by the native modules
|
|
2021
|
+
// (both iOS and Android currently emit these at the top level rather than
|
|
2022
|
+
// nested under `notification`).
|
|
2023
|
+
title: asString(r["title"]),
|
|
2024
|
+
body: asString(r["body"]),
|
|
2025
|
+
imageUrl: asString(r["imageUrl"]),
|
|
2023
2026
|
sentTime: typeof r["sentTime"] === "number" ? r["sentTime"] : void 0
|
|
2024
2027
|
};
|
|
2025
2028
|
} catch {
|
|
@@ -2158,10 +2161,11 @@ function setupForegroundHandler(deps, onReceive) {
|
|
|
2158
2161
|
const data = message.data ?? {};
|
|
2159
2162
|
const payload = extractPayload({
|
|
2160
2163
|
...data,
|
|
2161
|
-
title: data["title"] ?? message.notification?.title ?? "",
|
|
2162
|
-
body: data["body"] ?? message.notification?.body ?? ""
|
|
2164
|
+
title: data["title"] ?? message.notification?.title ?? message.title ?? "",
|
|
2165
|
+
body: data["body"] ?? message.notification?.body ?? message.body ?? "",
|
|
2166
|
+
imageUrl: data["imageUrl"] ?? message.notification?.imageUrl ?? message.imageUrl
|
|
2163
2167
|
});
|
|
2164
|
-
if (debug) console.
|
|
2168
|
+
if (debug) console.log("[Paywallo PUSH] foreground message received:", payload.notificationId);
|
|
2165
2169
|
onReceive(payload);
|
|
2166
2170
|
const messageId = message.messageId ?? payload.notificationId;
|
|
2167
2171
|
await tracker.track("notification_delivered", {
|
|
@@ -2192,13 +2196,20 @@ function getTimezone() {
|
|
|
2192
2196
|
function detectPlatform() {
|
|
2193
2197
|
return Platform5.OS === "ios" ? "ios" : "android";
|
|
2194
2198
|
}
|
|
2195
|
-
var SEEN_MESSAGES_KEY, SEEN_TTL_MS, MAX_SEEN_SIZE, NotificationEventTracker;
|
|
2199
|
+
var SEEN_MESSAGES_KEY, LEGACY_SEEN_MESSAGES_KEY, SEEN_TTL_MS, MAX_SEEN_SIZE, NOTIFICATION_TYPE_TO_FAMILY, NotificationEventTracker;
|
|
2196
2200
|
var init_NotificationEventTracker = __esm({
|
|
2197
2201
|
"src/domains/notifications/NotificationEventTracker.ts"() {
|
|
2198
2202
|
"use strict";
|
|
2199
|
-
SEEN_MESSAGES_KEY = "seen_messages";
|
|
2203
|
+
SEEN_MESSAGES_KEY = "@paywallo:seen_messages";
|
|
2204
|
+
LEGACY_SEEN_MESSAGES_KEY = "seen_messages";
|
|
2200
2205
|
SEEN_TTL_MS = 60 * 60 * 1e3;
|
|
2201
2206
|
MAX_SEEN_SIZE = 1e3;
|
|
2207
|
+
NOTIFICATION_TYPE_TO_FAMILY = {
|
|
2208
|
+
notification_delivered: "delivered",
|
|
2209
|
+
notification_displayed: "displayed",
|
|
2210
|
+
notification_clicked: "clicked",
|
|
2211
|
+
notification_dismissed: "dismissed"
|
|
2212
|
+
};
|
|
2202
2213
|
NotificationEventTracker = class {
|
|
2203
2214
|
constructor(batcher, config, secureStorage2) {
|
|
2204
2215
|
this.batcher = batcher;
|
|
@@ -2219,9 +2230,13 @@ var init_NotificationEventTracker = __esm({
|
|
|
2219
2230
|
if (this.config.debug) console.log("[Paywallo PUSH] skipped (no distinctId):", eventType);
|
|
2220
2231
|
return;
|
|
2221
2232
|
}
|
|
2233
|
+
const canonicalType = NOTIFICATION_TYPE_TO_FAMILY[eventType];
|
|
2234
|
+
if (!canonicalType) {
|
|
2235
|
+
if (this.config.debug) console.log("[Paywallo PUSH] eventType not mapped to family schema, skipping ingest:", eventType);
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2222
2238
|
const properties = {
|
|
2223
|
-
|
|
2224
|
-
type: eventType,
|
|
2239
|
+
type: canonicalType,
|
|
2225
2240
|
notification_id: notificationId,
|
|
2226
2241
|
campaign_id: campaignId,
|
|
2227
2242
|
variant_key: variantKey ?? null,
|
|
@@ -2233,7 +2248,7 @@ var init_NotificationEventTracker = __esm({
|
|
|
2233
2248
|
if (payload.failureReason) properties.failure_reason = payload.failureReason;
|
|
2234
2249
|
if (payload.appUserId) properties.app_user_id = payload.appUserId;
|
|
2235
2250
|
if (payload.properties) Object.assign(properties, payload.properties);
|
|
2236
|
-
if (this.config.debug) console.log("[Paywallo PUSH] tracking event:",
|
|
2251
|
+
if (this.config.debug) console.log("[Paywallo PUSH] tracking event:", canonicalType, notificationId);
|
|
2237
2252
|
await this.batcher.trackEvent("notification", distinctId, properties);
|
|
2238
2253
|
}
|
|
2239
2254
|
async isDuplicate(messageId, eventType) {
|
|
@@ -2278,7 +2293,10 @@ var init_NotificationEventTracker = __esm({
|
|
|
2278
2293
|
return;
|
|
2279
2294
|
}
|
|
2280
2295
|
try {
|
|
2281
|
-
|
|
2296
|
+
let raw = await this.secureStorage.get(SEEN_MESSAGES_KEY);
|
|
2297
|
+
if (!raw) {
|
|
2298
|
+
raw = await this.secureStorage.get(LEGACY_SEEN_MESSAGES_KEY).catch(() => null);
|
|
2299
|
+
}
|
|
2282
2300
|
if (raw) {
|
|
2283
2301
|
const parsed = JSON.parse(raw);
|
|
2284
2302
|
const now = Date.now();
|
|
@@ -2336,8 +2354,8 @@ async function getInitialNotificationPayload(bridge) {
|
|
|
2336
2354
|
notificationId: String(data["notificationId"] ?? data["notification_id"] ?? ""),
|
|
2337
2355
|
campaignId: String(data["campaignId"] ?? data["campaign_id"] ?? ""),
|
|
2338
2356
|
variantKey: data["variantKey"] != null ? String(data["variantKey"]) : void 0,
|
|
2339
|
-
title: String(data["title"] ?? message.notification?.title ?? ""),
|
|
2340
|
-
body: String(data["body"] ?? message.notification?.body ?? ""),
|
|
2357
|
+
title: String(data["title"] ?? message.notification?.title ?? message.title ?? ""),
|
|
2358
|
+
body: String(data["body"] ?? message.notification?.body ?? message.body ?? ""),
|
|
2341
2359
|
data
|
|
2342
2360
|
};
|
|
2343
2361
|
}
|
|
@@ -2352,8 +2370,8 @@ var init_NotificationHandlerSetup = __esm({
|
|
|
2352
2370
|
// src/core/version.ts
|
|
2353
2371
|
function resolveVersion() {
|
|
2354
2372
|
try {
|
|
2355
|
-
if ("2.2.
|
|
2356
|
-
return "2.2.
|
|
2373
|
+
if ("2.2.5") {
|
|
2374
|
+
return "2.2.5";
|
|
2357
2375
|
}
|
|
2358
2376
|
} catch {
|
|
2359
2377
|
}
|
|
@@ -2485,7 +2503,7 @@ async function buildRegistration(token, getDeviceId, getDistinctId) {
|
|
|
2485
2503
|
async function registerToken(deps, token) {
|
|
2486
2504
|
const { httpClient, appKey, getDeviceId, getDistinctId, debug } = deps;
|
|
2487
2505
|
if (!httpClient || !appKey) {
|
|
2488
|
-
if (debug) console.
|
|
2506
|
+
if (debug) console.log("[Paywallo PUSH] httpClient not ready, skipping token registration");
|
|
2489
2507
|
return;
|
|
2490
2508
|
}
|
|
2491
2509
|
const registration = await buildRegistration(token, getDeviceId, getDistinctId);
|
|
@@ -2495,22 +2513,25 @@ async function registerToken(deps, token) {
|
|
|
2495
2513
|
registration,
|
|
2496
2514
|
{ headers: { "X-App-Key": appKey } }
|
|
2497
2515
|
);
|
|
2498
|
-
if (debug) console.
|
|
2516
|
+
if (debug) console.log("[Paywallo PUSH] token registered successfully");
|
|
2499
2517
|
} catch (err) {
|
|
2500
|
-
|
|
2518
|
+
console.error("[Paywallo PUSH] token registration failed:", err);
|
|
2501
2519
|
throw new RegistrationFailedError("Token registration failed", err);
|
|
2502
2520
|
}
|
|
2503
2521
|
}
|
|
2504
|
-
async function unregisterToken(httpClient, appKey, debug) {
|
|
2522
|
+
async function unregisterToken(httpClient, appKey, debug, token, distinctId) {
|
|
2505
2523
|
if (!httpClient || !appKey) return;
|
|
2524
|
+
if (!token || !distinctId) return;
|
|
2506
2525
|
try {
|
|
2526
|
+
const body = JSON.stringify({ token, distinct_id: distinctId });
|
|
2507
2527
|
await httpClient.request(TOKEN_ENDPOINT, {
|
|
2508
2528
|
method: "DELETE",
|
|
2509
|
-
headers: { "X-App-Key": appKey },
|
|
2529
|
+
headers: { "X-App-Key": appKey, "Content-Type": "application/json" },
|
|
2530
|
+
body,
|
|
2510
2531
|
timeout: 1e4
|
|
2511
2532
|
});
|
|
2512
2533
|
} catch (err) {
|
|
2513
|
-
|
|
2534
|
+
console.error("[Paywallo PUSH] optOut error:", err);
|
|
2514
2535
|
}
|
|
2515
2536
|
}
|
|
2516
2537
|
var FCM_TOKEN_KEY, TOKEN_ENDPOINT;
|
|
@@ -2542,7 +2563,7 @@ async function registerAndPersistToken(deps, token) {
|
|
|
2542
2563
|
}
|
|
2543
2564
|
function subscribeTokenRefresh(bridge, deps, onToken) {
|
|
2544
2565
|
return bridge.onTokenRefresh((newToken) => {
|
|
2545
|
-
if (deps.debug) console.
|
|
2566
|
+
if (deps.debug) console.log("[Paywallo PUSH] token refreshed");
|
|
2546
2567
|
onToken(newToken);
|
|
2547
2568
|
persistToken(deps.secureStorage, newToken).catch(() => void 0);
|
|
2548
2569
|
registerToken(
|
|
@@ -2558,8 +2579,8 @@ function subscribeTokenRefresh(bridge, deps, onToken) {
|
|
|
2558
2579
|
).catch(() => void 0);
|
|
2559
2580
|
});
|
|
2560
2581
|
}
|
|
2561
|
-
async function optOutToken(httpClient, secureStorage2, appKey, debug) {
|
|
2562
|
-
await unregisterToken(httpClient, appKey, debug);
|
|
2582
|
+
async function optOutToken(httpClient, secureStorage2, appKey, debug, token, distinctId) {
|
|
2583
|
+
await unregisterToken(httpClient, appKey, debug, token, distinctId);
|
|
2563
2584
|
await clearPersistedToken(secureStorage2);
|
|
2564
2585
|
}
|
|
2565
2586
|
async function invalidateLocalTokenStorage(secureStorage2, debug) {
|
|
@@ -2579,7 +2600,7 @@ async function captureAndRegisterToken(bridge, deps, onTokenCaptured, subscribeR
|
|
|
2579
2600
|
await waitForApnsToken(bridge, deps.debug);
|
|
2580
2601
|
const token = await bridge.getToken();
|
|
2581
2602
|
if (!token) {
|
|
2582
|
-
if (deps.debug) console.
|
|
2603
|
+
if (deps.debug) console.log("[Paywallo PUSH] token unavailable after grant");
|
|
2583
2604
|
return;
|
|
2584
2605
|
}
|
|
2585
2606
|
onTokenCaptured(token);
|
|
@@ -2646,18 +2667,18 @@ var init_PermissionManager = __esm({
|
|
|
2646
2667
|
}
|
|
2647
2668
|
async requestPermission(options) {
|
|
2648
2669
|
const platform = this.platformOverride ?? getPlatform();
|
|
2649
|
-
if (this.debug) console.
|
|
2670
|
+
if (this.debug) console.log("[paywallo-push] platform detected:", platform.OS, "version:", String(platform.Version ?? "n/a"));
|
|
2650
2671
|
if (platform.OS === "ios") {
|
|
2651
|
-
if (this.debug) console.
|
|
2672
|
+
if (this.debug) console.log("[paywallo-push] requestPermission iOS \u2014 calling bridge...");
|
|
2652
2673
|
try {
|
|
2653
2674
|
const raw2 = await this.bridge.requestPermission(options);
|
|
2654
|
-
if (this.debug) console.
|
|
2675
|
+
if (this.debug) console.log("[paywallo-push] bridge returned raw:", raw2);
|
|
2655
2676
|
const status2 = mapPermissionStatus2(raw2);
|
|
2656
|
-
if (this.debug) console.
|
|
2677
|
+
if (this.debug) console.log("[paywallo-push] mapped status:", status2);
|
|
2657
2678
|
this.emitOsEvent(status2);
|
|
2658
2679
|
return status2;
|
|
2659
2680
|
} catch (err) {
|
|
2660
|
-
|
|
2681
|
+
console.error("[paywallo-push] requestPermission iOS CRASHED:", err instanceof Error ? err.message : String(err));
|
|
2661
2682
|
throw err;
|
|
2662
2683
|
}
|
|
2663
2684
|
}
|
|
@@ -2790,11 +2811,11 @@ var init_NotificationsManager = __esm({
|
|
|
2790
2811
|
await waitForApnsToken(this.bridge, this.debug);
|
|
2791
2812
|
const token = await this.bridge.getToken();
|
|
2792
2813
|
if (!token) {
|
|
2793
|
-
if (this.debug) console.
|
|
2814
|
+
if (this.debug) console.log("[Paywallo PUSH] token unavailable, skipping registration");
|
|
2794
2815
|
this.isInitialized = true;
|
|
2795
2816
|
return;
|
|
2796
2817
|
}
|
|
2797
|
-
if (this.debug) console.
|
|
2818
|
+
if (this.debug) console.log("[Paywallo PUSH] token acquired:", token);
|
|
2798
2819
|
this.currentToken = token;
|
|
2799
2820
|
await this.doRegisterToken(token);
|
|
2800
2821
|
this.subscribeTokenRefresh();
|
|
@@ -2812,7 +2833,7 @@ var init_NotificationsManager = __esm({
|
|
|
2812
2833
|
async refreshPermissionStatus() {
|
|
2813
2834
|
const permStatus = await this.bridge.hasPermission();
|
|
2814
2835
|
this.permissionStatus = mapPermissionStatus(permStatus);
|
|
2815
|
-
if (this.debug) console.
|
|
2836
|
+
if (this.debug) console.log("[Paywallo PUSH] permission status:", this.permissionStatus);
|
|
2816
2837
|
}
|
|
2817
2838
|
tokenDeps() {
|
|
2818
2839
|
return {
|
|
@@ -2840,7 +2861,7 @@ var init_NotificationsManager = __esm({
|
|
|
2840
2861
|
async optOut() {
|
|
2841
2862
|
await optOutToken(this.httpClient, this.secureStorage, this.appKey, this.debug);
|
|
2842
2863
|
this.currentToken = null;
|
|
2843
|
-
if (this.debug) console.
|
|
2864
|
+
if (this.debug) console.log("[Paywallo PUSH] opted out");
|
|
2844
2865
|
}
|
|
2845
2866
|
/** Clears token locally without server call (used on sign-out/reset). */
|
|
2846
2867
|
async invalidateLocalToken() {
|
|
@@ -2857,21 +2878,21 @@ var init_NotificationsManager = __esm({
|
|
|
2857
2878
|
}
|
|
2858
2879
|
/** Requests OS permission and, on success, captures + registers the push token. */
|
|
2859
2880
|
async requestPushPermission(options) {
|
|
2860
|
-
if (this.debug) console.
|
|
2881
|
+
if (this.debug) console.log("[Paywallo PUSH] requestPushPermission called");
|
|
2861
2882
|
try {
|
|
2862
2883
|
const status = await this.permissionManager.requestPermission(options);
|
|
2863
|
-
if (this.debug) console.
|
|
2884
|
+
if (this.debug) console.log("[Paywallo PUSH] permissionManager returned:", status);
|
|
2864
2885
|
this.permissionStatus = status;
|
|
2865
2886
|
if (status === "granted" || status === "provisional") {
|
|
2866
|
-
if (this.debug) console.
|
|
2887
|
+
if (this.debug) console.log("[Paywallo PUSH] permission granted \u2014 capturing token...");
|
|
2867
2888
|
await this.captureAndRegisterToken();
|
|
2868
|
-
if (this.debug) console.
|
|
2889
|
+
if (this.debug) console.log("[Paywallo PUSH] token capture complete");
|
|
2869
2890
|
} else {
|
|
2870
|
-
if (this.debug) console.
|
|
2891
|
+
if (this.debug) console.log("[Paywallo PUSH] permission not granted, skipping token register:", status);
|
|
2871
2892
|
}
|
|
2872
2893
|
return status;
|
|
2873
2894
|
} catch (err) {
|
|
2874
|
-
|
|
2895
|
+
console.error("[Paywallo PUSH] requestPushPermission CRASHED:", err instanceof Error ? err.message : String(err));
|
|
2875
2896
|
throw err;
|
|
2876
2897
|
}
|
|
2877
2898
|
}
|
|
@@ -3033,7 +3054,9 @@ function parseWebViewMessage(raw) {
|
|
|
3033
3054
|
const safePayload = payload !== null && typeof payload === "object" ? {
|
|
3034
3055
|
productId: typeof payload.productId === "string" ? String(payload.productId) : void 0,
|
|
3035
3056
|
url: typeof payload.url === "string" ? String(payload.url) : void 0,
|
|
3036
|
-
timestamp: typeof payload.timestamp === "number" ? Number(payload.timestamp) : void 0
|
|
3057
|
+
timestamp: typeof payload.timestamp === "number" ? Number(payload.timestamp) : void 0,
|
|
3058
|
+
variantKey: typeof payload.variantKey === "string" ? String(payload.variantKey) : void 0,
|
|
3059
|
+
style: HAPTIC_STYLES.has(String(payload.style)) ? String(payload.style) : typeof payload.style !== "undefined" ? "light" : void 0
|
|
3037
3060
|
} : void 0;
|
|
3038
3061
|
return {
|
|
3039
3062
|
type: parsed.type,
|
|
@@ -3044,17 +3067,19 @@ function parseWebViewMessage(raw) {
|
|
|
3044
3067
|
return null;
|
|
3045
3068
|
}
|
|
3046
3069
|
}
|
|
3047
|
-
var ALLOWED_MESSAGE_TYPES;
|
|
3070
|
+
var HAPTIC_STYLES, ALLOWED_MESSAGE_TYPES;
|
|
3048
3071
|
var init_parseWebViewMessage = __esm({
|
|
3049
3072
|
"src/domains/paywall/parseWebViewMessage.ts"() {
|
|
3050
3073
|
"use strict";
|
|
3074
|
+
HAPTIC_STYLES = /* @__PURE__ */ new Set(["light", "medium", "heavy"]);
|
|
3051
3075
|
ALLOWED_MESSAGE_TYPES = /* @__PURE__ */ new Set([
|
|
3052
3076
|
"purchase",
|
|
3053
3077
|
"close",
|
|
3054
3078
|
"restore",
|
|
3055
3079
|
"select-product",
|
|
3056
3080
|
"open-url",
|
|
3057
|
-
"ready"
|
|
3081
|
+
"ready",
|
|
3082
|
+
"haptic"
|
|
3058
3083
|
]);
|
|
3059
3084
|
}
|
|
3060
3085
|
});
|
|
@@ -3096,7 +3121,7 @@ var init_PaywallErrorBoundary = __esm({
|
|
|
3096
3121
|
return { hasError: true };
|
|
3097
3122
|
}
|
|
3098
3123
|
componentDidCatch(error) {
|
|
3099
|
-
|
|
3124
|
+
console.error("[Paywallo] Paywall render error:", error);
|
|
3100
3125
|
try {
|
|
3101
3126
|
PaywalloClient.getApiClient()?.reportError("PAYWALL_RENDER_ERROR", error.message);
|
|
3102
3127
|
} catch {
|
|
@@ -3263,7 +3288,9 @@ function buildPaywallInjectionScript(data) {
|
|
|
3263
3288
|
craftData: data.craftData,
|
|
3264
3289
|
products: data.products,
|
|
3265
3290
|
primaryProductId: data.primaryProductId,
|
|
3266
|
-
secondaryProductId: data.secondaryProductId
|
|
3291
|
+
secondaryProductId: data.secondaryProductId,
|
|
3292
|
+
currentLanguage: getCurrentLanguage(),
|
|
3293
|
+
defaultLanguage: getDefaultLanguage()
|
|
3267
3294
|
}
|
|
3268
3295
|
};
|
|
3269
3296
|
return `(function(){var d=${JSON.stringify(paywallData)},a=0,m=50;function t(){a++;if(window.receiveNativeMessage){window.receiveNativeMessage(d);return;}if(a<m){setTimeout(t,100);}}t();})();true;`;
|
|
@@ -3271,20 +3298,43 @@ function buildPaywallInjectionScript(data) {
|
|
|
3271
3298
|
function buildPurchaseStateScript(isPurchasing) {
|
|
3272
3299
|
return `if(window.receiveNativeMessage){window.receiveNativeMessage({type:"purchaseState",data:{isPurchasing:${isPurchasing}}});}true;`;
|
|
3273
3300
|
}
|
|
3301
|
+
function buildBackButtonScript(nonce = Date.now()) {
|
|
3302
|
+
return [
|
|
3303
|
+
`/*${nonce}*/`,
|
|
3304
|
+
"(function(){",
|
|
3305
|
+
"try{",
|
|
3306
|
+
"var h=window.__paywalloHandleBackPress;",
|
|
3307
|
+
"var consumed=typeof h==='function'?!!h():false;",
|
|
3308
|
+
"if(!consumed&&window.ReactNativeWebView){",
|
|
3309
|
+
'window.ReactNativeWebView.postMessage(JSON.stringify({type:"close"}));',
|
|
3310
|
+
"}",
|
|
3311
|
+
"}catch(e){",
|
|
3312
|
+
"if(window.ReactNativeWebView){",
|
|
3313
|
+
'window.ReactNativeWebView.postMessage(JSON.stringify({type:"close"}));',
|
|
3314
|
+
"}",
|
|
3315
|
+
"}",
|
|
3316
|
+
"})();true;"
|
|
3317
|
+
].join("");
|
|
3318
|
+
}
|
|
3274
3319
|
var init_paywallScripts = __esm({
|
|
3275
3320
|
"src/domains/paywall/paywallScripts.ts"() {
|
|
3276
3321
|
"use strict";
|
|
3322
|
+
init_localization();
|
|
3277
3323
|
}
|
|
3278
3324
|
});
|
|
3279
3325
|
|
|
3280
3326
|
// src/domains/paywall/PaywallWebView.tsx
|
|
3281
3327
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3282
3328
|
import {
|
|
3329
|
+
BackHandler,
|
|
3330
|
+
findNodeHandle,
|
|
3283
3331
|
Linking as Linking2,
|
|
3284
3332
|
NativeEventEmitter as NativeEventEmitter2,
|
|
3285
3333
|
NativeModules as NativeModules6,
|
|
3334
|
+
Platform as Platform9,
|
|
3286
3335
|
requireNativeComponent,
|
|
3287
3336
|
StyleSheet,
|
|
3337
|
+
UIManager,
|
|
3288
3338
|
View
|
|
3289
3339
|
} from "react-native";
|
|
3290
3340
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -3306,6 +3356,24 @@ function getWebViewEmitter() {
|
|
|
3306
3356
|
webViewEmitter = new NativeEventEmitter2(mod);
|
|
3307
3357
|
return webViewEmitter;
|
|
3308
3358
|
}
|
|
3359
|
+
async function triggerNativeHaptic(style) {
|
|
3360
|
+
try {
|
|
3361
|
+
const module = await import("react-native-haptic-feedback");
|
|
3362
|
+
const hapticModule = module.default ?? module;
|
|
3363
|
+
const trigger = hapticModule.trigger;
|
|
3364
|
+
if (typeof trigger !== "function") return;
|
|
3365
|
+
const typeMap = {
|
|
3366
|
+
light: "impactLight",
|
|
3367
|
+
medium: "impactMedium",
|
|
3368
|
+
heavy: "impactHeavy"
|
|
3369
|
+
};
|
|
3370
|
+
trigger(typeMap[style], {
|
|
3371
|
+
enableVibrateFallback: true,
|
|
3372
|
+
ignoreAndroidSystemSettings: false
|
|
3373
|
+
});
|
|
3374
|
+
} catch {
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3309
3377
|
function parseErrorEvent(raw) {
|
|
3310
3378
|
return {
|
|
3311
3379
|
code: typeof raw["code"] === "number" ? raw["code"] : -1,
|
|
@@ -3330,6 +3398,7 @@ function PaywallWebView({
|
|
|
3330
3398
|
const paywallDataSent = useRef(false);
|
|
3331
3399
|
const loadEndReceived = useRef(false);
|
|
3332
3400
|
const [scriptToInject, setScriptToInject] = useState(void 0);
|
|
3401
|
+
const webViewRef = useRef(null);
|
|
3333
3402
|
const onErrorRef = useRef(onError);
|
|
3334
3403
|
onErrorRef.current = onError;
|
|
3335
3404
|
const onReadyRef = useRef(onReady);
|
|
@@ -3373,6 +3442,15 @@ function PaywallWebView({
|
|
|
3373
3442
|
});
|
|
3374
3443
|
}
|
|
3375
3444
|
}, []);
|
|
3445
|
+
const injectScript = useCallback((script) => {
|
|
3446
|
+
if (Platform9.OS === "android") {
|
|
3447
|
+
const handle = findNodeHandle(webViewRef.current);
|
|
3448
|
+
if (handle == null) return;
|
|
3449
|
+
UIManager.dispatchViewManagerCommand(handle, "injectJavaScript", [script]);
|
|
3450
|
+
return;
|
|
3451
|
+
}
|
|
3452
|
+
setScriptToInject(script);
|
|
3453
|
+
}, []);
|
|
3376
3454
|
const buildAndSetInjectionScript = useCallback(() => {
|
|
3377
3455
|
if (!craftData || paywallDataSent.current) return;
|
|
3378
3456
|
paywallDataSent.current = true;
|
|
@@ -3382,8 +3460,8 @@ function PaywallWebView({
|
|
|
3382
3460
|
primaryProductId,
|
|
3383
3461
|
secondaryProductId
|
|
3384
3462
|
});
|
|
3385
|
-
|
|
3386
|
-
}, [craftData, products, primaryProductId, secondaryProductId]);
|
|
3463
|
+
injectScript(script);
|
|
3464
|
+
}, [craftData, products, primaryProductId, secondaryProductId, injectScript]);
|
|
3387
3465
|
const processedIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
3388
3466
|
const dedupeTimersRef = useRef(/* @__PURE__ */ new Map());
|
|
3389
3467
|
useEffect(() => {
|
|
@@ -3420,6 +3498,9 @@ function PaywallWebView({
|
|
|
3420
3498
|
case "restore":
|
|
3421
3499
|
onRestore();
|
|
3422
3500
|
break;
|
|
3501
|
+
case "select-product":
|
|
3502
|
+
console.log("[Paywallo:PaywallWebView] select-product received", message.payload?.productId);
|
|
3503
|
+
break;
|
|
3423
3504
|
case "open-url":
|
|
3424
3505
|
if (message.payload?.url) {
|
|
3425
3506
|
const url = message.payload.url;
|
|
@@ -3428,6 +3509,9 @@ function PaywallWebView({
|
|
|
3428
3509
|
}
|
|
3429
3510
|
}
|
|
3430
3511
|
break;
|
|
3512
|
+
case "haptic":
|
|
3513
|
+
void triggerNativeHaptic(message.payload?.style ?? "light");
|
|
3514
|
+
break;
|
|
3431
3515
|
}
|
|
3432
3516
|
},
|
|
3433
3517
|
[buildAndSetInjectionScript, onPurchase, onClose, onRestore]
|
|
@@ -3499,13 +3583,24 @@ function PaywallWebView({
|
|
|
3499
3583
|
);
|
|
3500
3584
|
useEffect(() => {
|
|
3501
3585
|
if (!paywallDataSent.current) return;
|
|
3502
|
-
|
|
3503
|
-
}, [isPurchasing]);
|
|
3586
|
+
injectScript(buildPurchaseStateScript(isPurchasing));
|
|
3587
|
+
}, [isPurchasing, injectScript]);
|
|
3588
|
+
useEffect(() => {
|
|
3589
|
+
if (Platform9.OS !== "android") return;
|
|
3590
|
+
const onBackPress = () => {
|
|
3591
|
+
if (!paywallDataSent.current) return false;
|
|
3592
|
+
injectScript(buildBackButtonScript());
|
|
3593
|
+
return true;
|
|
3594
|
+
};
|
|
3595
|
+
const subscription = BackHandler.addEventListener("hardwareBackPress", onBackPress);
|
|
3596
|
+
return () => subscription.remove();
|
|
3597
|
+
}, [injectScript]);
|
|
3504
3598
|
if (!resolvedWebUrl || !NativeWebView) return null;
|
|
3505
3599
|
const paywallUrl = `${resolvedWebUrl}/paywall/${paywallId}`;
|
|
3506
3600
|
return /* @__PURE__ */ jsx(View, { style: styles.container, children: /* @__PURE__ */ jsx(
|
|
3507
3601
|
NativeWebView,
|
|
3508
3602
|
{
|
|
3603
|
+
ref: webViewRef,
|
|
3509
3604
|
sourceUrl: paywallUrl,
|
|
3510
3605
|
injectedJavaScript: scriptToInject,
|
|
3511
3606
|
onMessage: handleMessage,
|
|
@@ -3588,7 +3683,7 @@ __export(NativeStoreKit_exports, {
|
|
|
3588
3683
|
NativeStoreKit: () => NativeStoreKit,
|
|
3589
3684
|
nativeStoreKit: () => nativeStoreKit
|
|
3590
3685
|
});
|
|
3591
|
-
import { NativeEventEmitter as NativeEventEmitter3, NativeModules as NativeModules7, Platform as
|
|
3686
|
+
import { NativeEventEmitter as NativeEventEmitter3, NativeModules as NativeModules7, Platform as Platform10 } from "react-native";
|
|
3592
3687
|
function isAvailable3() {
|
|
3593
3688
|
return PaywalloStoreKitNative != null;
|
|
3594
3689
|
}
|
|
@@ -3661,7 +3756,7 @@ function mapNativePurchase(native) {
|
|
|
3661
3756
|
transactionId: native.transactionId,
|
|
3662
3757
|
transactionDate: native.transactionDate,
|
|
3663
3758
|
receipt: native.receipt,
|
|
3664
|
-
platform:
|
|
3759
|
+
platform: Platform10.OS
|
|
3665
3760
|
};
|
|
3666
3761
|
}
|
|
3667
3762
|
function normalizeTransactionUpdate(raw) {
|
|
@@ -3732,7 +3827,7 @@ var init_NativeStoreKit = __esm({
|
|
|
3732
3827
|
try {
|
|
3733
3828
|
await PaywalloStoreKitNative.finishTransaction(transactionId);
|
|
3734
3829
|
} catch (err) {
|
|
3735
|
-
|
|
3830
|
+
console.error("[Paywallo] finishTransaction native error", err);
|
|
3736
3831
|
}
|
|
3737
3832
|
},
|
|
3738
3833
|
async getActiveTransactions() {
|
|
@@ -3741,7 +3836,7 @@ var init_NativeStoreKit = __esm({
|
|
|
3741
3836
|
const results = await PaywalloStoreKitNative.getActiveTransactions();
|
|
3742
3837
|
return results.map(mapNativePurchase);
|
|
3743
3838
|
} catch (err) {
|
|
3744
|
-
|
|
3839
|
+
console.error("[Paywallo] getActiveTransactions failed", err);
|
|
3745
3840
|
return [];
|
|
3746
3841
|
}
|
|
3747
3842
|
},
|
|
@@ -4592,7 +4687,7 @@ var init_QueueProcessor = __esm({
|
|
|
4592
4687
|
}
|
|
4593
4688
|
const allItems = offlineQueue.getQueue();
|
|
4594
4689
|
const eventItems = allItems.filter(
|
|
4595
|
-
(i) =>
|
|
4690
|
+
(i) => i.url.includes("/events") || i.url.includes("/ingest")
|
|
4596
4691
|
);
|
|
4597
4692
|
const eventItemIds = new Set(eventItems.map((i) => i.id));
|
|
4598
4693
|
const { processed: batchProcessed, failed: batchFailed, retryIds } = await this.processEventBatches(eventItems);
|
|
@@ -4632,12 +4727,24 @@ var init_QueueProcessor = __esm({
|
|
|
4632
4727
|
const freshHeaders = this.config.getFreshHeaders?.() ?? {};
|
|
4633
4728
|
const headers = { ...persistedHeaders, ...freshHeaders };
|
|
4634
4729
|
this.log("Sending event batch", { size: batch.length, batchIndex: Math.floor(i / BATCH_SIZE) });
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4730
|
+
let response;
|
|
4731
|
+
try {
|
|
4732
|
+
response = await this.httpClient.request("/sdk/ingest/batch", {
|
|
4733
|
+
method: "POST",
|
|
4734
|
+
body: { events: bodies },
|
|
4735
|
+
headers,
|
|
4736
|
+
skipRetry: false
|
|
4737
|
+
});
|
|
4738
|
+
} catch (error) {
|
|
4739
|
+
for (const item of batch) {
|
|
4740
|
+
retryIds.add(item.id);
|
|
4741
|
+
}
|
|
4742
|
+
this.log("Event batch threw network error - will retry", {
|
|
4743
|
+
size: batch.length,
|
|
4744
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4745
|
+
});
|
|
4746
|
+
continue;
|
|
4747
|
+
}
|
|
4641
4748
|
if (response.ok) {
|
|
4642
4749
|
for (const item of batch) {
|
|
4643
4750
|
await offlineQueue.removeItem(item.id);
|
|
@@ -4677,12 +4784,21 @@ var init_QueueProcessor = __esm({
|
|
|
4677
4784
|
});
|
|
4678
4785
|
const persistedHeaders = item.headers ?? {};
|
|
4679
4786
|
const freshHeaders = this.config.getFreshHeaders?.() ?? {};
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4787
|
+
let response;
|
|
4788
|
+
try {
|
|
4789
|
+
response = await this.httpClient.request(item.url, {
|
|
4790
|
+
method: item.method,
|
|
4791
|
+
body: item.body,
|
|
4792
|
+
headers: { ...persistedHeaders, ...freshHeaders },
|
|
4793
|
+
skipRetry: false
|
|
4794
|
+
});
|
|
4795
|
+
} catch (error) {
|
|
4796
|
+
this.log("Request threw network error - will retry", {
|
|
4797
|
+
id: item.id,
|
|
4798
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4799
|
+
});
|
|
4800
|
+
return { success: false, permanent: false };
|
|
4801
|
+
}
|
|
4686
4802
|
if (response.ok) {
|
|
4687
4803
|
this.log("Queue item processed successfully", { id: item.id });
|
|
4688
4804
|
return { success: true, permanent: false };
|
|
@@ -4757,7 +4873,7 @@ var init_queue = __esm({
|
|
|
4757
4873
|
});
|
|
4758
4874
|
|
|
4759
4875
|
// src/domains/iap/IAPValidator.ts
|
|
4760
|
-
import { Platform as
|
|
4876
|
+
import { Platform as Platform11 } from "react-native";
|
|
4761
4877
|
var IAPValidator;
|
|
4762
4878
|
var init_IAPValidator = __esm({
|
|
4763
4879
|
"src/domains/iap/IAPValidator.ts"() {
|
|
@@ -4787,7 +4903,7 @@ var init_IAPValidator = __esm({
|
|
|
4787
4903
|
async validateWithServer(purchase, productId, options) {
|
|
4788
4904
|
const apiClient = this.getApiClientFn();
|
|
4789
4905
|
const product = this.getProductFromCache(productId);
|
|
4790
|
-
const platform =
|
|
4906
|
+
const platform = Platform11.OS;
|
|
4791
4907
|
const distinctId = PaywalloClient.getDistinctId();
|
|
4792
4908
|
return this.validateWithRetry(
|
|
4793
4909
|
() => apiClient.validatePurchase(
|
|
@@ -4822,24 +4938,24 @@ var init_IAPValidator = __esm({
|
|
|
4822
4938
|
try {
|
|
4823
4939
|
const apiClient = this.getApiClientFn();
|
|
4824
4940
|
const product = this.getProductFromCache(productId);
|
|
4825
|
-
const platform =
|
|
4941
|
+
const platform = Platform11.OS;
|
|
4826
4942
|
const distinctId = PaywalloClient.getDistinctId();
|
|
4827
4943
|
const appKey = apiClient.getAppKey();
|
|
4828
4944
|
const body = {
|
|
4829
4945
|
platform,
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4946
|
+
receipt_data: purchase.receipt,
|
|
4947
|
+
product_id: purchase.productId,
|
|
4948
|
+
transaction_id: purchase.transactionId,
|
|
4949
|
+
price_local: product?.priceValue ?? 0,
|
|
4834
4950
|
currency: product?.currency ?? "USD",
|
|
4835
4951
|
country: this.getDeviceCountry(),
|
|
4836
|
-
distinctId
|
|
4952
|
+
distinct_id: distinctId
|
|
4837
4953
|
};
|
|
4838
|
-
if (options?.paywallPlacement !== void 0) body.
|
|
4839
|
-
if (options?.variantKey !== void 0) body.
|
|
4954
|
+
if (options?.paywallPlacement !== void 0) body.paywall_placement = options.paywallPlacement;
|
|
4955
|
+
if (options?.variantKey !== void 0) body.variant_key = options.variantKey;
|
|
4840
4956
|
await offlineQueue.enqueue(
|
|
4841
4957
|
"POST",
|
|
4842
|
-
"/purchases/validate",
|
|
4958
|
+
"/sdk/purchases/validate",
|
|
4843
4959
|
body,
|
|
4844
4960
|
{ "X-App-Key": appKey },
|
|
4845
4961
|
`validate:${purchase.transactionId}`,
|
|
@@ -4847,7 +4963,7 @@ var init_IAPValidator = __esm({
|
|
|
4847
4963
|
);
|
|
4848
4964
|
if (this.getDebug()) console.log("[Paywallo PURCHASE] validation retry enqueued", purchase.transactionId);
|
|
4849
4965
|
} catch (err) {
|
|
4850
|
-
|
|
4966
|
+
console.error("[Paywallo PURCHASE] failed to enqueue validation retry", err);
|
|
4851
4967
|
}
|
|
4852
4968
|
}
|
|
4853
4969
|
};
|
|
@@ -4855,7 +4971,7 @@ var init_IAPValidator = __esm({
|
|
|
4855
4971
|
});
|
|
4856
4972
|
|
|
4857
4973
|
// src/domains/iap/IAPService.ts
|
|
4858
|
-
import { Platform as
|
|
4974
|
+
import { Platform as Platform12 } from "react-native";
|
|
4859
4975
|
function getIAPService() {
|
|
4860
4976
|
if (!_instance) {
|
|
4861
4977
|
_instance = new IAPService();
|
|
@@ -4926,7 +5042,7 @@ var init_IAPService = __esm({
|
|
|
4926
5042
|
}
|
|
4927
5043
|
return products;
|
|
4928
5044
|
} catch (err) {
|
|
4929
|
-
|
|
5045
|
+
console.error("[Paywallo] loadProducts failed", err);
|
|
4930
5046
|
return [];
|
|
4931
5047
|
}
|
|
4932
5048
|
}
|
|
@@ -4945,7 +5061,7 @@ var init_IAPService = __esm({
|
|
|
4945
5061
|
await nativeStoreKit.finishTransaction(transactionId);
|
|
4946
5062
|
this.finishedTransactions.add(transactionId);
|
|
4947
5063
|
} catch (err) {
|
|
4948
|
-
|
|
5064
|
+
console.error("[Paywallo] finishTransaction failed", err);
|
|
4949
5065
|
}
|
|
4950
5066
|
}
|
|
4951
5067
|
startTransactionListener() {
|
|
@@ -4994,7 +5110,7 @@ var init_IAPService = __esm({
|
|
|
4994
5110
|
await this.finishTransaction(purchase.transactionId);
|
|
4995
5111
|
return;
|
|
4996
5112
|
}
|
|
4997
|
-
|
|
5113
|
+
console.error("[Paywallo PURCHASE] background validation failed (network) \u2014 queued for retry", err);
|
|
4998
5114
|
await this.validator.enqueueValidationRetry(purchase, productId, {
|
|
4999
5115
|
paywallPlacement: options?.paywallPlacement,
|
|
5000
5116
|
variantKey: options?.variantKey
|
|
@@ -5002,7 +5118,7 @@ var init_IAPService = __esm({
|
|
|
5002
5118
|
});
|
|
5003
5119
|
return { success: true, purchase };
|
|
5004
5120
|
} catch (error) {
|
|
5005
|
-
|
|
5121
|
+
console.error(`[Paywallo PURCHASE] ${productId} failed`, error);
|
|
5006
5122
|
const e = error instanceof PurchaseError ? error : new PurchaseError(PURCHASE_ERROR_CODES.PURCHASE_FAILED, error instanceof Error ? error.message : String(error));
|
|
5007
5123
|
return { success: false, error: e };
|
|
5008
5124
|
} finally {
|
|
@@ -5015,7 +5131,7 @@ var init_IAPService = __esm({
|
|
|
5015
5131
|
const transactions = await nativeStoreKit.getActiveTransactions();
|
|
5016
5132
|
const apiClient = this.getApiClient();
|
|
5017
5133
|
const distinctId = PaywalloClient.getDistinctId();
|
|
5018
|
-
const platform =
|
|
5134
|
+
const platform = Platform12.OS;
|
|
5019
5135
|
const results = await Promise.allSettled(
|
|
5020
5136
|
transactions.map((tx) => {
|
|
5021
5137
|
const product = this.productsCache.get(tx.productId);
|
|
@@ -5046,7 +5162,7 @@ var init_IAPService = __esm({
|
|
|
5046
5162
|
if (this.debug) console.log("[Paywallo RESTORE] validation rejected (4xx) \u2014 dropping", tx.transactionId);
|
|
5047
5163
|
await this.finishTransaction(tx.transactionId);
|
|
5048
5164
|
} else {
|
|
5049
|
-
|
|
5165
|
+
console.error("[Paywallo RESTORE] validation failed (network) \u2014 queued for retry", r.reason);
|
|
5050
5166
|
await this.validator.enqueueValidationRetry(tx, tx.productId);
|
|
5051
5167
|
}
|
|
5052
5168
|
} else if (r.status === "fulfilled" && !r.value.success) {
|
|
@@ -5056,7 +5172,7 @@ var init_IAPService = __esm({
|
|
|
5056
5172
|
}
|
|
5057
5173
|
return validated;
|
|
5058
5174
|
} catch (err) {
|
|
5059
|
-
|
|
5175
|
+
console.error("[Paywallo] restore failed", err);
|
|
5060
5176
|
return [];
|
|
5061
5177
|
}
|
|
5062
5178
|
}
|
|
@@ -5272,7 +5388,7 @@ function usePaywallLoader(placement, visible, preloadedConfig, preloadedProducts
|
|
|
5272
5388
|
setProducts(map);
|
|
5273
5389
|
}
|
|
5274
5390
|
} catch (err) {
|
|
5275
|
-
|
|
5391
|
+
console.error("[Paywallo] loadProducts in paywall failed", err);
|
|
5276
5392
|
if (!cancelled) setProducts(/* @__PURE__ */ new Map());
|
|
5277
5393
|
}
|
|
5278
5394
|
} else {
|
|
@@ -6406,11 +6522,9 @@ var init_SubscriptionManager = __esm({
|
|
|
6406
6522
|
if (!this.config) {
|
|
6407
6523
|
return this.getEmptyStatus();
|
|
6408
6524
|
}
|
|
6409
|
-
const
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
}
|
|
6413
|
-
const response = await fetch(url.toString(), {
|
|
6525
|
+
const userId = this.userId ?? "";
|
|
6526
|
+
const url = `${this.config.serverUrl}/sdk/purchases/status?distinctId=${encodeURIComponent(userId)}`;
|
|
6527
|
+
const response = await fetch(url, {
|
|
6414
6528
|
method: "GET",
|
|
6415
6529
|
headers: {
|
|
6416
6530
|
"Content-Type": "application/json",
|
|
@@ -6423,17 +6537,32 @@ var init_SubscriptionManager = __esm({
|
|
|
6423
6537
|
`Failed to fetch subscription status: ${response.status}`
|
|
6424
6538
|
);
|
|
6425
6539
|
}
|
|
6426
|
-
const
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6540
|
+
const envelope = await response.json();
|
|
6541
|
+
const raw = envelope.data ?? envelope;
|
|
6542
|
+
const data = {
|
|
6543
|
+
hasActiveSubscription: !!(raw["has_active_subscription"] ?? raw["hasActiveSubscription"]),
|
|
6544
|
+
subscription: null,
|
|
6545
|
+
entitlements: raw["entitlements"] ?? []
|
|
6546
|
+
};
|
|
6547
|
+
const sub = raw["subscription"];
|
|
6548
|
+
if (sub) {
|
|
6549
|
+
const cancellationRaw = sub["cancellationDate"] ?? sub["cancellation_date"];
|
|
6550
|
+
const gracePeriodRaw = sub["gracePeriodExpiresAt"] ?? sub["grace_period_expires_at"];
|
|
6551
|
+
data.subscription = {
|
|
6552
|
+
id: sub["id"],
|
|
6553
|
+
productId: sub["product_id"] ?? sub["productId"],
|
|
6554
|
+
status: sub["status"],
|
|
6555
|
+
expiresAt: new Date(sub["expires_at"] ?? sub["expiresAt"]),
|
|
6556
|
+
originalPurchaseDate: new Date(sub["originalPurchaseDate"] ?? sub["original_purchase_date"]),
|
|
6557
|
+
latestPurchaseDate: new Date(sub["latestPurchaseDate"] ?? sub["latest_purchase_date"]),
|
|
6558
|
+
willRenew: !!(sub["will_renew"] ?? sub["willRenew"] ?? sub["auto_renew_enabled"] ?? sub["autoRenewEnabled"]),
|
|
6559
|
+
isTrial: !!(sub["is_trial"] ?? sub["isTrial"]),
|
|
6560
|
+
isIntroductoryPeriod: !!(sub["is_introductory_period"] ?? sub["isIntroductoryPeriod"]),
|
|
6561
|
+
platform: sub["platform"],
|
|
6562
|
+
storeTransactionId: sub["store_transaction_id"] ?? sub["storeTransactionId"],
|
|
6563
|
+
cancellationDate: cancellationRaw ? new Date(cancellationRaw) : void 0,
|
|
6564
|
+
gracePeriodExpiresAt: gracePeriodRaw ? new Date(gracePeriodRaw) : void 0
|
|
6565
|
+
};
|
|
6437
6566
|
}
|
|
6438
6567
|
return data;
|
|
6439
6568
|
}
|
|
@@ -6471,15 +6600,15 @@ async function validatePurchase(client, appKey, platform, receipt, productId, tr
|
|
|
6471
6600
|
"/sdk/purchases/validate",
|
|
6472
6601
|
{
|
|
6473
6602
|
platform,
|
|
6474
|
-
receipt,
|
|
6475
|
-
productId,
|
|
6476
|
-
transactionId,
|
|
6477
|
-
priceLocal,
|
|
6603
|
+
receipt_data: receipt,
|
|
6604
|
+
product_id: productId,
|
|
6605
|
+
transaction_id: transactionId,
|
|
6606
|
+
price_local: priceLocal,
|
|
6478
6607
|
currency,
|
|
6479
6608
|
country,
|
|
6480
|
-
distinctId,
|
|
6481
|
-
...paywallPlacement !== void 0 && { paywallPlacement },
|
|
6482
|
-
...variantKey !== void 0 && { variantKey }
|
|
6609
|
+
distinct_id: distinctId,
|
|
6610
|
+
...paywallPlacement !== void 0 && { paywall_placement: paywallPlacement },
|
|
6611
|
+
...variantKey !== void 0 && { variant_key: variantKey }
|
|
6483
6612
|
},
|
|
6484
6613
|
false
|
|
6485
6614
|
);
|
|
@@ -6491,7 +6620,7 @@ async function validatePurchase(client, appKey, platform, receipt, productId, tr
|
|
|
6491
6620
|
response.status
|
|
6492
6621
|
);
|
|
6493
6622
|
}
|
|
6494
|
-
return response.data;
|
|
6623
|
+
return response.data.data;
|
|
6495
6624
|
}
|
|
6496
6625
|
async function getSubscriptionStatus(client, baseUrl, appKey, distinctId) {
|
|
6497
6626
|
const url = new URL(`${baseUrl}/sdk/purchases/status`);
|
|
@@ -6500,7 +6629,7 @@ async function getSubscriptionStatus(client, baseUrl, appKey, distinctId) {
|
|
|
6500
6629
|
if (!response.ok) {
|
|
6501
6630
|
throw new PurchaseError(PURCHASE_ERROR_CODES.NETWORK_ERROR, `Subscription status check failed: HTTP ${response.status}`);
|
|
6502
6631
|
}
|
|
6503
|
-
return response.data;
|
|
6632
|
+
return response.data.data;
|
|
6504
6633
|
}
|
|
6505
6634
|
async function getEmergencyPaywall(client) {
|
|
6506
6635
|
try {
|
|
@@ -6709,7 +6838,7 @@ async function evaluateFlags2(deps, keys, distinctId) {
|
|
|
6709
6838
|
const result = {};
|
|
6710
6839
|
for (const key of Object.keys(record)) {
|
|
6711
6840
|
const value = record[key];
|
|
6712
|
-
const variant = typeof value === "
|
|
6841
|
+
const variant = typeof value === "string" ? value : null;
|
|
6713
6842
|
result[key] = variant;
|
|
6714
6843
|
const flagVariant = { variant };
|
|
6715
6844
|
deps.cache.setVariant(`${key}:${distinctId}`, flagVariant);
|
|
@@ -6947,7 +7076,7 @@ var init_eventFamilies = __esm({
|
|
|
6947
7076
|
});
|
|
6948
7077
|
|
|
6949
7078
|
// src/core/eventEnvelopeV2.ts
|
|
6950
|
-
import { Platform as
|
|
7079
|
+
import { Platform as Platform13 } from "react-native";
|
|
6951
7080
|
import { z as z2 } from "zod";
|
|
6952
7081
|
function buildV2Envelope(events, providerContext) {
|
|
6953
7082
|
const context = { ...providerContext };
|
|
@@ -6971,7 +7100,7 @@ function buildV2Envelope(events, providerContext) {
|
|
|
6971
7100
|
};
|
|
6972
7101
|
});
|
|
6973
7102
|
if (context.sdk_version === void 0) context.sdk_version = SDK_VERSION;
|
|
6974
|
-
if (context.platform === void 0) context.platform =
|
|
7103
|
+
if (context.platform === void 0) context.platform = Platform13.OS;
|
|
6975
7104
|
if (context.distinct_id === void 0 && events.length > 0) {
|
|
6976
7105
|
context.distinct_id = events[0].distinctId;
|
|
6977
7106
|
}
|
|
@@ -7022,7 +7151,7 @@ var init_eventEnvelopeV2 = __esm({
|
|
|
7022
7151
|
payload: z2.record(z2.string(), z2.unknown())
|
|
7023
7152
|
});
|
|
7024
7153
|
v2ContextSchema = z2.object({
|
|
7025
|
-
distinct_id: z2.string().
|
|
7154
|
+
distinct_id: z2.string().min(1),
|
|
7026
7155
|
session_id: z2.string().optional(),
|
|
7027
7156
|
device_id: z2.string().optional(),
|
|
7028
7157
|
app_version: z2.string().optional(),
|
|
@@ -7065,8 +7194,8 @@ var init_events = __esm({
|
|
|
7065
7194
|
});
|
|
7066
7195
|
|
|
7067
7196
|
// src/core/EventBatcher.ts
|
|
7068
|
-
import { Platform as
|
|
7069
|
-
var BATCH_MAX_SIZE, BATCH_FLUSH_MS, EVENT_NAME_REGEX, V2_BATCH_ENDPOINT,
|
|
7197
|
+
import { Platform as Platform14 } from "react-native";
|
|
7198
|
+
var BATCH_MAX_SIZE, BATCH_FLUSH_MS, EVENT_NAME_REGEX, V2_BATCH_ENDPOINT, EventBatcher;
|
|
7070
7199
|
var init_EventBatcher = __esm({
|
|
7071
7200
|
"src/core/EventBatcher.ts"() {
|
|
7072
7201
|
"use strict";
|
|
@@ -7076,15 +7205,12 @@ var init_EventBatcher = __esm({
|
|
|
7076
7205
|
BATCH_FLUSH_MS = 1e4;
|
|
7077
7206
|
EVENT_NAME_REGEX = /^(\$[a-zA-Z0-9_]+|[a-z][a-z0-9_]*)$/;
|
|
7078
7207
|
V2_BATCH_ENDPOINT = "/sdk/ingest/batch";
|
|
7079
|
-
V1_BATCH_ENDPOINT = "/sdk/events/batch";
|
|
7080
|
-
V1_SINGLE_ENDPOINT = "/sdk/events";
|
|
7081
7208
|
EventBatcher = class {
|
|
7082
7209
|
constructor(post, debug = false, contextProvider = null) {
|
|
7083
7210
|
this.criticalQueue = [];
|
|
7084
7211
|
this.normalQueue = [];
|
|
7085
7212
|
this.normalTimer = null;
|
|
7086
7213
|
this.criticalScheduled = false;
|
|
7087
|
-
this.v2Disabled = false;
|
|
7088
7214
|
this.post = post;
|
|
7089
7215
|
this.debug = debug;
|
|
7090
7216
|
this.contextProvider = contextProvider;
|
|
@@ -7121,7 +7247,7 @@ var init_EventBatcher = __esm({
|
|
|
7121
7247
|
const event = {
|
|
7122
7248
|
eventName,
|
|
7123
7249
|
distinctId,
|
|
7124
|
-
properties: { ...properties, platform:
|
|
7250
|
+
properties: { ...properties, platform: Platform14.OS },
|
|
7125
7251
|
timestamp: timestamp ?? Date.now(),
|
|
7126
7252
|
environment: environment.toLowerCase()
|
|
7127
7253
|
};
|
|
@@ -7180,11 +7306,7 @@ var init_EventBatcher = __esm({
|
|
|
7180
7306
|
try {
|
|
7181
7307
|
await this.postBatch([event], `event_critical:${event.eventName}`, "critical");
|
|
7182
7308
|
} catch {
|
|
7183
|
-
|
|
7184
|
-
await this.post(V1_SINGLE_ENDPOINT, event, `event:${event.eventName}`, "critical");
|
|
7185
|
-
} catch {
|
|
7186
|
-
if (this.debug) console.log(`[Paywallo] critical event ${event.eventName} post failed`);
|
|
7187
|
-
}
|
|
7309
|
+
if (this.debug) console.log(`[Paywallo] critical event ${event.eventName} post failed`);
|
|
7188
7310
|
}
|
|
7189
7311
|
}
|
|
7190
7312
|
}
|
|
@@ -7198,50 +7320,24 @@ var init_EventBatcher = __esm({
|
|
|
7198
7320
|
try {
|
|
7199
7321
|
await this.postBatch(batch, `event_batch:${batch.length}`);
|
|
7200
7322
|
} catch {
|
|
7201
|
-
|
|
7202
|
-
await this.post(V1_SINGLE_ENDPOINT, event, `event:${event.eventName}`);
|
|
7203
|
-
}
|
|
7323
|
+
if (this.debug) console.log(`[Paywallo] normal batch post failed \u2014 OfflineQueue will handle durability`);
|
|
7204
7324
|
}
|
|
7205
7325
|
}
|
|
7206
|
-
/**
|
|
7207
|
-
* POST the batch with V2 envelope semantics. Tries `/ingest/batch`
|
|
7208
|
-
* first; on failure (404/network) falls back to `/events/batch`
|
|
7209
|
-
* with the legacy per-event shape for retrocompat.
|
|
7210
|
-
*
|
|
7211
|
-
* After a single V2 failure we flip `v2Disabled` and stop trying V2 for
|
|
7212
|
-
* the lifetime of this EventBatcher — avoids N retries per batch on old
|
|
7213
|
-
* servers that will never have the endpoint. A fresh `new EventBatcher()`
|
|
7214
|
-
* (e.g. after `Paywallo.init` on a new server URL) resets the flag.
|
|
7215
|
-
*/
|
|
7216
7326
|
async postBatch(events, label, priority = "normal") {
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
if (this.debug) console.log("[Paywallo EVENTS] V2 envelope schema validation failed:", parsed.error.issues);
|
|
7230
|
-
throw parsed.error;
|
|
7231
|
-
}
|
|
7232
|
-
await this.post(V2_BATCH_ENDPOINT, parsed.data, label, priority);
|
|
7233
|
-
return;
|
|
7234
|
-
} catch (error) {
|
|
7235
|
-
this.v2Disabled = true;
|
|
7236
|
-
if (this.debug) {
|
|
7237
|
-
console.log(
|
|
7238
|
-
"[Paywallo EVENTS] V2 ingest unavailable, falling back to /events/batch:",
|
|
7239
|
-
error
|
|
7240
|
-
);
|
|
7241
|
-
}
|
|
7242
|
-
}
|
|
7327
|
+
const providerContext = resolveProviderContext(this.contextProvider);
|
|
7328
|
+
const inputs = events.map((e) => ({
|
|
7329
|
+
eventName: e.eventName,
|
|
7330
|
+
distinctId: e.distinctId,
|
|
7331
|
+
properties: e.properties,
|
|
7332
|
+
timestamp: e.timestamp
|
|
7333
|
+
}));
|
|
7334
|
+
const envelope = buildV2Envelope(inputs, providerContext);
|
|
7335
|
+
const parsed = v2EnvelopeSchema.safeParse(envelope);
|
|
7336
|
+
if (!parsed.success) {
|
|
7337
|
+
if (this.debug) console.log("[Paywallo EVENTS] V2 envelope schema validation failed:", parsed.error.issues);
|
|
7338
|
+
throw parsed.error;
|
|
7243
7339
|
}
|
|
7244
|
-
await this.post(
|
|
7340
|
+
await this.post(V2_BATCH_ENDPOINT, parsed.data, label, priority);
|
|
7245
7341
|
}
|
|
7246
7342
|
};
|
|
7247
7343
|
}
|
|
@@ -7476,7 +7572,7 @@ var init_http = __esm({
|
|
|
7476
7572
|
});
|
|
7477
7573
|
|
|
7478
7574
|
// src/core/ApiClient.ts
|
|
7479
|
-
import { Platform as
|
|
7575
|
+
import { Platform as Platform15 } from "react-native";
|
|
7480
7576
|
var ApiClient;
|
|
7481
7577
|
var init_ApiClient = __esm({
|
|
7482
7578
|
"src/core/ApiClient.ts"() {
|
|
@@ -7582,7 +7678,7 @@ var init_ApiClient = __esm({
|
|
|
7582
7678
|
buildSdkHeaders() {
|
|
7583
7679
|
return {
|
|
7584
7680
|
"x-sdk-version": SDK_VERSION,
|
|
7585
|
-
"x-sdk-platform":
|
|
7681
|
+
"x-sdk-platform": Platform15.OS,
|
|
7586
7682
|
"x-sdk-environment": this.environment
|
|
7587
7683
|
};
|
|
7588
7684
|
}
|
|
@@ -7612,7 +7708,7 @@ var init_ApiClient = __esm({
|
|
|
7612
7708
|
message,
|
|
7613
7709
|
context,
|
|
7614
7710
|
sdkVersion: SDK_VERSION,
|
|
7615
|
-
platform:
|
|
7711
|
+
platform: Platform15.OS
|
|
7616
7712
|
}, true);
|
|
7617
7713
|
} catch (err) {
|
|
7618
7714
|
if (this.debug) console.log("[Paywallo:ApiClient] reportError failed", err);
|
|
@@ -7628,6 +7724,26 @@ var init_ApiClient = __esm({
|
|
|
7628
7724
|
this.batcher.dispose();
|
|
7629
7725
|
}
|
|
7630
7726
|
async identify(distinctId, properties, email, deviceId, pii) {
|
|
7727
|
+
const rawTraits = {
|
|
7728
|
+
email: email || void 0,
|
|
7729
|
+
platform: Platform15.OS,
|
|
7730
|
+
name: properties?.name,
|
|
7731
|
+
country: properties?.country,
|
|
7732
|
+
locale: properties?.locale,
|
|
7733
|
+
app_version: properties?.appVersion ?? properties?.["app_version"]
|
|
7734
|
+
};
|
|
7735
|
+
const traits = Object.fromEntries(
|
|
7736
|
+
Object.entries(rawTraits).filter(([, v]) => v !== void 0)
|
|
7737
|
+
);
|
|
7738
|
+
const attributionKeys = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content", "fbclid", "gclid", "ttclid", "referrer"];
|
|
7739
|
+
const rawAttribution = {};
|
|
7740
|
+
if (properties) {
|
|
7741
|
+
for (const key of attributionKeys) {
|
|
7742
|
+
const val = properties[key];
|
|
7743
|
+
if (val !== void 0) rawAttribution[key] = val;
|
|
7744
|
+
}
|
|
7745
|
+
}
|
|
7746
|
+
const attribution = Object.keys(rawAttribution).length > 0 ? rawAttribution : void 0;
|
|
7631
7747
|
await postWithQueue(
|
|
7632
7748
|
{
|
|
7633
7749
|
isOfflineQueueEnabled: () => this.offlineQueueEnabled,
|
|
@@ -7635,12 +7751,11 @@ var init_ApiClient = __esm({
|
|
|
7635
7751
|
isDebug: () => this.debug,
|
|
7636
7752
|
post: (path, body, skipRetry) => this.post(path, body, skipRetry)
|
|
7637
7753
|
},
|
|
7638
|
-
"/sdk/identify",
|
|
7754
|
+
"/sdk/identity/identify",
|
|
7639
7755
|
{
|
|
7640
|
-
distinctId,
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
platform: Platform14.OS,
|
|
7756
|
+
distinct_id: distinctId,
|
|
7757
|
+
traits,
|
|
7758
|
+
...attribution && { attribution },
|
|
7644
7759
|
...deviceId && { deviceId },
|
|
7645
7760
|
...pii?.phone && { phone: pii.phone },
|
|
7646
7761
|
...pii?.firstName && { firstName: pii.firstName },
|
|
@@ -7651,10 +7766,9 @@ var init_ApiClient = __esm({
|
|
|
7651
7766
|
"identify"
|
|
7652
7767
|
);
|
|
7653
7768
|
}
|
|
7654
|
-
// Session lifecycle endpoints
|
|
7655
|
-
//
|
|
7656
|
-
//
|
|
7657
|
-
// EventBatcher pipeline.
|
|
7769
|
+
// Session lifecycle endpoints were dropped. All session bookkeeping is now
|
|
7770
|
+
// derived on the server from `$session_start` and `session.end` events that
|
|
7771
|
+
// flow through the unified EventBatcher pipeline.
|
|
7658
7772
|
async getVariant(flagKey, distinctId) {
|
|
7659
7773
|
return getVariant2(this.flagDeps(), flagKey, distinctId);
|
|
7660
7774
|
}
|
|
@@ -7712,7 +7826,7 @@ var init_ApiClient = __esm({
|
|
|
7712
7826
|
const hit = this.cache.getCampaign(key);
|
|
7713
7827
|
if (hit !== void 0) return hit;
|
|
7714
7828
|
try {
|
|
7715
|
-
const res = await this.get(`/
|
|
7829
|
+
const res = await this.get(`/campaigns/public/primary?distinctId=${encodeURIComponent(distinctId)}`);
|
|
7716
7830
|
if (res.status === 404) {
|
|
7717
7831
|
this.cache.setCampaign(key, null, this.cache.nullTTL);
|
|
7718
7832
|
return null;
|
|
@@ -7812,10 +7926,10 @@ function setupNotifications(apiClient, config, environment, eventPipeline) {
|
|
|
7812
7926
|
debug: config.debug,
|
|
7813
7927
|
environment: environment === "Sandbox" ? "sandbox" : "production"
|
|
7814
7928
|
}).catch((err) => {
|
|
7815
|
-
|
|
7929
|
+
console.error("[Paywallo PUSH] initialization warning:", err instanceof Error ? err.message : String(err));
|
|
7816
7930
|
});
|
|
7817
7931
|
} catch (err) {
|
|
7818
|
-
|
|
7932
|
+
console.error("[Paywallo PUSH] setup warning:", err instanceof Error ? err.message : String(err));
|
|
7819
7933
|
}
|
|
7820
7934
|
}
|
|
7821
7935
|
function setupAutoPreload(state, apiClient, config, distinctId) {
|
|
@@ -7940,7 +8054,7 @@ function reportInitFailure(state, config, error, reason) {
|
|
|
7940
8054
|
error: error instanceof Error ? error.message : String(error)
|
|
7941
8055
|
});
|
|
7942
8056
|
} catch (err) {
|
|
7943
|
-
|
|
8057
|
+
console.error("[Paywallo] reportInitFailure error", err);
|
|
7944
8058
|
}
|
|
7945
8059
|
}
|
|
7946
8060
|
function reportInitSuccess(state, config, attempts) {
|
|
@@ -7949,7 +8063,7 @@ function reportInitSuccess(state, config, attempts) {
|
|
|
7949
8063
|
void state.apiClient.reportError("INIT_RECOVERED", `Succeeded after ${attempts} retries`, { attempts });
|
|
7950
8064
|
}
|
|
7951
8065
|
} catch (err) {
|
|
7952
|
-
|
|
8066
|
+
console.error("[Paywallo] reportInitSuccess error", err);
|
|
7953
8067
|
}
|
|
7954
8068
|
}
|
|
7955
8069
|
async function resolveSessionFlags(state, keys, apiClient, distinctId) {
|
|
@@ -8003,7 +8117,7 @@ async function doInit(state, config) {
|
|
|
8003
8117
|
try {
|
|
8004
8118
|
await identityManager.identify(pending);
|
|
8005
8119
|
} catch (err) {
|
|
8006
|
-
|
|
8120
|
+
console.error("[Paywallo INIT] pending identify replay failed", err);
|
|
8007
8121
|
}
|
|
8008
8122
|
}
|
|
8009
8123
|
state.pendingIdentifies = [];
|
|
@@ -8081,7 +8195,7 @@ async function doInit(state, config) {
|
|
|
8081
8195
|
setupNotifications(apiClient, config, environment, eventPipeline);
|
|
8082
8196
|
if (config.autoStartSession !== false) {
|
|
8083
8197
|
sessionManager.startSession().catch((err) => {
|
|
8084
|
-
|
|
8198
|
+
console.error("[Paywallo INIT] autoStart session error", err);
|
|
8085
8199
|
});
|
|
8086
8200
|
}
|
|
8087
8201
|
new InstallTracker(config.debug, {
|
|
@@ -8099,7 +8213,7 @@ async function doInit(state, config) {
|
|
|
8099
8213
|
state.resolveReady();
|
|
8100
8214
|
state.resolveReady = null;
|
|
8101
8215
|
}
|
|
8102
|
-
if (config.debug) console.
|
|
8216
|
+
if (config.debug) console.log("[Paywallo] initialized successfully");
|
|
8103
8217
|
if (distinctId) {
|
|
8104
8218
|
apiClient.getSubscriptionStatus(distinctId).then(() => {
|
|
8105
8219
|
if (config.debug) console.log("[Paywallo SUB] preloaded on boot");
|
|
@@ -8216,7 +8330,7 @@ async function checkActiveSubscription(state) {
|
|
|
8216
8330
|
if (state.config?.debug) console.log("[Paywallo SUB] hasActiveSubscription (server):", isActive);
|
|
8217
8331
|
return isActive;
|
|
8218
8332
|
} catch (error) {
|
|
8219
|
-
|
|
8333
|
+
console.error("[Paywallo SUB] hasActiveSubscription error", error);
|
|
8220
8334
|
if (state.apiClient) void state.apiClient.reportError("SUBSCRIPTION_CHECK_FAILED", error instanceof Error ? error.message : "hasActiveSubscription failed");
|
|
8221
8335
|
return false;
|
|
8222
8336
|
}
|
|
@@ -8537,9 +8651,9 @@ __export(OfferingService_exports, {
|
|
|
8537
8651
|
OfferingService: () => OfferingService,
|
|
8538
8652
|
offeringService: () => offeringService
|
|
8539
8653
|
});
|
|
8540
|
-
import { Platform as
|
|
8654
|
+
import { Platform as Platform16 } from "react-native";
|
|
8541
8655
|
function resolveProductId(raw) {
|
|
8542
|
-
const isIos =
|
|
8656
|
+
const isIos = Platform16.OS === "ios";
|
|
8543
8657
|
const productId = isIos ? raw.apple_product_id : raw.google_product_id;
|
|
8544
8658
|
return productId ?? "";
|
|
8545
8659
|
}
|
|
@@ -8558,7 +8672,7 @@ function mapProduct2(raw) {
|
|
|
8558
8672
|
};
|
|
8559
8673
|
}
|
|
8560
8674
|
function pickPlatformProduct(products) {
|
|
8561
|
-
const isIos =
|
|
8675
|
+
const isIos = Platform16.OS === "ios";
|
|
8562
8676
|
const match = products.find((p) => isIos ? p.apple_product_id : p.google_product_id);
|
|
8563
8677
|
return match ?? products[0] ?? null;
|
|
8564
8678
|
}
|
|
@@ -8682,6 +8796,7 @@ init_PurchaseError();
|
|
|
8682
8796
|
// src/index.ts
|
|
8683
8797
|
init_identity();
|
|
8684
8798
|
init_identity();
|
|
8799
|
+
init_identity();
|
|
8685
8800
|
init_notifications();
|
|
8686
8801
|
|
|
8687
8802
|
// src/domains/offering/index.ts
|
|
@@ -9352,7 +9467,6 @@ function useCampaignPreload() {
|
|
|
9352
9467
|
}
|
|
9353
9468
|
|
|
9354
9469
|
// src/hooks/useProductLoader.ts
|
|
9355
|
-
init_PaywalloClient();
|
|
9356
9470
|
import { useCallback as useCallback16, useState as useState14 } from "react";
|
|
9357
9471
|
function useProductLoader() {
|
|
9358
9472
|
const [products, setProducts] = useState14(/* @__PURE__ */ new Map());
|
|
@@ -9366,7 +9480,7 @@ function useProductLoader() {
|
|
|
9366
9480
|
for (const p of loaded) map.set(p.productId, p);
|
|
9367
9481
|
setProducts(map);
|
|
9368
9482
|
} catch (err) {
|
|
9369
|
-
|
|
9483
|
+
console.error("[Paywallo] refreshProducts failed", err);
|
|
9370
9484
|
} finally {
|
|
9371
9485
|
setIsLoadingProducts(false);
|
|
9372
9486
|
}
|
|
@@ -9375,7 +9489,6 @@ function useProductLoader() {
|
|
|
9375
9489
|
}
|
|
9376
9490
|
|
|
9377
9491
|
// src/hooks/usePurchaseOrchestrator.ts
|
|
9378
|
-
init_PaywalloClient();
|
|
9379
9492
|
import { useCallback as useCallback17 } from "react";
|
|
9380
9493
|
init_paywall();
|
|
9381
9494
|
function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clearPreloadedWebView, setShowingPreloadedWebView, presentedAtRef, invalidateSubscriptionCache) {
|
|
@@ -9410,7 +9523,7 @@ function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clea
|
|
|
9410
9523
|
clearPreloadedWebView();
|
|
9411
9524
|
resolvePreloadedPaywall({ presented: true, purchased: true, cancelled: false, restored: false });
|
|
9412
9525
|
} catch (error) {
|
|
9413
|
-
|
|
9526
|
+
console.error("[Paywallo] preloaded purchase failed", error);
|
|
9414
9527
|
setShowingPreloadedWebView(false);
|
|
9415
9528
|
clearPreloadedWebView();
|
|
9416
9529
|
resolvePreloadedPaywall({ presented: true, purchased: false, cancelled: false, restored: false });
|
|
@@ -9431,7 +9544,7 @@ function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clea
|
|
|
9431
9544
|
clearPreloadedWebView();
|
|
9432
9545
|
resolvePreloadedPaywall({ presented: true, purchased: false, cancelled: false, restored: true });
|
|
9433
9546
|
} catch (error) {
|
|
9434
|
-
|
|
9547
|
+
console.error("[Paywallo] preloaded restore failed", error);
|
|
9435
9548
|
setShowingPreloadedWebView(false);
|
|
9436
9549
|
clearPreloadedWebView();
|
|
9437
9550
|
resolvePreloadedPaywall({ presented: true, purchased: false, cancelled: false, restored: false });
|
|
@@ -10083,6 +10196,7 @@ var Paywallo = PaywalloClient;
|
|
|
10083
10196
|
var index_default = Paywallo;
|
|
10084
10197
|
export {
|
|
10085
10198
|
ApiClient,
|
|
10199
|
+
AttributionTracker,
|
|
10086
10200
|
CAMPAIGN_ERROR_CODES,
|
|
10087
10201
|
CampaignError,
|
|
10088
10202
|
PURCHASE_ERROR_CODES as ERROR_CODES,
|
|
@@ -10117,6 +10231,7 @@ export {
|
|
|
10117
10231
|
SessionError,
|
|
10118
10232
|
SessionManager,
|
|
10119
10233
|
SubscriptionCache,
|
|
10234
|
+
attributionTracker,
|
|
10120
10235
|
createPurchaseError,
|
|
10121
10236
|
index_default as default,
|
|
10122
10237
|
detectDeviceLanguage,
|