@virex-tech/paywallo-sdk 2.6.0 → 2.6.2
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/README.md +11 -0
- package/android/build.gradle +2 -1
- package/android/src/main/AndroidManifest.xml +7 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloAdvertisingIdModule.kt +55 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloSdkPackage.kt +3 -2
- package/android/src/main/java/com/paywallo/sdk/PaywalloStoreKitModule.kt +10 -3
- package/dist/index.d.mts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +288 -200
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +168 -81
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,6 +25,17 @@ npm install expo-tracking-transparency
|
|
|
25
25
|
|
|
26
26
|
This enables the ATT prompt ("Allow this app to track your activity?"). Without it, the SDK skips IDFA collection — everything else works normally.
|
|
27
27
|
|
|
28
|
+
### Optional: Facebook `_fbp` on Android
|
|
29
|
+
|
|
30
|
+
For `fb_anon_id` (the `_fbp` cookie proxy used by Meta attribution) to work correctly on Android, the host app must declare the Facebook Android SDK as a runtime dependency:
|
|
31
|
+
|
|
32
|
+
```gradle
|
|
33
|
+
// android/app/build.gradle
|
|
34
|
+
implementation 'com.facebook.android:facebook-android-sdk:latest.release'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The SDK references the Facebook Android SDK as `compileOnly` (to avoid forcing it on all apps). If the host does **not** include it as `implementation`, `metaBridge.getAnonymousID()` returns `null` and the SDK falls back to a locally-generated `PW_<uuid>`. This local ID is **not recognised by Meta** as a `_fbp` value, so Facebook attribution will not benefit from cookie matching on Android. When debug mode is enabled, the SDK logs a warning when this fallback is triggered.
|
|
38
|
+
|
|
28
39
|
## Quick start
|
|
29
40
|
|
|
30
41
|
### 1. Wrap your app
|
package/android/build.gradle
CHANGED
|
@@ -49,7 +49,7 @@ repositories {
|
|
|
49
49
|
dependencies {
|
|
50
50
|
implementation "com.facebook.react:react-native:+"
|
|
51
51
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:${safeExtGet('kotlinVersion', '2.0.21')}"
|
|
52
|
-
implementation "com.android.billingclient:billing-ktx:
|
|
52
|
+
implementation "com.android.billingclient:billing-ktx:8.0.0"
|
|
53
53
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
|
|
54
54
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
|
|
55
55
|
compileOnly "com.facebook.android:facebook-android-sdk:17.+"
|
|
@@ -57,4 +57,5 @@ dependencies {
|
|
|
57
57
|
// 1.1.0+ required for MasterKey.Builder API used in PaywalloStorageModule.
|
|
58
58
|
// 1.0.0 only ships the deprecated MasterKeys.getOrCreate(...) static helper.
|
|
59
59
|
implementation "androidx.security:security-crypto:1.1.0"
|
|
60
|
+
implementation "com.google.android.gms:play-services-ads-identifier:18.0.1"
|
|
60
61
|
}
|
|
@@ -16,6 +16,13 @@
|
|
|
16
16
|
-->
|
|
17
17
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
18
18
|
|
|
19
|
+
<!--
|
|
20
|
+
AD_ID (Android 13+) — sem essa permissão o Google Play Services devolve
|
|
21
|
+
o GAID como all-zeros, quebrando o madid do Meta CAPI. O merge de manifest
|
|
22
|
+
propaga pro app host automaticamente.
|
|
23
|
+
-->
|
|
24
|
+
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
|
|
25
|
+
|
|
19
26
|
<application>
|
|
20
27
|
<!--
|
|
21
28
|
PaywalloFirebaseMessagingService handles FCM token refresh and message delivery.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
package com.paywallo.sdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Promise
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
6
|
+
import com.facebook.react.bridge.ReactMethod
|
|
7
|
+
import java.util.concurrent.Executors
|
|
8
|
+
|
|
9
|
+
private val ALL_ZEROS = "00000000-0000-0000-0000-000000000000"
|
|
10
|
+
|
|
11
|
+
class PaywalloAdvertisingIdModule(private val reactContext: ReactApplicationContext) :
|
|
12
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
13
|
+
|
|
14
|
+
private val executor = Executors.newSingleThreadExecutor()
|
|
15
|
+
|
|
16
|
+
override fun getName() = "PaywalloAdvertisingId"
|
|
17
|
+
|
|
18
|
+
// invalidate() is the post-TurboModule replacement for onCatalystInstanceDestroy.
|
|
19
|
+
// Shuts down the background executor to avoid thread leak on bridge reload.
|
|
20
|
+
override fun invalidate() {
|
|
21
|
+
executor.shutdown()
|
|
22
|
+
super.invalidate()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@ReactMethod
|
|
26
|
+
fun getAdvertisingId(promise: Promise) {
|
|
27
|
+
// AdvertisingIdClient.getAdvertisingIdInfo() is blocking and must NOT run
|
|
28
|
+
// on the main thread — run on a background executor instead.
|
|
29
|
+
executor.execute {
|
|
30
|
+
try {
|
|
31
|
+
val info = com.google.android.gms.ads.identifier.AdvertisingIdClient
|
|
32
|
+
.getAdvertisingIdInfo(reactApplicationContext)
|
|
33
|
+
|
|
34
|
+
if (info.isLimitAdTrackingEnabled) {
|
|
35
|
+
// User opted out of ad tracking — honour their choice.
|
|
36
|
+
promise.resolve(null)
|
|
37
|
+
return@execute
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
val id = info.id
|
|
41
|
+
if (id == null || id == ALL_ZEROS) {
|
|
42
|
+
promise.resolve(null)
|
|
43
|
+
} else {
|
|
44
|
+
promise.resolve(id)
|
|
45
|
+
}
|
|
46
|
+
} catch (t: Throwable) {
|
|
47
|
+
// Catches GooglePlayServicesNotAvailableException,
|
|
48
|
+
// GooglePlayServicesRepairableException, NoClassDefFoundError,
|
|
49
|
+
// IOException, and any other runtime failure.
|
|
50
|
+
// Never reject/crash — gracefully return null.
|
|
51
|
+
promise.resolve(null)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -11,8 +11,9 @@ class PaywalloSdkPackage : ReactPackage {
|
|
|
11
11
|
PaywalloStoreKitModule(reactContext),
|
|
12
12
|
PaywalloFBBridgeModule(reactContext),
|
|
13
13
|
PaywalloStorageModule(reactContext),
|
|
14
|
-
PaywalloNotificationsModule(reactContext),
|
|
15
|
-
PaywalloEnvModule(reactContext)
|
|
14
|
+
PaywalloNotificationsModule(reactContext),
|
|
15
|
+
PaywalloEnvModule(reactContext),
|
|
16
|
+
PaywalloAdvertisingIdModule(reactContext)
|
|
16
17
|
)
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -56,7 +56,12 @@ class PaywalloStoreKitModule(private val reactContext: ReactApplicationContext)
|
|
|
56
56
|
if (billingClient == null || billingClient?.isReady != true) {
|
|
57
57
|
billingClient = BillingClient.newBuilder(reactContext)
|
|
58
58
|
.setListener(this)
|
|
59
|
-
|
|
59
|
+
// A Billing 7 depreciou e a 8 REMOVEU o enablePendingPurchases() sem argumento.
|
|
60
|
+
// Um app que traz a billing 8 por outra dependência (ex.: Superwall) resolve a
|
|
61
|
+
// versão mais alta no Gradle e a chamada antiga vira NoSuchMethodError em runtime.
|
|
62
|
+
.enablePendingPurchases(
|
|
63
|
+
PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()
|
|
64
|
+
)
|
|
60
65
|
.build()
|
|
61
66
|
}
|
|
62
67
|
return billingClient!!
|
|
@@ -173,10 +178,12 @@ class PaywalloStoreKitModule(private val reactContext: ReactApplicationContext)
|
|
|
173
178
|
.build()
|
|
174
179
|
|
|
175
180
|
return suspendCancellableCoroutine { cont ->
|
|
176
|
-
|
|
181
|
+
// Na Billing 8 o callback passou a receber QueryProductDetailsResult em vez da
|
|
182
|
+
// lista direta — a assinatura antiga não existe mais em runtime.
|
|
183
|
+
client.queryProductDetailsAsync(params) { result, detailsResult ->
|
|
177
184
|
if (cont.isActive) {
|
|
178
185
|
if (result.responseCode == BillingClient.BillingResponseCode.OK) {
|
|
179
|
-
cont.resume(
|
|
186
|
+
cont.resume(detailsResult.productDetailsList) {}
|
|
180
187
|
} else {
|
|
181
188
|
cont.resume(emptyList()) {}
|
|
182
189
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -346,6 +346,7 @@ interface IdentifyOptions {
|
|
|
346
346
|
lastName?: string;
|
|
347
347
|
dateOfBirth?: string;
|
|
348
348
|
gender?: "m" | "f";
|
|
349
|
+
zipCode?: string;
|
|
349
350
|
}
|
|
350
351
|
interface TrackEventOptions {
|
|
351
352
|
properties?: UserProperties;
|
|
@@ -407,9 +408,12 @@ interface EventContext {
|
|
|
407
408
|
/**
|
|
408
409
|
* Event priority controls flush semantics:
|
|
409
410
|
*
|
|
410
|
-
* - `"critical"` →
|
|
411
|
-
*
|
|
412
|
-
*
|
|
411
|
+
* - `"critical"` → posted as a batch-of-1 immediately, and `track()` awaits
|
|
412
|
+
* the post before resolving. `PostFn` (`ApiClient.postWithQueue`) performs
|
|
413
|
+
* a write-ahead journal to `OfflineQueue` for critical events before any
|
|
414
|
+
* network attempt, so by the time `track()` resolves the event is durable
|
|
415
|
+
* on disk — not just handed off to a microtask. Used for events where loss
|
|
416
|
+
* is unacceptable: `transaction`, `identify`, `lifecycle {type: "install"}`,
|
|
413
417
|
* `subscription_*`, `refund`, `checkout_started`.
|
|
414
418
|
* - `"normal"` → buffered and flushed on a rolling window (whichever fires
|
|
415
419
|
* first): `BATCH_MAX_SIZE` events OR `BATCH_FLUSH_MS`. Used for events
|
|
@@ -535,6 +539,7 @@ declare class ApiClient {
|
|
|
535
539
|
lastName?: string;
|
|
536
540
|
dateOfBirth?: string;
|
|
537
541
|
gender?: string;
|
|
542
|
+
zipCode?: string;
|
|
538
543
|
}): Promise<void>;
|
|
539
544
|
getVariant(flagKey: string, distinctId: string): Promise<FlagVariant>;
|
|
540
545
|
getPaywall(placement: string): Promise<PaywallConfig | null>;
|
|
@@ -559,6 +564,7 @@ interface IdentityState {
|
|
|
559
564
|
lastName: string | null;
|
|
560
565
|
dateOfBirth: string | null;
|
|
561
566
|
gender: string | null;
|
|
567
|
+
zipCode: string | null;
|
|
562
568
|
}
|
|
563
569
|
declare class IdentityManager {
|
|
564
570
|
private deviceId;
|
|
@@ -570,6 +576,7 @@ declare class IdentityManager {
|
|
|
570
576
|
private lastName;
|
|
571
577
|
private dateOfBirth;
|
|
572
578
|
private gender;
|
|
579
|
+
private zipCode;
|
|
573
580
|
private apiClient;
|
|
574
581
|
private secureStorage;
|
|
575
582
|
private debug;
|
package/dist/index.d.ts
CHANGED
|
@@ -346,6 +346,7 @@ interface IdentifyOptions {
|
|
|
346
346
|
lastName?: string;
|
|
347
347
|
dateOfBirth?: string;
|
|
348
348
|
gender?: "m" | "f";
|
|
349
|
+
zipCode?: string;
|
|
349
350
|
}
|
|
350
351
|
interface TrackEventOptions {
|
|
351
352
|
properties?: UserProperties;
|
|
@@ -407,9 +408,12 @@ interface EventContext {
|
|
|
407
408
|
/**
|
|
408
409
|
* Event priority controls flush semantics:
|
|
409
410
|
*
|
|
410
|
-
* - `"critical"` →
|
|
411
|
-
*
|
|
412
|
-
*
|
|
411
|
+
* - `"critical"` → posted as a batch-of-1 immediately, and `track()` awaits
|
|
412
|
+
* the post before resolving. `PostFn` (`ApiClient.postWithQueue`) performs
|
|
413
|
+
* a write-ahead journal to `OfflineQueue` for critical events before any
|
|
414
|
+
* network attempt, so by the time `track()` resolves the event is durable
|
|
415
|
+
* on disk — not just handed off to a microtask. Used for events where loss
|
|
416
|
+
* is unacceptable: `transaction`, `identify`, `lifecycle {type: "install"}`,
|
|
413
417
|
* `subscription_*`, `refund`, `checkout_started`.
|
|
414
418
|
* - `"normal"` → buffered and flushed on a rolling window (whichever fires
|
|
415
419
|
* first): `BATCH_MAX_SIZE` events OR `BATCH_FLUSH_MS`. Used for events
|
|
@@ -535,6 +539,7 @@ declare class ApiClient {
|
|
|
535
539
|
lastName?: string;
|
|
536
540
|
dateOfBirth?: string;
|
|
537
541
|
gender?: string;
|
|
542
|
+
zipCode?: string;
|
|
538
543
|
}): Promise<void>;
|
|
539
544
|
getVariant(flagKey: string, distinctId: string): Promise<FlagVariant>;
|
|
540
545
|
getPaywall(placement: string): Promise<PaywallConfig | null>;
|
|
@@ -559,6 +564,7 @@ interface IdentityState {
|
|
|
559
564
|
lastName: string | null;
|
|
560
565
|
dateOfBirth: string | null;
|
|
561
566
|
gender: string | null;
|
|
567
|
+
zipCode: string | null;
|
|
562
568
|
}
|
|
563
569
|
declare class IdentityManager {
|
|
564
570
|
private deviceId;
|
|
@@ -570,6 +576,7 @@ declare class IdentityManager {
|
|
|
570
576
|
private lastName;
|
|
571
577
|
private dateOfBirth;
|
|
572
578
|
private gender;
|
|
579
|
+
private zipCode;
|
|
573
580
|
private apiClient;
|
|
574
581
|
private secureStorage;
|
|
575
582
|
private debug;
|