in in_app_purchases/complete/firebase-backend/functions/src/app-store.purchase-handler.ts [49:107]
private async handleValidation(
userId: string,
token: string,
): Promise<boolean> {
// Validate receipt and fetch the products
let products: appleReceiptVerify.PurchasedProducts[];
try {
products = await appleReceiptVerify.validate({receipt: token});
} catch (e) {
if (e instanceof appleReceiptVerify.EmptyError) {
// Receipt is valid but it is now empty.
console.warn(
"Received valid empty receipt");
return true;
} else if (e instanceof
appleReceiptVerify.ServiceUnavailableError) {
console.warn(
"App store is currently unavailable, could not validate");
// Handle app store services not being available
return false;
}
return false;
}
// Process the received products
for (const product of products) {
// Skip processing the product if it is unknown
const productData = productDataMap[product.productId];
if (!productData) continue;
// Process the product
switch (productData.type) {
case "SUBSCRIPTION":
await this.iapRepository.createOrUpdatePurchase({
type: productData.type,
iapSource: "app_store",
orderId: product.originalTransactionId,
productId: product.productId,
userId,
purchaseDate: firestore.Timestamp.fromMillis(product.purchaseDate),
expiryDate: firestore.Timestamp.fromMillis(
product.expirationDate ?? 0,
),
status: (product.expirationDate ?? 0) <= Date.now() ? "EXPIRED" : "ACTIVE",
});
break;
case "NON_SUBSCRIPTION":
await this.iapRepository.createOrUpdatePurchase({
type: productData.type,
iapSource: "app_store",
orderId: product.originalTransactionId,
productId: product.productId,
userId,
purchaseDate: firestore.Timestamp.fromMillis(product.purchaseDate),
status: "COMPLETED",
});
break;
}
}
return true;
}