@chipmobilesdk/rn-payment 0.6.0 → 0.7.0
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/CHANGELOG.md +111 -0
- package/README.md +1 -1
- package/lib/commonjs/adapter/createStoreProvider.js +110 -0
- package/lib/commonjs/adapter/createStoreProvider.js.map +1 -0
- package/lib/commonjs/adapter/iap-adapter.js +393 -0
- package/lib/commonjs/adapter/iap-adapter.js.map +1 -0
- package/lib/commonjs/adapter/iapShapes.js +169 -0
- package/lib/commonjs/adapter/iapShapes.js.map +1 -0
- package/lib/commonjs/adapter/port.js +6 -0
- package/lib/commonjs/adapter/port.js.map +1 -0
- package/lib/commonjs/config/types.js +2 -0
- package/lib/commonjs/config/types.js.map +1 -0
- package/lib/commonjs/config/validate.js +181 -0
- package/lib/commonjs/config/validate.js.map +1 -0
- package/lib/commonjs/core/mutex.js +31 -0
- package/lib/commonjs/core/mutex.js.map +1 -0
- package/lib/commonjs/core/retry.js +37 -0
- package/lib/commonjs/core/retry.js.map +1 -0
- package/lib/commonjs/core/timers.js +207 -0
- package/lib/commonjs/core/timers.js.map +1 -0
- package/lib/commonjs/diagnostics/errors.js +83 -0
- package/lib/commonjs/diagnostics/errors.js.map +1 -0
- package/lib/commonjs/diagnostics/events.js +126 -0
- package/lib/commonjs/diagnostics/events.js.map +1 -0
- package/lib/commonjs/diagnostics/messageKeys.js +70 -0
- package/lib/commonjs/diagnostics/messageKeys.js.map +1 -0
- package/lib/commonjs/engine/connection.js +189 -0
- package/lib/commonjs/engine/connection.js.map +1 -0
- package/lib/commonjs/engine/engine.js +279 -0
- package/lib/commonjs/engine/engine.js.map +1 -0
- package/lib/commonjs/engine/finalize.js +325 -0
- package/lib/commonjs/engine/finalize.js.map +1 -0
- package/lib/commonjs/engine/foreground.js +26 -0
- package/lib/commonjs/engine/foreground.js.map +1 -0
- package/lib/commonjs/engine/internals.js +31 -0
- package/lib/commonjs/engine/internals.js.map +1 -0
- package/lib/commonjs/engine/pending.js +102 -0
- package/lib/commonjs/engine/pending.js.map +1 -0
- package/lib/commonjs/engine/products.js +198 -0
- package/lib/commonjs/engine/products.js.map +1 -0
- package/lib/commonjs/engine/purchase.js +395 -0
- package/lib/commonjs/engine/purchase.js.map +1 -0
- package/lib/commonjs/engine/purchaseFailure.js +77 -0
- package/lib/commonjs/engine/purchaseFailure.js.map +1 -0
- package/lib/commonjs/engine/receiptValidation.js +90 -0
- package/lib/commonjs/engine/receiptValidation.js.map +1 -0
- package/lib/commonjs/engine/state.js +201 -0
- package/lib/commonjs/engine/state.js.map +1 -0
- package/lib/commonjs/engine/subscriptions.js +122 -0
- package/lib/commonjs/engine/subscriptions.js.map +1 -0
- package/lib/commonjs/engine/sync.js +163 -0
- package/lib/commonjs/engine/sync.js.map +1 -0
- package/lib/commonjs/entitlements/aggregate.js +212 -0
- package/lib/commonjs/entitlements/aggregate.js.map +1 -0
- package/lib/commonjs/entitlements/mapping.js +41 -0
- package/lib/commonjs/entitlements/mapping.js.map +1 -0
- package/lib/commonjs/entitlements/policy.js +110 -0
- package/lib/commonjs/entitlements/policy.js.map +1 -0
- package/lib/commonjs/index.js +266 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/persistence/mmkv-store.js +149 -0
- package/lib/commonjs/persistence/mmkv-store.js.map +1 -0
- package/lib/commonjs/persistence/snapshot.js +229 -0
- package/lib/commonjs/persistence/snapshot.js.map +1 -0
- package/lib/commonjs/react/PaymentProvider.js +96 -0
- package/lib/commonjs/react/PaymentProvider.js.map +1 -0
- package/lib/commonjs/react/hooks.js +202 -0
- package/lib/commonjs/react/hooks.js.map +1 -0
- package/lib/commonjs/testing/conformance.js +136 -0
- package/lib/commonjs/testing/conformance.js.map +1 -0
- package/lib/commonjs/testing/fakeStore.js +281 -0
- package/lib/commonjs/testing/fakeStore.js.map +1 -0
- package/lib/commonjs/testing/index.js +45 -0
- package/lib/commonjs/testing/index.js.map +1 -0
- package/lib/module/adapter/createStoreProvider.js +106 -0
- package/lib/module/adapter/createStoreProvider.js.map +1 -0
- package/lib/module/adapter/iap-adapter.js +383 -0
- package/lib/module/adapter/iap-adapter.js.map +1 -0
- package/lib/module/adapter/iapShapes.js +160 -0
- package/lib/module/adapter/iapShapes.js.map +1 -0
- package/lib/module/adapter/port.js +4 -0
- package/lib/module/adapter/port.js.map +1 -0
- package/lib/module/config/types.js +2 -0
- package/lib/module/config/types.js.map +1 -0
- package/lib/module/config/validate.js +175 -0
- package/lib/module/config/validate.js.map +1 -0
- package/lib/module/core/mutex.js +22 -0
- package/lib/module/core/mutex.js.map +1 -0
- package/lib/module/core/retry.js +33 -0
- package/lib/module/core/retry.js.map +1 -0
- package/lib/module/core/timers.js +198 -0
- package/lib/module/core/timers.js.map +1 -0
- package/lib/module/diagnostics/errors.js +76 -0
- package/lib/module/diagnostics/errors.js.map +1 -0
- package/lib/module/diagnostics/events.js +117 -0
- package/lib/module/diagnostics/events.js.map +1 -0
- package/lib/module/diagnostics/messageKeys.js +64 -0
- package/lib/module/diagnostics/messageKeys.js.map +1 -0
- package/lib/module/engine/connection.js +185 -0
- package/lib/module/engine/connection.js.map +1 -0
- package/lib/module/engine/engine.js +274 -0
- package/lib/module/engine/engine.js.map +1 -0
- package/lib/module/engine/finalize.js +322 -0
- package/lib/module/engine/finalize.js.map +1 -0
- package/lib/module/engine/foreground.js +21 -0
- package/lib/module/engine/foreground.js.map +1 -0
- package/lib/module/engine/internals.js +26 -0
- package/lib/module/engine/internals.js.map +1 -0
- package/lib/module/engine/pending.js +95 -0
- package/lib/module/engine/pending.js.map +1 -0
- package/lib/module/engine/products.js +195 -0
- package/lib/module/engine/products.js.map +1 -0
- package/lib/module/engine/purchase.js +390 -0
- package/lib/module/engine/purchase.js.map +1 -0
- package/lib/module/engine/purchaseFailure.js +72 -0
- package/lib/module/engine/purchaseFailure.js.map +1 -0
- package/lib/module/engine/receiptValidation.js +87 -0
- package/lib/module/engine/receiptValidation.js.map +1 -0
- package/lib/module/engine/state.js +196 -0
- package/lib/module/engine/state.js.map +1 -0
- package/lib/module/engine/subscriptions.js +119 -0
- package/lib/module/engine/subscriptions.js.map +1 -0
- package/lib/module/engine/sync.js +158 -0
- package/lib/module/engine/sync.js.map +1 -0
- package/lib/module/entitlements/aggregate.js +204 -0
- package/lib/module/entitlements/aggregate.js.map +1 -0
- package/lib/module/entitlements/mapping.js +35 -0
- package/lib/module/entitlements/mapping.js.map +1 -0
- package/lib/module/entitlements/policy.js +104 -0
- package/lib/module/entitlements/policy.js.map +1 -0
- package/lib/module/index.js +59 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/persistence/mmkv-store.js +144 -0
- package/lib/module/persistence/mmkv-store.js.map +1 -0
- package/lib/module/persistence/snapshot.js +221 -0
- package/lib/module/persistence/snapshot.js.map +1 -0
- package/lib/module/react/PaymentProvider.js +90 -0
- package/lib/module/react/PaymentProvider.js.map +1 -0
- package/lib/module/react/hooks.js +192 -0
- package/lib/module/react/hooks.js.map +1 -0
- package/lib/module/testing/conformance.js +130 -0
- package/lib/module/testing/conformance.js.map +1 -0
- package/lib/module/testing/fakeStore.js +276 -0
- package/lib/module/testing/fakeStore.js.map +1 -0
- package/lib/module/testing/index.js +13 -0
- package/lib/module/testing/index.js.map +1 -0
- package/lib/typescript/commonjs/adapter/createStoreProvider.d.ts +45 -0
- package/lib/typescript/commonjs/adapter/createStoreProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/adapter/iap-adapter.d.ts +80 -0
- package/lib/typescript/commonjs/adapter/iap-adapter.d.ts.map +1 -0
- package/lib/typescript/commonjs/adapter/iapShapes.d.ts +94 -0
- package/lib/typescript/commonjs/adapter/iapShapes.d.ts.map +1 -0
- package/lib/typescript/commonjs/adapter/port.d.ts +184 -0
- package/lib/typescript/commonjs/adapter/port.d.ts.map +1 -0
- package/lib/typescript/commonjs/config/types.d.ts +326 -0
- package/lib/typescript/commonjs/config/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/config/validate.d.ts +63 -0
- package/lib/typescript/commonjs/config/validate.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/mutex.d.ts +17 -0
- package/lib/typescript/commonjs/core/mutex.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/retry.d.ts +19 -0
- package/lib/typescript/commonjs/core/retry.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/timers.d.ts +142 -0
- package/lib/typescript/commonjs/core/timers.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts +55 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/events.d.ts +158 -0
- package/lib/typescript/commonjs/diagnostics/events.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts +54 -0
- package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/connection.d.ts +30 -0
- package/lib/typescript/commonjs/engine/connection.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/engine.d.ts +93 -0
- package/lib/typescript/commonjs/engine/engine.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/finalize.d.ts +53 -0
- package/lib/typescript/commonjs/engine/finalize.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/foreground.d.ts +15 -0
- package/lib/typescript/commonjs/engine/foreground.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/internals.d.ts +28 -0
- package/lib/typescript/commonjs/engine/internals.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/pending.d.ts +51 -0
- package/lib/typescript/commonjs/engine/pending.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/products.d.ts +82 -0
- package/lib/typescript/commonjs/engine/products.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/purchase.d.ts +61 -0
- package/lib/typescript/commonjs/engine/purchase.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/purchaseFailure.d.ts +15 -0
- package/lib/typescript/commonjs/engine/purchaseFailure.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/receiptValidation.d.ts +42 -0
- package/lib/typescript/commonjs/engine/receiptValidation.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/state.d.ts +46 -0
- package/lib/typescript/commonjs/engine/state.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/subscriptions.d.ts +61 -0
- package/lib/typescript/commonjs/engine/subscriptions.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/sync.d.ts +36 -0
- package/lib/typescript/commonjs/engine/sync.d.ts.map +1 -0
- package/lib/typescript/commonjs/entitlements/aggregate.d.ts +97 -0
- package/lib/typescript/commonjs/entitlements/aggregate.d.ts.map +1 -0
- package/lib/typescript/commonjs/entitlements/mapping.d.ts +27 -0
- package/lib/typescript/commonjs/entitlements/mapping.d.ts.map +1 -0
- package/lib/typescript/commonjs/entitlements/policy.d.ts +75 -0
- package/lib/typescript/commonjs/entitlements/policy.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +44 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/persistence/mmkv-store.d.ts +45 -0
- package/lib/typescript/commonjs/persistence/mmkv-store.d.ts.map +1 -0
- package/lib/typescript/commonjs/persistence/snapshot.d.ts +106 -0
- package/lib/typescript/commonjs/persistence/snapshot.d.ts.map +1 -0
- package/lib/typescript/commonjs/react/PaymentProvider.d.ts +57 -0
- package/lib/typescript/commonjs/react/PaymentProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/react/hooks.d.ts +80 -0
- package/lib/typescript/commonjs/react/hooks.d.ts.map +1 -0
- package/lib/typescript/commonjs/testing/conformance.d.ts +41 -0
- package/lib/typescript/commonjs/testing/conformance.d.ts.map +1 -0
- package/lib/typescript/commonjs/testing/fakeStore.d.ts +69 -0
- package/lib/typescript/commonjs/testing/fakeStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/testing/index.d.ts +12 -0
- package/lib/typescript/commonjs/testing/index.d.ts.map +1 -0
- package/lib/typescript/module/adapter/createStoreProvider.d.ts +45 -0
- package/lib/typescript/module/adapter/createStoreProvider.d.ts.map +1 -0
- package/lib/typescript/module/adapter/iap-adapter.d.ts +80 -0
- package/lib/typescript/module/adapter/iap-adapter.d.ts.map +1 -0
- package/lib/typescript/module/adapter/iapShapes.d.ts +94 -0
- package/lib/typescript/module/adapter/iapShapes.d.ts.map +1 -0
- package/lib/typescript/module/adapter/port.d.ts +184 -0
- package/lib/typescript/module/adapter/port.d.ts.map +1 -0
- package/lib/typescript/module/config/types.d.ts +326 -0
- package/lib/typescript/module/config/types.d.ts.map +1 -0
- package/lib/typescript/module/config/validate.d.ts +63 -0
- package/lib/typescript/module/config/validate.d.ts.map +1 -0
- package/lib/typescript/module/core/mutex.d.ts +17 -0
- package/lib/typescript/module/core/mutex.d.ts.map +1 -0
- package/lib/typescript/module/core/retry.d.ts +19 -0
- package/lib/typescript/module/core/retry.d.ts.map +1 -0
- package/lib/typescript/module/core/timers.d.ts +142 -0
- package/lib/typescript/module/core/timers.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/errors.d.ts +55 -0
- package/lib/typescript/module/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/events.d.ts +158 -0
- package/lib/typescript/module/diagnostics/events.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/messageKeys.d.ts +54 -0
- package/lib/typescript/module/diagnostics/messageKeys.d.ts.map +1 -0
- package/lib/typescript/module/engine/connection.d.ts +30 -0
- package/lib/typescript/module/engine/connection.d.ts.map +1 -0
- package/lib/typescript/module/engine/engine.d.ts +93 -0
- package/lib/typescript/module/engine/engine.d.ts.map +1 -0
- package/lib/typescript/module/engine/finalize.d.ts +53 -0
- package/lib/typescript/module/engine/finalize.d.ts.map +1 -0
- package/lib/typescript/module/engine/foreground.d.ts +15 -0
- package/lib/typescript/module/engine/foreground.d.ts.map +1 -0
- package/lib/typescript/module/engine/internals.d.ts +28 -0
- package/lib/typescript/module/engine/internals.d.ts.map +1 -0
- package/lib/typescript/module/engine/pending.d.ts +51 -0
- package/lib/typescript/module/engine/pending.d.ts.map +1 -0
- package/lib/typescript/module/engine/products.d.ts +82 -0
- package/lib/typescript/module/engine/products.d.ts.map +1 -0
- package/lib/typescript/module/engine/purchase.d.ts +61 -0
- package/lib/typescript/module/engine/purchase.d.ts.map +1 -0
- package/lib/typescript/module/engine/purchaseFailure.d.ts +15 -0
- package/lib/typescript/module/engine/purchaseFailure.d.ts.map +1 -0
- package/lib/typescript/module/engine/receiptValidation.d.ts +42 -0
- package/lib/typescript/module/engine/receiptValidation.d.ts.map +1 -0
- package/lib/typescript/module/engine/state.d.ts +46 -0
- package/lib/typescript/module/engine/state.d.ts.map +1 -0
- package/lib/typescript/module/engine/subscriptions.d.ts +61 -0
- package/lib/typescript/module/engine/subscriptions.d.ts.map +1 -0
- package/lib/typescript/module/engine/sync.d.ts +36 -0
- package/lib/typescript/module/engine/sync.d.ts.map +1 -0
- package/lib/typescript/module/entitlements/aggregate.d.ts +97 -0
- package/lib/typescript/module/entitlements/aggregate.d.ts.map +1 -0
- package/lib/typescript/module/entitlements/mapping.d.ts +27 -0
- package/lib/typescript/module/entitlements/mapping.d.ts.map +1 -0
- package/lib/typescript/module/entitlements/policy.d.ts +75 -0
- package/lib/typescript/module/entitlements/policy.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +44 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/persistence/mmkv-store.d.ts +45 -0
- package/lib/typescript/module/persistence/mmkv-store.d.ts.map +1 -0
- package/lib/typescript/module/persistence/snapshot.d.ts +106 -0
- package/lib/typescript/module/persistence/snapshot.d.ts.map +1 -0
- package/lib/typescript/module/react/PaymentProvider.d.ts +57 -0
- package/lib/typescript/module/react/PaymentProvider.d.ts.map +1 -0
- package/lib/typescript/module/react/hooks.d.ts +80 -0
- package/lib/typescript/module/react/hooks.d.ts.map +1 -0
- package/lib/typescript/module/testing/conformance.d.ts +41 -0
- package/lib/typescript/module/testing/conformance.d.ts.map +1 -0
- package/lib/typescript/module/testing/fakeStore.d.ts +69 -0
- package/lib/typescript/module/testing/fakeStore.d.ts.map +1 -0
- package/lib/typescript/module/testing/index.d.ts +12 -0
- package/lib/typescript/module/testing/index.d.ts.map +1 -0
- package/package.json +49 -13
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeout, retry, and cache policy.
|
|
3
|
+
*
|
|
4
|
+
* Defaults and bounds live here rather than at each call site so there is one
|
|
5
|
+
* place to read what the package will wait for, and so consumers can read the
|
|
6
|
+
* values they are bound by instead of discovering them from a timeout in
|
|
7
|
+
* production.
|
|
8
|
+
*
|
|
9
|
+
* Out-of-band values are a configuration error rather than being silently
|
|
10
|
+
* clamped: quietly turning a 1-second timeout into 3 seconds would tell the app
|
|
11
|
+
* it configured something it did not.
|
|
12
|
+
*/
|
|
13
|
+
import type { BackoffConfig, RetryConfig, TimeoutConfig } from '../config/types';
|
|
14
|
+
/** Local IPC to Play Services. Slower than this means unavailable, not busy. */
|
|
15
|
+
export declare const DEFAULT_CONNECT_TIMEOUT_MS = 10000;
|
|
16
|
+
/** A network round trip; a paywall that hangs longer should show its error state. */
|
|
17
|
+
export declare const DEFAULT_PRODUCT_QUERY_TIMEOUT_MS = 15000;
|
|
18
|
+
/** Runs at startup, so it must not hold the first render hostage. */
|
|
19
|
+
export declare const DEFAULT_SYNC_TIMEOUT_MS = 20000;
|
|
20
|
+
/**
|
|
21
|
+
* Covers opening the store surface only.
|
|
22
|
+
*
|
|
23
|
+
* Time the user spends *inside* the store's own UI is deliberately excluded
|
|
24
|
+
* (FR-035): a user reading the terms, switching to their banking app for an OTP,
|
|
25
|
+
* or simply hesitating must never have their purchase cancelled by our clock.
|
|
26
|
+
*/
|
|
27
|
+
export declare const DEFAULT_PURCHASE_LAUNCH_TIMEOUT_MS = 30000;
|
|
28
|
+
/** Per finalize attempt, not per transaction — the queue owns overall persistence. */
|
|
29
|
+
export declare const DEFAULT_FINALIZE_ATTEMPT_TIMEOUT_MS = 15000;
|
|
30
|
+
/** The app's backend hook. A user is waiting on a purchase result behind it. */
|
|
31
|
+
export declare const DEFAULT_VALIDATE_TIMEOUT_MS = 15000;
|
|
32
|
+
/**
|
|
33
|
+
* The ceiling on a purchase flow whose outcome includes the user's own time in
|
|
34
|
+
* the store UI, so is otherwise untimed (FR-035). Not a timeout on the user: it
|
|
35
|
+
* exists only so a binding that never answers cannot hold the purchase lock for
|
|
36
|
+
* the rest of the session. A purchase that completes later still arrives through
|
|
37
|
+
* the store update channel and is granted then.
|
|
38
|
+
*/
|
|
39
|
+
export declare const PURCHASE_FLOW_CEILING_MS: number;
|
|
40
|
+
export declare const CONNECT_TIMEOUT_BOUNDS: {
|
|
41
|
+
readonly min: 3000;
|
|
42
|
+
readonly max: 60000;
|
|
43
|
+
};
|
|
44
|
+
export declare const PRODUCT_QUERY_TIMEOUT_BOUNDS: {
|
|
45
|
+
readonly min: 3000;
|
|
46
|
+
readonly max: 60000;
|
|
47
|
+
};
|
|
48
|
+
export declare const SYNC_TIMEOUT_BOUNDS: {
|
|
49
|
+
readonly min: 5000;
|
|
50
|
+
readonly max: 120000;
|
|
51
|
+
};
|
|
52
|
+
export declare const PURCHASE_LAUNCH_TIMEOUT_BOUNDS: {
|
|
53
|
+
readonly min: 5000;
|
|
54
|
+
readonly max: 120000;
|
|
55
|
+
};
|
|
56
|
+
export declare const FINALIZE_ATTEMPT_TIMEOUT_BOUNDS: {
|
|
57
|
+
readonly min: 3000;
|
|
58
|
+
readonly max: 60000;
|
|
59
|
+
};
|
|
60
|
+
export declare const VALIDATE_TIMEOUT_BOUNDS: {
|
|
61
|
+
readonly min: 3000;
|
|
62
|
+
readonly max: 120000;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Prices and offer eligibility are shown at the moment of purchase, so a short
|
|
66
|
+
* TTL with on-demand refresh beats a long one (FR-029).
|
|
67
|
+
*/
|
|
68
|
+
export declare const DEFAULT_PRODUCT_CACHE_TTL_MS = 900000;
|
|
69
|
+
export declare const PRODUCT_CACHE_TTL_BOUNDS: {
|
|
70
|
+
readonly min: 60000;
|
|
71
|
+
readonly max: 86400000;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* How long a successful sync keeps entitlements trustworthy offline: **7 days**.
|
|
75
|
+
*
|
|
76
|
+
* Fixed by the specification (FR-055) after weighing both failure directions.
|
|
77
|
+
* The realistic offline cases — travel, poor coverage, a device left unused —
|
|
78
|
+
* resolve within days. Seven days covers a holiday without connectivity while
|
|
79
|
+
* bounding how long a refunded entitlement can outlive its refund to one week.
|
|
80
|
+
*
|
|
81
|
+
* Past this the entitlement becomes `unknown`, never `not_entitled` (FR-055a):
|
|
82
|
+
* the package stops asserting rather than telling a paying customer they did not
|
|
83
|
+
* pay.
|
|
84
|
+
*/
|
|
85
|
+
export declare const DEFAULT_STALE_AFTER_MS = 604800000;
|
|
86
|
+
export declare const STALE_AFTER_BOUNDS: {
|
|
87
|
+
readonly min: 3600000;
|
|
88
|
+
readonly max: 7776000000;
|
|
89
|
+
};
|
|
90
|
+
/** Keeps rapid app switching from becoming a request storm (PERF-002). */
|
|
91
|
+
export declare const DEFAULT_FOREGROUND_SYNC_MIN_INTERVAL_MS = 60000;
|
|
92
|
+
export declare const FOREGROUND_SYNC_MIN_INTERVAL_BOUNDS: {
|
|
93
|
+
readonly min: 0;
|
|
94
|
+
readonly max: 3600000;
|
|
95
|
+
};
|
|
96
|
+
/** Bounded so a dropped billing connection cannot become a retry storm (FR-020). */
|
|
97
|
+
export declare const DEFAULT_RECONNECT_BACKOFF: Required<BackoffConfig>;
|
|
98
|
+
/**
|
|
99
|
+
* Finalize retry.
|
|
100
|
+
*
|
|
101
|
+
* Bounded **per session** but never permanently abandoned: Google auto-refunds
|
|
102
|
+
* an unacknowledged purchase after three days, so exhausting this session's
|
|
103
|
+
* attempts must leave the transaction queued for the next launch, not dropped
|
|
104
|
+
* (FR-045).
|
|
105
|
+
*/
|
|
106
|
+
export declare const DEFAULT_FINALIZE_BACKOFF: Required<BackoffConfig>;
|
|
107
|
+
export declare const BACKOFF_MAX_DELAY_BOUNDS: {
|
|
108
|
+
readonly min: 5000;
|
|
109
|
+
readonly max: 600000;
|
|
110
|
+
};
|
|
111
|
+
export declare const BACKOFF_ATTEMPT_BOUNDS: {
|
|
112
|
+
readonly min: 1;
|
|
113
|
+
readonly max: 10;
|
|
114
|
+
};
|
|
115
|
+
/** A first retry sooner than this is a storm; later than this, the user has given up. */
|
|
116
|
+
export declare const BACKOFF_INITIAL_DELAY_BOUNDS: {
|
|
117
|
+
readonly min: 100;
|
|
118
|
+
readonly max: 60000;
|
|
119
|
+
};
|
|
120
|
+
/** 1 is a constant delay; 0 or below would retry at once, forever (CORE-05). */
|
|
121
|
+
export declare const BACKOFF_FACTOR_BOUNDS: {
|
|
122
|
+
readonly min: 1;
|
|
123
|
+
readonly max: 10;
|
|
124
|
+
};
|
|
125
|
+
export interface ResolvedTimeouts {
|
|
126
|
+
connectMs: number;
|
|
127
|
+
productQueryMs: number;
|
|
128
|
+
syncMs: number;
|
|
129
|
+
purchaseLaunchMs: number;
|
|
130
|
+
finalizeAttemptMs: number;
|
|
131
|
+
validateMs: number;
|
|
132
|
+
}
|
|
133
|
+
export declare function resolveTimeouts(config?: TimeoutConfig): ResolvedTimeouts;
|
|
134
|
+
export interface ResolvedRetry {
|
|
135
|
+
reconnect: Required<BackoffConfig>;
|
|
136
|
+
finalize: Required<BackoffConfig>;
|
|
137
|
+
}
|
|
138
|
+
export declare function resolveRetry(config?: RetryConfig): ResolvedRetry;
|
|
139
|
+
export declare function resolveStaleAfterMs(value?: number): number;
|
|
140
|
+
export declare function resolveProductCacheTtlMs(value?: number): number;
|
|
141
|
+
export declare function resolveForegroundSyncMinIntervalMs(value?: number): number;
|
|
142
|
+
//# sourceMappingURL=timers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timers.d.ts","sourceRoot":"","sources":["../../../../src/core/timers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEjF,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,QAAS,CAAC;AACjD,qFAAqF;AACrF,eAAO,MAAM,gCAAgC,QAAS,CAAC;AACvD,qEAAqE;AACrE,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAC9C;;;;;;GAMG;AACH,eAAO,MAAM,kCAAkC,QAAS,CAAC;AACzD,sFAAsF;AACtF,eAAO,MAAM,mCAAmC,QAAS,CAAC;AAC1D,gFAAgF;AAChF,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAClD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,QAAc,CAAC;AAEpD,eAAO,MAAM,sBAAsB;;;CAAuC,CAAC;AAC3E,eAAO,MAAM,4BAA4B;;;CAAuC,CAAC;AACjF,eAAO,MAAM,mBAAmB;;;CAAwC,CAAC;AACzE,eAAO,MAAM,8BAA8B;;;CAGjC,CAAC;AACX,eAAO,MAAM,+BAA+B;;;CAGlC,CAAC;AACX,eAAO,MAAM,uBAAuB;;;CAAwC,CAAC;AAE7E;;;GAGG;AACH,eAAO,MAAM,4BAA4B,SAAU,CAAC;AACpD,eAAO,MAAM,wBAAwB;;;CAA4C,CAAC;AAElF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,YAAc,CAAC;AAClD,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAEX,0EAA0E;AAC1E,eAAO,MAAM,uCAAuC,QAAS,CAAC;AAC9D,eAAO,MAAM,mCAAmC;;;CAGtC,CAAC;AAEX,oFAAoF;AACpF,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,aAAa,CAM7D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,aAAa,CAM5D,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;CAAwC,CAAC;AAC9E,eAAO,MAAM,sBAAsB;;;CAA+B,CAAC;AACnE,yFAAyF;AACzF,eAAO,MAAM,4BAA4B;;;CAAqC,CAAC;AAC/E,gFAAgF;AAChF,eAAO,MAAM,qBAAqB;;;CAA+B,CAAC;AAwBlE,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,gBAAgB,CAuCxE;AA+CD,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;IACnC,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;CAClC;AAED,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,aAAa,CAKhE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAO/D;AAED,wBAAgB,kCAAkC,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAOzE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalized public errors.
|
|
3
|
+
*
|
|
4
|
+
* Error codes are **public API**: renaming one is a breaking change (FR-078,
|
|
5
|
+
* LIB-008). They are the vocabulary an app branches on, so they must outlive any
|
|
6
|
+
* internal refactor and must never leak a store's own code.
|
|
7
|
+
*/
|
|
8
|
+
import { SdkError } from '@chipmobilesdk/rn-core';
|
|
9
|
+
export declare const PAYMENT_ERROR_CODES: readonly ["PAYMENT_NOT_CONFIGURED", "PAYMENT_INVALID_CATALOG", "PAYMENT_NOT_READY", "PAYMENT_DISABLED", "PAYMENT_UNAVAILABLE", "PAYMENT_UNSUPPORTED_PLATFORM", "PAYMENT_ENVIRONMENT_BLOCKED", "PAYMENT_PRODUCTION_CONFIG_IN_NON_PRODUCTION_BUILD", "PAYMENT_PURCHASE_IN_PROGRESS", "PAYMENT_USER_CANCELLED", "PAYMENT_PENDING", "PAYMENT_ALREADY_OWNED", "PAYMENT_INELIGIBLE", "PAYMENT_UNKNOWN_PRODUCT", "PAYMENT_PRODUCT_UNAVAILABLE_IN_REGION", "PAYMENT_TIMEOUT", "PAYMENT_NETWORK_ERROR", "PAYMENT_STORE_ERROR", "PAYMENT_FINALIZE_FAILED", "PAYMENT_VALIDATION_REJECTED", "PAYMENT_VALIDATION_UNAVAILABLE", "PAYMENT_STORAGE_UNAVAILABLE", "PAYMENT_NOT_CONSUMABLE", "PAYMENT_INVALID_CONFIG"];
|
|
10
|
+
export type PaymentErrorCode = (typeof PAYMENT_ERROR_CODES)[number];
|
|
11
|
+
/** Which operation produced an error. Part of the public error shape (FR-078). */
|
|
12
|
+
export type PaymentOperation = 'configure' | 'initialize' | 'getProducts' | 'purchase' | 'finalize' | 'consume' | 'sync' | 'restore' | 'changePlan' | 'validate' | 'persist';
|
|
13
|
+
/** The package's error; an `SdkError` (`@chipmobilesdk/rn-core`) with `pkg: 'rn-payment'`. */
|
|
14
|
+
export declare class PaymentError extends SdkError<PaymentErrorCode> {
|
|
15
|
+
readonly operation: PaymentOperation;
|
|
16
|
+
/** Redacted where appropriate — never a raw receipt, token, or store object (FR-074). */
|
|
17
|
+
readonly cause?: string;
|
|
18
|
+
constructor(init: {
|
|
19
|
+
code: PaymentErrorCode;
|
|
20
|
+
message: string;
|
|
21
|
+
operation: PaymentOperation;
|
|
22
|
+
retryable?: boolean;
|
|
23
|
+
cause?: string;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A configuration problem the app can act on.
|
|
28
|
+
*
|
|
29
|
+
* Separate from `PaymentError` because configuration faults are developer-facing
|
|
30
|
+
* and must never be shown to an end user — the message-key map keeps that
|
|
31
|
+
* separation explicit (FR-085).
|
|
32
|
+
*/
|
|
33
|
+
export declare class PaymentConfigError extends PaymentError {
|
|
34
|
+
/** The offending catalog entries or entitlement keys, named (FR-011). */
|
|
35
|
+
readonly offenders: string[];
|
|
36
|
+
constructor(init: {
|
|
37
|
+
code: PaymentErrorCode;
|
|
38
|
+
message: string;
|
|
39
|
+
operation: PaymentOperation;
|
|
40
|
+
offenders?: string[];
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Strips anything that must never reach a log or event.
|
|
45
|
+
*
|
|
46
|
+
* Applied at the boundary rather than trusted to call sites: a single forgotten
|
|
47
|
+
* interpolation is how receipts end up in logs (NFR-006).
|
|
48
|
+
*
|
|
49
|
+
* Identifier-only: what survives is what code defined, never what data carried.
|
|
50
|
+
* A `PaymentError` keeps its code and an `Error` its class name; every message
|
|
51
|
+
* and every string is dropped, because a store or consumer message can embed a
|
|
52
|
+
* purchase token or an account id and nothing here can tell which.
|
|
53
|
+
*/
|
|
54
|
+
export declare function redact(value: unknown): string;
|
|
55
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../../src/diagnostics/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAY,QAAQ,EAAkB,MAAM,wBAAwB,CAAC;AAI5E,eAAO,MAAM,mBAAmB,sqBA8BtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,kFAAkF;AAClF,MAAM,MAAM,gBAAgB,GACzB,WAAW,GACX,YAAY,GACZ,aAAa,GACb,UAAU,GACV,UAAU,GACV,SAAS,GACT,MAAM,GACN,SAAS,GACT,YAAY,GACZ,UAAU,GACV,SAAS,CAAC;AAEb,8FAA8F;AAC9F,qBAAa,YAAa,SAAQ,QAAQ,CAAC,gBAAgB,CAAC;IAC3D,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,yFAAyF;IACzF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE;QACjB,IAAI,EAAE,gBAAgB,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,gBAAgB,CAAC;QAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;KACf;CAUD;AAED;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IACnD,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;gBAEjB,IAAI,EAAE;QACjB,IAAI,EAAE,gBAAgB,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,gBAAgB,CAAC;QAC5B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB;CAKD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK7C"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed events and the emitter.
|
|
3
|
+
*
|
|
4
|
+
* The bar is FR-077: the event stream **alone** must be enough to reconstruct a
|
|
5
|
+
* transaction's full lifecycle, so that "the user says they paid but has no
|
|
6
|
+
* entitlement" can be investigated from logs without a reproduction.
|
|
7
|
+
*
|
|
8
|
+
* Forbidden in every payload, without exception (FR-076, FR-074): store objects,
|
|
9
|
+
* raw receipts, verification payloads, backend tokens, payment details, the
|
|
10
|
+
* obfuscated account identifier, and the cache-scope token.
|
|
11
|
+
*/
|
|
12
|
+
import { redact, type PaymentErrorCode, type PaymentOperation } from './errors';
|
|
13
|
+
import type { EntitlementKey, Environment, PendingResolution, ProductKey, Unsubscribe, UnavailableReason, PaymentStatusKind } from '../config/types';
|
|
14
|
+
export type PaymentEventType = 'initialization' | 'connection_changed' | 'products_queried' | 'purchase_started' | 'purchase_succeeded' | 'purchase_cancelled' | 'purchase_pending' | 'purchase_pending_resolved' | 'purchase_failed' | 'transaction_finalized' | 'transaction_consumed' | 'finalize_retry_scheduled' | 'sync_completed' | 'entitlement_granted' | 'entitlement_revoked' | 'validation_decided' | 'validation_unavailable' | 'environment_blocked' | 'config_warning' | 'internal_error';
|
|
15
|
+
interface BaseEvent {
|
|
16
|
+
timestamp: number;
|
|
17
|
+
/** Ties one purchase cycle together end to end. Absent for lifecycle events. */
|
|
18
|
+
correlationId?: string;
|
|
19
|
+
}
|
|
20
|
+
export type SyncTrigger = 'initialize' | 'foreground' | 'manual' | 'already_owned';
|
|
21
|
+
export type PaymentEvent = BaseEvent & ({
|
|
22
|
+
type: 'initialization';
|
|
23
|
+
status: PaymentStatusKind;
|
|
24
|
+
unavailableReason?: UnavailableReason;
|
|
25
|
+
retryable?: boolean;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'connection_changed';
|
|
28
|
+
connected: boolean;
|
|
29
|
+
reason?: string;
|
|
30
|
+
attempt?: number;
|
|
31
|
+
} | {
|
|
32
|
+
type: 'products_queried';
|
|
33
|
+
productKeys: ProductKey[];
|
|
34
|
+
found: number;
|
|
35
|
+
missing: ProductKey[];
|
|
36
|
+
fromCache: boolean;
|
|
37
|
+
} | {
|
|
38
|
+
type: 'purchase_started';
|
|
39
|
+
productKey: ProductKey;
|
|
40
|
+
} | {
|
|
41
|
+
type: 'purchase_succeeded';
|
|
42
|
+
productKey: ProductKey;
|
|
43
|
+
} | {
|
|
44
|
+
type: 'purchase_cancelled';
|
|
45
|
+
productKey: ProductKey;
|
|
46
|
+
} | {
|
|
47
|
+
type: 'purchase_pending';
|
|
48
|
+
productKey: ProductKey;
|
|
49
|
+
} | {
|
|
50
|
+
type: 'purchase_pending_resolved';
|
|
51
|
+
productKey: ProductKey;
|
|
52
|
+
outcome: PendingResolution;
|
|
53
|
+
} | {
|
|
54
|
+
type: 'purchase_failed';
|
|
55
|
+
productKey: ProductKey;
|
|
56
|
+
code: PaymentErrorCode;
|
|
57
|
+
retryable: boolean;
|
|
58
|
+
} | {
|
|
59
|
+
type: 'transaction_finalized';
|
|
60
|
+
productKey: ProductKey;
|
|
61
|
+
attempts: number;
|
|
62
|
+
} | {
|
|
63
|
+
type: 'transaction_consumed';
|
|
64
|
+
productKey: ProductKey;
|
|
65
|
+
} | {
|
|
66
|
+
type: 'finalize_retry_scheduled';
|
|
67
|
+
productKey: ProductKey;
|
|
68
|
+
attempt: number;
|
|
69
|
+
delayMs: number;
|
|
70
|
+
} | {
|
|
71
|
+
type: 'sync_completed';
|
|
72
|
+
restoredCount: number;
|
|
73
|
+
revokedCount: number;
|
|
74
|
+
trigger: SyncTrigger;
|
|
75
|
+
} | {
|
|
76
|
+
type: 'entitlement_granted';
|
|
77
|
+
entitlementKey: EntitlementKey;
|
|
78
|
+
sources: ProductKey[];
|
|
79
|
+
} | {
|
|
80
|
+
type: 'entitlement_revoked';
|
|
81
|
+
entitlementKey: EntitlementKey;
|
|
82
|
+
reason: 'expired' | 'revoked_by_store' | 'validation_rejected' | 'consumed';
|
|
83
|
+
} | {
|
|
84
|
+
type: 'validation_decided';
|
|
85
|
+
productKey: ProductKey;
|
|
86
|
+
decision: 'approved' | 'rejected';
|
|
87
|
+
} | {
|
|
88
|
+
type: 'validation_unavailable';
|
|
89
|
+
productKey: ProductKey;
|
|
90
|
+
fallback: 'grant_and_queue' | 'withhold';
|
|
91
|
+
} | {
|
|
92
|
+
type: 'environment_blocked';
|
|
93
|
+
productKey: ProductKey;
|
|
94
|
+
environment: Environment;
|
|
95
|
+
} | {
|
|
96
|
+
type: 'config_warning';
|
|
97
|
+
detail: string;
|
|
98
|
+
} | {
|
|
99
|
+
type: 'internal_error';
|
|
100
|
+
code: PaymentErrorCode;
|
|
101
|
+
operation: PaymentOperation;
|
|
102
|
+
});
|
|
103
|
+
export type PaymentEventListener = (event: PaymentEvent) => void;
|
|
104
|
+
/**
|
|
105
|
+
* A `PaymentEvent` with the timestamp left to the emitter.
|
|
106
|
+
*
|
|
107
|
+
* Distributive on purpose: a plain `Omit<PaymentEvent, 'timestamp'>` collapses the
|
|
108
|
+
* discriminated union into one object type with only the shared keys, which would
|
|
109
|
+
* reject every variant-specific field. `T extends unknown` forces the mapping to
|
|
110
|
+
* apply per member and keeps the union discriminated.
|
|
111
|
+
*/
|
|
112
|
+
type WithOptionalTimestamp<T> = T extends unknown ? Omit<T, 'timestamp'> & {
|
|
113
|
+
timestamp?: number;
|
|
114
|
+
} : never;
|
|
115
|
+
export type PaymentEventInput = WithOptionalTimestamp<PaymentEvent>;
|
|
116
|
+
export interface PaymentEmitter {
|
|
117
|
+
emit(event: PaymentEvent): void;
|
|
118
|
+
subscribe(listener: PaymentEventListener): Unsubscribe;
|
|
119
|
+
/** Disarms permanently. After this nothing is emitted (FR-082). */
|
|
120
|
+
dispose(): void;
|
|
121
|
+
listenerCount(): number;
|
|
122
|
+
disposed(): boolean;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Creates the emitter.
|
|
126
|
+
*
|
|
127
|
+
* Two properties are deliberate:
|
|
128
|
+
*
|
|
129
|
+
* 1. **A throwing listener cannot break anything** (FR-081). Each listener is
|
|
130
|
+
* invoked defensively, the throw is handed to `onListenerError`, and delivery
|
|
131
|
+
* continues to the remaining listeners. One app's broken analytics callback
|
|
132
|
+
* must not stop the package granting an entitlement or stop another listener
|
|
133
|
+
* hearing about it.
|
|
134
|
+
*
|
|
135
|
+
* The failure is **not** re-emitted as an event, deliberately. A consumer's own
|
|
136
|
+
* bug is not a payment-lifecycle event, and reporting it through the channel
|
|
137
|
+
* that just failed would both invite recursion and double event traffic for
|
|
138
|
+
* every event while that listener stays broken. It goes to the logger instead.
|
|
139
|
+
*
|
|
140
|
+
* 2. **After `dispose`, nothing is emitted** (FR-082). A store callback can
|
|
141
|
+
* arrive after cleanup; it must be dropped silently rather than reach a
|
|
142
|
+
* listener whose component is gone.
|
|
143
|
+
*/
|
|
144
|
+
export declare function createEmitter(onListenerError?: (error: unknown, event: PaymentEvent) => void): PaymentEmitter;
|
|
145
|
+
/**
|
|
146
|
+
* Fields that must never appear in an event payload.
|
|
147
|
+
*
|
|
148
|
+
* Used by `__tests__/diagnostics.test.ts` to walk every emitted event across the
|
|
149
|
+
* whole suite. Enumerating the ban here rather than in the test keeps the rule
|
|
150
|
+
* next to the type it constrains.
|
|
151
|
+
*/
|
|
152
|
+
export declare const FORBIDDEN_EVENT_FIELDS: readonly string[];
|
|
153
|
+
/** Correlation ids tie one purchase cycle together; no user data goes into them. */
|
|
154
|
+
export declare function createCorrelationId(counter: {
|
|
155
|
+
next: number;
|
|
156
|
+
}, prefix?: string): string;
|
|
157
|
+
export { redact };
|
|
158
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../../src/diagnostics/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable, localizable message keys with English default copy (FR-084, FR-085).
|
|
3
|
+
*
|
|
4
|
+
* The package takes no i18n runtime dependency: consuming apps map these keys to
|
|
5
|
+
* localized strings through whatever i18n system they already run. This is plain
|
|
6
|
+
* data, and the package never resolves or renders it.
|
|
7
|
+
*
|
|
8
|
+
* Message keys are **public API**: renaming one is a breaking change, on the
|
|
9
|
+
* same footing as an error code (FR-078).
|
|
10
|
+
*
|
|
11
|
+
* User-actionable copy and developer/configuration copy are kept in separate
|
|
12
|
+
* maps so an app cannot accidentally show "Payment catalog is invalid" to a
|
|
13
|
+
* customer — a configuration fault is a developer's problem, not a user's.
|
|
14
|
+
*/
|
|
15
|
+
export interface PaymentUserMessageMap {
|
|
16
|
+
'payment.state.pending': string;
|
|
17
|
+
'payment.state.alreadyOwned': string;
|
|
18
|
+
'payment.action.restore': string;
|
|
19
|
+
'payment.restore.succeeded': string;
|
|
20
|
+
'payment.restore.nothingFound': string;
|
|
21
|
+
'payment.error.cancelled': string;
|
|
22
|
+
'payment.error.network': string;
|
|
23
|
+
'payment.error.unavailable': string;
|
|
24
|
+
'payment.error.disabled': string;
|
|
25
|
+
'payment.subscription.grace': string;
|
|
26
|
+
'payment.subscription.hold': string;
|
|
27
|
+
}
|
|
28
|
+
/** Copy for developers and operators. **Never** surfaced to an end user. */
|
|
29
|
+
export interface PaymentDeveloperMessageMap {
|
|
30
|
+
'payment.config.invalidCatalog': string;
|
|
31
|
+
'payment.config.missingStoreId': string;
|
|
32
|
+
'payment.config.productionInNonProductionBuild': string;
|
|
33
|
+
'payment.config.storageUnavailable': string;
|
|
34
|
+
'payment.config.environmentBlocked': string;
|
|
35
|
+
}
|
|
36
|
+
export type PaymentMessageMap = PaymentUserMessageMap & PaymentDeveloperMessageMap;
|
|
37
|
+
export type PaymentUserMessageKey = keyof PaymentUserMessageMap;
|
|
38
|
+
export type PaymentDeveloperMessageKey = keyof PaymentDeveloperMessageMap;
|
|
39
|
+
export type PaymentMessageKey = keyof PaymentMessageMap;
|
|
40
|
+
export declare const DEFAULT_USER_MESSAGES: PaymentUserMessageMap;
|
|
41
|
+
export declare const DEFAULT_DEVELOPER_MESSAGES: PaymentDeveloperMessageMap;
|
|
42
|
+
/**
|
|
43
|
+
* The catalog as an rn-core message set. Register `paymentMessages.user` with
|
|
44
|
+
* rn-i18n to translate it like app copy; the developer copy stays out of bundles.
|
|
45
|
+
*/
|
|
46
|
+
export declare const paymentMessages: import("@chipmobilesdk/rn-core").MessageSet<PaymentUserMessageMap, PaymentDeveloperMessageMap>;
|
|
47
|
+
export declare const DEFAULT_MESSAGES: PaymentMessageMap;
|
|
48
|
+
/** Every user-actionable key, for an app building its translation resource. */
|
|
49
|
+
export declare const USER_MESSAGE_KEYS: PaymentUserMessageKey[];
|
|
50
|
+
/** Every developer-facing key, so an app can exclude them from user-visible bundles. */
|
|
51
|
+
export declare const DEVELOPER_MESSAGE_KEYS: PaymentDeveloperMessageKey[];
|
|
52
|
+
/** True for keys safe to show an end user. Lets an app assert that at its boundary. */
|
|
53
|
+
export declare function isUserMessageKey(key: PaymentMessageKey): key is PaymentUserMessageKey;
|
|
54
|
+
//# sourceMappingURL=messageKeys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messageKeys.d.ts","sourceRoot":"","sources":["../../../../src/diagnostics/messageKeys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,qBAAqB;IACrC,uBAAuB,EAAE,MAAM,CAAC;IAChC,4BAA4B,EAAE,MAAM,CAAC;IACrC,wBAAwB,EAAE,MAAM,CAAC;IACjC,2BAA2B,EAAE,MAAM,CAAC;IACpC,8BAA8B,EAAE,MAAM,CAAC;IACvC,yBAAyB,EAAE,MAAM,CAAC;IAClC,uBAAuB,EAAE,MAAM,CAAC;IAChC,2BAA2B,EAAE,MAAM,CAAC;IACpC,wBAAwB,EAAE,MAAM,CAAC;IACjC,4BAA4B,EAAE,MAAM,CAAC;IACrC,2BAA2B,EAAE,MAAM,CAAC;CACpC;AAED,4EAA4E;AAC5E,MAAM,WAAW,0BAA0B;IAC1C,+BAA+B,EAAE,MAAM,CAAC;IACxC,+BAA+B,EAAE,MAAM,CAAC;IACxC,+CAA+C,EAAE,MAAM,CAAC;IACxD,mCAAmC,EAAE,MAAM,CAAC;IAC5C,mCAAmC,EAAE,MAAM,CAAC;CAC5C;AAED,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG,0BAA0B,CAAC;AAEnF,MAAM,MAAM,qBAAqB,GAAG,MAAM,qBAAqB,CAAC;AAChE,MAAM,MAAM,0BAA0B,GAAG,MAAM,0BAA0B,CAAC;AAC1E,MAAM,MAAM,iBAAiB,GAAG,MAAM,iBAAiB,CAAC;AAExD,eAAO,MAAM,qBAAqB,EAAE,qBAYnC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,0BASxC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,gGAG1B,CAAC;AAEH,eAAO,MAAM,gBAAgB,EAAE,iBAA4C,CAAC;AAE5E,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,EAA+B,qBAAqB,EAAE,CAAC;AAErF,wFAAwF;AACxF,eAAO,MAAM,sBAAsB,EAAoC,0BAA0B,EAAE,CAAC;AAEpG,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,iBAAiB,GAAG,GAAG,IAAI,qBAAqB,CAErF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The billing connection: connecting, watching it, and reconnecting with bounded
|
|
3
|
+
* backoff (FR-018 – FR-024, PAY-10).
|
|
4
|
+
*
|
|
5
|
+
* A reconnect is always a full teardown-then-connect cycle. The upstream
|
|
6
|
+
* binding's own `reconnect()` has reported success without rebuilding anything
|
|
7
|
+
* (openiap#408), so no shortcut is trusted here.
|
|
8
|
+
*/
|
|
9
|
+
import type { ProviderPurchase } from '../adapter/port';
|
|
10
|
+
import { PaymentError } from '../diagnostics/errors';
|
|
11
|
+
import type { EngineState } from './state';
|
|
12
|
+
export type InitOutcome = {
|
|
13
|
+
ok: true;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
error: PaymentError;
|
|
17
|
+
};
|
|
18
|
+
export interface Connection {
|
|
19
|
+
/** Connects and attaches the watchers; status follows the outcome. */
|
|
20
|
+
connect(): Promise<InitOutcome>;
|
|
21
|
+
/**
|
|
22
|
+
* A fresh reconnect budget and one immediate attempt, when an earlier budget
|
|
23
|
+
* ran out: a foreground return is when the network the app lost is usually
|
|
24
|
+
* back.
|
|
25
|
+
*/
|
|
26
|
+
recover(): Promise<void>;
|
|
27
|
+
dispose(): void;
|
|
28
|
+
}
|
|
29
|
+
export declare function createConnection(state: EngineState, onPurchase: (purchase: ProviderPurchase) => void): Connection;
|
|
30
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../../src/engine/connection.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC;AAE5E,MAAM,WAAW,UAAU;IAC1B,sEAAsE;IACtE,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAChC;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAC9C,UAAU,CAiKZ"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The engine: status, initialization, entitlement reads, and sync.
|
|
3
|
+
*
|
|
4
|
+
* Owns the concurrency guarantees that make three requirements structurally true
|
|
5
|
+
* rather than hoped for — one connection under concurrent init (FR-018), one
|
|
6
|
+
* store request under concurrent sync (FR-063), and a rate-limited foreground
|
|
7
|
+
* sync (PERF-002).
|
|
8
|
+
*
|
|
9
|
+
* It never imports a store type. The only thing it talks to is `ProviderPort`,
|
|
10
|
+
* which is what keeps the binding replaceable and iOS additive (FR-002, FR-007).
|
|
11
|
+
*
|
|
12
|
+
* This file composes (PAY-10): state and its publication live in `state.ts`, the
|
|
13
|
+
* connection in `connection.ts`, sync in `sync.ts`, and the internals tests reach
|
|
14
|
+
* for in `internals.ts`, off the public type (PAY-11).
|
|
15
|
+
*/
|
|
16
|
+
import type { ProviderPort } from '../adapter/port';
|
|
17
|
+
import { type TargetPlatform } from '../config/validate';
|
|
18
|
+
import type { EntitlementKey, FinalizeResult, PaymentConfig, PaymentStatus, PendingPurchasesState, ProductKey, PurchaseOptions, PurchaseResult, TransactionRef, UnfinalizedSummary, Unsubscribe } from '../config/types';
|
|
19
|
+
import { PaymentError } from '../diagnostics/errors';
|
|
20
|
+
import { type PaymentEventListener, type SyncTrigger } from '../diagnostics/events';
|
|
21
|
+
import type { EntitlementMap, EntitlementState } from '../entitlements/aggregate';
|
|
22
|
+
import { type SnapshotStore } from '../persistence/mmkv-store';
|
|
23
|
+
import { type InitOutcome } from './connection';
|
|
24
|
+
import { type ProductQueryResult } from './products';
|
|
25
|
+
import { type PriceChangeResult, type ProrationMode } from './subscriptions';
|
|
26
|
+
import { type SyncOutcome } from './sync';
|
|
27
|
+
export type { SyncOutcome } from './sync';
|
|
28
|
+
export type { InitOutcome } from './connection';
|
|
29
|
+
export type RestoreOutcome = {
|
|
30
|
+
ok: true;
|
|
31
|
+
restored: true;
|
|
32
|
+
entitlements: EntitlementKey[];
|
|
33
|
+
}
|
|
34
|
+
/** Distinct from a failure so an app never shows a false success (FR-061). */
|
|
35
|
+
| {
|
|
36
|
+
ok: true;
|
|
37
|
+
restored: false;
|
|
38
|
+
} | {
|
|
39
|
+
ok: false;
|
|
40
|
+
error: PaymentError;
|
|
41
|
+
};
|
|
42
|
+
export interface EngineDeps {
|
|
43
|
+
/** Injected so the fake store is a drop-in replacement (NFR-007). */
|
|
44
|
+
provider: ProviderPort;
|
|
45
|
+
snapshotStore?: SnapshotStore;
|
|
46
|
+
platform?: TargetPlatform;
|
|
47
|
+
now?: () => number;
|
|
48
|
+
}
|
|
49
|
+
export interface PaymentEngine {
|
|
50
|
+
initialize(): Promise<InitOutcome>;
|
|
51
|
+
cleanup(): void;
|
|
52
|
+
getStatus(): PaymentStatus;
|
|
53
|
+
subscribeStatus(listener: (status: PaymentStatus) => void): Unsubscribe;
|
|
54
|
+
getEntitlement(key: EntitlementKey): EntitlementState;
|
|
55
|
+
getAllEntitlements(): EntitlementMap;
|
|
56
|
+
subscribeEntitlements(listener: (entitlements: EntitlementMap) => void): Unsubscribe;
|
|
57
|
+
/**
|
|
58
|
+
* Purchases whose money has not arrived, in this session or an earlier one
|
|
59
|
+
* (FR-101). Synchronous and in-memory, like `getEntitlement`. Added in 0.2.0.
|
|
60
|
+
*/
|
|
61
|
+
getPendingPurchases(): PendingPurchasesState;
|
|
62
|
+
/** Pushed only when the set, its status, or its staleness changes (FR-101). */
|
|
63
|
+
subscribePendingPurchases(listener: (pending: PendingPurchasesState) => void): Unsubscribe;
|
|
64
|
+
sync(trigger?: SyncTrigger): Promise<SyncOutcome>;
|
|
65
|
+
restore(): Promise<RestoreOutcome>;
|
|
66
|
+
getLastSyncedAt(): number | undefined;
|
|
67
|
+
clearLocalData(): Promise<void>;
|
|
68
|
+
subscribeEvents(listener: PaymentEventListener): Unsubscribe;
|
|
69
|
+
purchase(productKey: ProductKey, options?: PurchaseOptions): Promise<PurchaseResult>;
|
|
70
|
+
/** App-triggered consumption of a consumable (FR-043). */
|
|
71
|
+
consume(ref: TransactionRef): Promise<FinalizeResult>;
|
|
72
|
+
/** Paid-but-unsettled transactions, so the condition is observable (FR-045). */
|
|
73
|
+
getUnfinalized(): UnfinalizedSummary[];
|
|
74
|
+
getProducts(productKeys: ProductKey[]): Promise<ProductQueryResult>;
|
|
75
|
+
refreshProducts(productKeys: ProductKey[]): Promise<ProductQueryResult>;
|
|
76
|
+
changePlan(fromProductKey: ProductKey, toProductKey: ProductKey, mode: ProrationMode, options?: PurchaseOptions): Promise<PurchaseResult>;
|
|
77
|
+
/** Opens the **store's** management screen; never a self-built one (FR-066). */
|
|
78
|
+
openSubscriptionManagement(productKey?: ProductKey): Promise<void>;
|
|
79
|
+
confirmPriceChange(productKey: ProductKey): Promise<PriceChangeResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Call when the app returns to the foreground (FR-059).
|
|
82
|
+
*
|
|
83
|
+
* Left to the app rather than subscribing to `AppState` internally: the package
|
|
84
|
+
* must not decide what "foreground" means for a host that may be backgrounded
|
|
85
|
+
* by its own modal, a biometric prompt, or the store's purchase sheet. The
|
|
86
|
+
* engine rate-limits it regardless (PERF-002).
|
|
87
|
+
*/
|
|
88
|
+
handleForeground(): Promise<void>;
|
|
89
|
+
}
|
|
90
|
+
/** How many refused operations `status.blockedOperations` keeps. */
|
|
91
|
+
export declare const MAX_BLOCKED_OPERATIONS = 20;
|
|
92
|
+
export declare function createEngine(config: PaymentConfig, deps: EngineDeps): PaymentEngine;
|
|
93
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../../src/engine/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAEX,cAAc,EACd,cAAc,EACd,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAEN,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAGlE,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrE,OAAO,EAAuB,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAClG,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAEtD,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,MAAM,cAAc,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,cAAc,EAAE,CAAA;CAAE;AAC9D,8EAA8E;GAC5E;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC;AAEtC,MAAM,WAAW,UAAU;IAC1B,qEAAqE;IACrE,QAAQ,EAAE,YAAY,CAAC;IACvB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC7B,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IACnC,OAAO,IAAI,IAAI,CAAC;IAEhB,SAAS,IAAI,aAAa,CAAC;IAC3B,eAAe,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,GAAG,WAAW,CAAC;IAExE,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,gBAAgB,CAAC;IACtD,kBAAkB,IAAI,cAAc,CAAC;IACrC,qBAAqB,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,cAAc,KAAK,IAAI,GAAG,WAAW,CAAC;IAErF;;;OAGG;IACH,mBAAmB,IAAI,qBAAqB,CAAC;IAC7C,+EAA+E;IAC/E,yBAAyB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,GAAG,WAAW,CAAC;IAE3F,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAClD,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACnC,eAAe,IAAI,MAAM,GAAG,SAAS,CAAC;IACtC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC,eAAe,CAAC,QAAQ,EAAE,oBAAoB,GAAG,WAAW,CAAC;IAG7D,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACrF,0DAA0D;IAC1D,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACtD,gFAAgF;IAChF,cAAc,IAAI,kBAAkB,EAAE,CAAC;IAGvC,WAAW,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACpE,eAAe,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAGxE,UAAU,CACT,cAAc,EAAE,UAAU,EAC1B,YAAY,EAAE,UAAU,EACxB,IAAI,EAAE,aAAa,EACnB,OAAO,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3B,gFAAgF;IAChF,0BAA0B,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAGvE;;;;;;;OAOG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,aAAa,CA+NnF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The finalization queue — the package's hardest invariant (FR-041, FR-042).
|
|
3
|
+
*
|
|
4
|
+
* Google auto-refunds and revokes a purchase that is not acknowledged within
|
|
5
|
+
* **three days**. So finalization cannot be a step the app might forget, and it
|
|
6
|
+
* cannot live only in memory: the failure case FR-042 names is the app being
|
|
7
|
+
* force-killed in the instant between payment and acknowledgement.
|
|
8
|
+
*
|
|
9
|
+
* The ordering that makes this work is: **write the intent, then call the store.**
|
|
10
|
+
* A crash before the write means the purchase is still owned and the next sync
|
|
11
|
+
* re-queues it from `queryOwned`. A crash after the write means the queue has a
|
|
12
|
+
* record and the next startup drains it. There is no window where a paid
|
|
13
|
+
* transaction is forgotten.
|
|
14
|
+
*
|
|
15
|
+
* Consumption stays app-triggered (FR-043), because only the app knows whether
|
|
16
|
+
* the item was actually banked in its own data.
|
|
17
|
+
*/
|
|
18
|
+
import type { FinalizeResult, TransactionRef, UnfinalizedSummary } from '../config/types';
|
|
19
|
+
import type { ProviderPort } from '../adapter/port';
|
|
20
|
+
import type { ResolvedRetry } from '../core/timers';
|
|
21
|
+
import { type PersistedSnapshot } from '../persistence/snapshot';
|
|
22
|
+
import type { PaymentEventInput } from '../diagnostics/events';
|
|
23
|
+
export interface FinalizerDeps {
|
|
24
|
+
provider: ProviderPort;
|
|
25
|
+
retry: ResolvedRetry;
|
|
26
|
+
/** `timeouts.finalizeAttemptMs`: one acknowledge or consume call may take no longer. */
|
|
27
|
+
attemptTimeoutMs: number;
|
|
28
|
+
snapshot: () => PersistedSnapshot;
|
|
29
|
+
commit: (next: PersistedSnapshot) => void;
|
|
30
|
+
emit: (event: PaymentEventInput) => void;
|
|
31
|
+
now: () => number;
|
|
32
|
+
disposed: () => boolean;
|
|
33
|
+
/** Injected so a test can run the retry schedule without waiting it out. */
|
|
34
|
+
setTimeoutFn?: (fn: () => void, ms: number) => FinalizeTimerHandle;
|
|
35
|
+
clearTimeoutFn?: (handle: FinalizeTimerHandle) => void;
|
|
36
|
+
}
|
|
37
|
+
/** A Node `Timeout` and a browser numeric id are both valid here. */
|
|
38
|
+
type FinalizeTimerHandle = ReturnType<typeof setTimeout> | number;
|
|
39
|
+
export interface Finalizer {
|
|
40
|
+
/** Records the intent to finalize, then attempts it. Safe to call repeatedly. */
|
|
41
|
+
enqueue(transactionId: string): Promise<FinalizeResult>;
|
|
42
|
+
/** Drains every outstanding finalization. Runs at startup and on foreground. */
|
|
43
|
+
drain(): Promise<void>;
|
|
44
|
+
/** App-triggered consumption of a consumable (FR-043). */
|
|
45
|
+
consume(ref: TransactionRef): Promise<FinalizeResult>;
|
|
46
|
+
/** Paid-but-unsettled transactions, so the condition is observable (FR-045). */
|
|
47
|
+
unfinalized(): UnfinalizedSummary[];
|
|
48
|
+
/** Cancels pending retries. Idempotent, called from cleanup. */
|
|
49
|
+
dispose(): void;
|
|
50
|
+
}
|
|
51
|
+
export declare function createFinalizer(deps: FinalizerDeps): Finalizer;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=finalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finalize.d.ts","sourceRoot":"","sources":["../../../../src/engine/finalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACX,cAAc,EAEd,cAAc,EACd,kBAAkB,EAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,OAAO,EAGN,KAAK,iBAAiB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,wFAAwF;IACxF,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;IAClC,MAAM,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC1C,IAAI,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACzC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,mBAAmB,CAAC;IACnE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACvD;AAED,qEAAqE;AACrE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,MAAM,CAAC;AAElE,MAAM,WAAW,SAAS;IACzB,iFAAiF;IACjF,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACxD,gFAAgF;IAChF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,0DAA0D;IAC1D,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACtD,gFAAgF;IAChF,WAAW,IAAI,kBAAkB,EAAE,CAAC;IACpC,gEAAgE;IAChE,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,CAmR9D"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in foreground sync over rn-core's shared lifecycle port (PERF-07, FR-059).
|
|
3
|
+
*
|
|
4
|
+
* `handleForeground()` stays the app's to call: the engine does not decide what a
|
|
5
|
+
* foreground return is. An app that is happy with "back from the background" calls
|
|
6
|
+
* this once instead of wiring `AppState` itself, and shares the one native
|
|
7
|
+
* subscription every package uses. A trip through `inactive` alone (a biometric
|
|
8
|
+
* prompt, iOS Control Center) is not a return. On Android the Play purchase sheet
|
|
9
|
+
* does send the app to the background, so a purchase is followed by a sync; the
|
|
10
|
+
* engine's foreground rate limit keeps that to one request per interval.
|
|
11
|
+
*/
|
|
12
|
+
import { type AppLifecyclePort, type Unsubscribe } from '@chipmobilesdk/rn-core';
|
|
13
|
+
import type { PaymentEngine } from './engine';
|
|
14
|
+
export declare function syncOnForeground(engine: Pick<PaymentEngine, 'handleForeground'>, lifecycle?: AppLifecyclePort): Unsubscribe;
|
|
15
|
+
//# sourceMappingURL=foreground.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foreground.d.ts","sourceRoot":"","sources":["../../../../src/engine/foreground.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAGN,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,kBAAkB,CAAC,EAC/C,SAAS,GAAE,gBAAiC,GAC1C,WAAW,CAKb"}
|