@mpgd/game-services 0.23.0 → 0.24.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/README.md +46 -12
- package/dist/apps-in-toss-partner-api.d.ts +7 -0
- package/dist/apps-in-toss-partner-api.js +34 -0
- package/dist/client.d.ts +8 -6
- package/dist/client.js +16 -129
- package/dist/commerce-reconciler.d.ts +9 -5
- package/dist/commerce-reconciler.js +88 -23
- package/dist/google-play-purchase.d.ts +0 -9
- package/dist/google-play-purchase.js +0 -9
- package/dist/monetization-operation-store.d.ts +15 -6
- package/dist/monetization-operation-store.js +23 -8
- package/dist/monetization-recovery.d.ts +30 -25
- package/dist/monetization-recovery.js +125 -302
- package/dist/notification-delivery.js +5 -35
- package/dist/types.d.ts +0 -9
- package/package.json +6 -5
- package/dist/authoritative-purchase.d.ts +0 -32
- package/dist/authoritative-purchase.js +0 -62
|
@@ -1,14 +1,23 @@
|
|
|
1
|
-
import type { MonetizationOperationRecord, MonetizationOperationStore } from './monetization-recovery.js';
|
|
1
|
+
import type { MonetizationOperationRecord, MonetizationOperationStore, RetiredPurchaseOperationRecord } from './monetization-recovery.js';
|
|
2
2
|
/**
|
|
3
3
|
* Whether a journal record still needs a reconcile pass. A game's durable
|
|
4
4
|
* `MonetizationOperationStore.listRecoverable` applies this rule (or an
|
|
5
|
-
* equivalent index): a
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* equivalent index): a rewarded-ad record is open until it holds a
|
|
6
|
+
* non-pending result; a commerce purchase record is open until its state is
|
|
7
|
+
* terminal (`finished`, `cancelled`, `failed`, `rejected`, `revoked`). A
|
|
8
|
+
* retired v1 `purchase` record (written before commerce v2 C4) is open only
|
|
9
|
+
* while it holds a completed platform result and either no terminal result or
|
|
10
|
+
* a grant whose finalization is still pending: the recoverable client sends
|
|
11
|
+
* its verification to the backend once more and closes it. Terminal records stay addressable by `read` for duplicate
|
|
12
|
+
* protection.
|
|
10
13
|
*/
|
|
11
14
|
export declare function isMonetizationOperationRecoverable(record: MonetizationOperationRecord): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* A retired v1 purchase record whose backend verification was never settled,
|
|
17
|
+
* or whose grant still waits for the backend to consume or acknowledge the
|
|
18
|
+
* store purchase (`response.finalization.status === 'pending'`).
|
|
19
|
+
*/
|
|
20
|
+
export declare function isRetiredPurchaseOpen(record: RetiredPurchaseOperationRecord): boolean;
|
|
12
21
|
/** Whether a commerce v2 record holds a ledger grant the revocation pass should keep checking. */
|
|
13
22
|
export declare function isMonetizationOperationGranted(record: MonetizationOperationRecord): boolean;
|
|
14
23
|
/**
|
|
@@ -2,20 +2,35 @@ import { isTerminalCommercePurchaseState } from '@mpgd/platform/commerce';
|
|
|
2
2
|
/**
|
|
3
3
|
* Whether a journal record still needs a reconcile pass. A game's durable
|
|
4
4
|
* `MonetizationOperationStore.listRecoverable` applies this rule (or an
|
|
5
|
-
* equivalent index): a
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* equivalent index): a rewarded-ad record is open until it holds a
|
|
6
|
+
* non-pending result; a commerce purchase record is open until its state is
|
|
7
|
+
* terminal (`finished`, `cancelled`, `failed`, `rejected`, `revoked`). A
|
|
8
|
+
* retired v1 `purchase` record (written before commerce v2 C4) is open only
|
|
9
|
+
* while it holds a completed platform result and either no terminal result or
|
|
10
|
+
* a grant whose finalization is still pending: the recoverable client sends
|
|
11
|
+
* its verification to the backend once more and closes it. Terminal records stay addressable by `read` for duplicate
|
|
12
|
+
* protection.
|
|
10
13
|
*/
|
|
11
14
|
export function isMonetizationOperationRecoverable(record) {
|
|
12
15
|
if (record.kind === 'commerce-purchase') {
|
|
13
16
|
return !isTerminalCommercePurchaseState(record.state);
|
|
14
17
|
}
|
|
15
|
-
if (record.
|
|
16
|
-
return
|
|
18
|
+
if (record.kind === 'purchase') {
|
|
19
|
+
return isRetiredPurchaseOpen(record);
|
|
17
20
|
}
|
|
18
|
-
return record.
|
|
21
|
+
return record.result === undefined || record.result.status === 'pending';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A retired v1 purchase record whose backend verification was never settled,
|
|
25
|
+
* or whose grant still waits for the backend to consume or acknowledge the
|
|
26
|
+
* store purchase (`response.finalization.status === 'pending'`).
|
|
27
|
+
*/
|
|
28
|
+
export function isRetiredPurchaseOpen(record) {
|
|
29
|
+
return record.platform?.status === 'completed'
|
|
30
|
+
&& record.platform.transactionId !== undefined
|
|
31
|
+
&& (record.result === undefined
|
|
32
|
+
|| record.result.status === 'pending'
|
|
33
|
+
|| record.response?.finalization?.status === 'pending');
|
|
19
34
|
}
|
|
20
35
|
/** Whether a commerce v2 record holds a ledger grant the revocation pass should keep checking. */
|
|
21
36
|
export function isMonetizationOperationGranted(record) {
|
|
@@ -13,27 +13,42 @@ interface OperationIdentity {
|
|
|
13
13
|
/** Fixed when a platform result is first journaled, before backend dispatch. */
|
|
14
14
|
readonly platformCompletedAt?: string;
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* The v1 purchase journal record. Releases before commerce v2 C4 wrote them;
|
|
18
|
+
* the reconciler is now the only purchase path, so nothing starts, reopens, or
|
|
19
|
+
* grants from one. A durable journal still parses it, and the one thing
|
|
20
|
+
* `reconcile()` still does with it is finish an in-flight verification: a
|
|
21
|
+
* record that holds a completed platform result and no terminal result sends
|
|
22
|
+
* its saved verify request (or the one its own fields describe) to the
|
|
23
|
+
* backend once more, through the ledger and under the same idempotency key,
|
|
24
|
+
* then closes the record with what the backend answered. A record without a
|
|
25
|
+
* completed platform result is closed without a request: whatever the store
|
|
26
|
+
* still holds is found again from the store's own unfinished list.
|
|
27
|
+
*/
|
|
28
|
+
export type RetiredPurchaseOperationRecord = OperationIdentity & {
|
|
18
29
|
readonly kind: 'purchase';
|
|
19
30
|
readonly input: GameServicesPurchaseInput;
|
|
20
31
|
readonly platform?: PurchaseResult;
|
|
21
32
|
readonly request?: VerifyPurchaseRequest;
|
|
22
33
|
readonly response?: VerifyPurchaseResponse;
|
|
23
34
|
readonly result?: GameServicesPurchaseResult;
|
|
24
|
-
}
|
|
35
|
+
};
|
|
36
|
+
/** The rewarded-ad journal record. */
|
|
37
|
+
export type RewardedAdOperationRecord = OperationIdentity & {
|
|
25
38
|
readonly kind: 'rewarded-ad';
|
|
26
39
|
readonly input: GameServicesRewardedAdInput;
|
|
27
40
|
readonly platform?: RewardedAdResult;
|
|
28
41
|
readonly request?: ClaimAdRewardRequest;
|
|
29
42
|
readonly response?: ClaimAdRewardResponse;
|
|
30
43
|
readonly result?: GameServicesRewardedAdResult;
|
|
31
|
-
}
|
|
44
|
+
};
|
|
45
|
+
/** The pre-reconciler journal records: a retired purchase record and the live rewarded-ad record. */
|
|
46
|
+
export type LegacyMonetizationOperationRecord = RetiredPurchaseOperationRecord | RewardedAdOperationRecord;
|
|
32
47
|
/**
|
|
33
48
|
* Every record kind the journal holds. `commerce-purchase` records are the
|
|
34
|
-
*
|
|
35
|
-
* `
|
|
36
|
-
*
|
|
49
|
+
* reconciler's (`./commerce-reconciler`); their open state is `state`, not
|
|
50
|
+
* `result`, and `isMonetizationOperationRecoverable` applies the rule for
|
|
51
|
+
* every kind.
|
|
37
52
|
*/
|
|
38
53
|
export type MonetizationOperationRecord = LegacyMonetizationOperationRecord | CommercePurchaseOperationRecord;
|
|
39
54
|
/** Games must supply a durable, atomic implementation; an in-memory map is not recovery. */
|
|
@@ -49,13 +64,13 @@ export interface MonetizationOperationStore {
|
|
|
49
64
|
/** Return only unresolved operations; keep terminal records addressable by read for deduplication. */
|
|
50
65
|
listRecoverable(playerId: string): Promise<readonly MonetizationOperationRecord[]>;
|
|
51
66
|
/**
|
|
52
|
-
*
|
|
67
|
+
* Reconciler records in `granted`, `finishing`, or `finished` kept within
|
|
53
68
|
* the journal retention window, for the reconciler's revocation pass. A
|
|
54
69
|
* store without it only reports reversals of grants seen in this session.
|
|
55
70
|
*/
|
|
56
71
|
listGranted?(playerId: string): Promise<readonly MonetizationOperationRecord[]>;
|
|
57
72
|
/**
|
|
58
|
-
* The
|
|
73
|
+
* The reconciler record, terminal or not, whose `purchase.transactionId`
|
|
59
74
|
* is this store transaction. With it a transaction the store lists again
|
|
60
75
|
* after a restart (an owned durable, a rejected or finished purchase) meets
|
|
61
76
|
* its own record instead of being verified again under a derived key.
|
|
@@ -75,7 +90,7 @@ export interface MonetizationOperationSummary {
|
|
|
75
90
|
readonly kind: MonetizationOperationRecord['kind'];
|
|
76
91
|
readonly idempotencyKey: string;
|
|
77
92
|
/**
|
|
78
|
-
* RFC "Purchase lifecycle" mapping for a
|
|
93
|
+
* RFC "Purchase lifecycle" mapping for a reconciler record: `granted`
|
|
79
94
|
* covers `granted`, `finishing`, and `finished`; `pending` covers
|
|
80
95
|
* `launched`, `pending`, `purchased`, and `verifying`; `revoked` is a
|
|
81
96
|
* reversed grant.
|
|
@@ -84,29 +99,19 @@ export interface MonetizationOperationSummary {
|
|
|
84
99
|
readonly finalizationPending: boolean;
|
|
85
100
|
}
|
|
86
101
|
export interface RecoverableMonetizationClient extends GameServicesOperationClient {
|
|
87
|
-
/**
|
|
88
|
-
* Replays a platform purchase callback into a v1 journal record.
|
|
89
|
-
*
|
|
90
|
-
* @deprecated For a gateway with a commerce v2 provider the reconciler
|
|
91
|
-
* learns the result from the provider itself: this call then runs one
|
|
92
|
-
* reconcile pass and returns the journaled result for the key, ignoring
|
|
93
|
-
* `platform`. Removed with the v1 adapter in C4.
|
|
94
|
-
*/
|
|
95
|
-
recoverPurchaseResult(idempotencyKey: string, platform: PurchaseResult): Promise<GameServicesPurchaseResult>;
|
|
96
102
|
recoverRewardResult(idempotencyKey: string, platform: RewardedAdResult): Promise<GameServicesRewardedAdResult>;
|
|
97
103
|
/**
|
|
98
|
-
* Startup and app-resume recovery: resumes
|
|
99
|
-
*
|
|
104
|
+
* Startup and app-resume recovery: resumes rewarded-ad records and, with a
|
|
105
|
+
* commerce provider, starts or runs the reconciler (subscribe, read available
|
|
100
106
|
* purchases, send saved verify requests, finish granted purchases).
|
|
101
107
|
*/
|
|
102
108
|
reconcile(): Promise<readonly MonetizationOperationSummary[]>;
|
|
103
109
|
/**
|
|
104
|
-
* The manual restore trigger of the
|
|
105
|
-
*
|
|
106
|
-
* provider it is `reconcile()`.
|
|
110
|
+
* The manual restore trigger of the reconciler (`provider.restorePurchases`
|
|
111
|
+
* when offered, then a pass). Without a commerce provider it is `reconcile()`.
|
|
107
112
|
*/
|
|
108
113
|
restorePurchases(): Promise<readonly MonetizationOperationSummary[]>;
|
|
109
|
-
/** Present when the gateway exposes `
|
|
114
|
+
/** Present when the gateway exposes `commerce`. */
|
|
110
115
|
readonly commerceReconciler?: CommerceReconciler;
|
|
111
116
|
}
|
|
112
117
|
/**
|