in ClassyTaxiServer/src/play-billing/PurchasesManager.ts [104:161]
private async querySubscriptionPurchaseWithTrigger(packageName: string, sku: string, purchaseToken: string, triggerNotificationType?: NotificationType): Promise<SubscriptionPurchase> {
// STEP 1. Query Play Developer API to verify the purchase token
const apiResponse = await new Promise((resolve, reject) => {
this.playDeveloperApiClient.purchases.subscriptions.get({
packageName: packageName,
subscriptionId: sku,
token: purchaseToken
}, (err, result) => {
if (err) {
reject(this.convertPlayAPIErrorToLibraryError(err));
} else {
resolve(result.data);
}
})
});
try {
// STEP 2. Look up purchase records from Firestore which matches this purchase token
const purchaseRecordDoc = await this.purchasesDbRef.doc(purchaseToken).get();
// Generate SubscriptionPurchase object from Firestore response
const now = Date.now();
const subscriptionPurchase = SubscriptionPurchaseImpl.fromApiResponse(apiResponse, packageName, purchaseToken, sku, now);
// Store notificationType to database if queryPurchase was triggered by a realtime developer notification
if (triggerNotificationType !== undefined) {
subscriptionPurchase.latestNotificationType = triggerNotificationType;
}
// Convert subscriptionPurchase object to a format that to be stored in Firestore
const firestoreObject = subscriptionPurchase.toFirestoreObject();
if (purchaseRecordDoc.exists) {
// STEP 3a. We has this purchase cached in Firstore. Update our cache with the newly received response from Google Play Developer API
await purchaseRecordDoc.ref.update(firestoreObject);
// STEP 4a. Merge other fields of our purchase record in Firestore (such as userId) with our SubscriptionPurchase object and return to caller.
mergePurchaseWithFirestorePurchaseRecord(subscriptionPurchase, purchaseRecordDoc.data());
return subscriptionPurchase;
} else {
// STEP 3b. This is a brand-new subscription purchase. Just save the purchase record to Firestore
await purchaseRecordDoc.ref.set(firestoreObject);
if (subscriptionPurchase.linkedPurchaseToken) {
// STEP 4b. This is a subscription purchase that replaced other subscriptions in the past. Let's disable the purchases that it has replaced.
await this.disableReplacedSubscription(packageName, sku, subscriptionPurchase.linkedPurchaseToken);
}
// STEP 5. This is a brand-new subscription purchase. Just save the purchase record to Firestore and return an SubscriptionPurchase object with userId = null.
return subscriptionPurchase;
}
} catch (err) {
// Some unexpected error has occured while interacting with Firestore.
const libraryError = new Error(err.message);
libraryError.name = PurchaseQueryError.OTHER_ERROR;
throw libraryError;
}
}