Loading server/core_purchase.go +9 −5 Original line number Diff line number Diff line Loading @@ -63,11 +63,6 @@ func ValidatePurchasesApple(ctx context.Context, logger *zap.Logger, db *sql.DB, return nil, status.Error(codes.FailedPrecondition, fmt.Sprintf("Invalid Receipt. Status: %d", validation.Status)) } if validation.LatestReceipt != "" { // Receipt is for a subscription, ValidateSubscriptionApple should be used instead. return nil, status.Error(codes.FailedPrecondition, "Subscription Receipt. Use the appropriate function instead.") } env := api.StoreEnvironment_PRODUCTION if validation.Environment == iap.AppleSandboxEnvironment { env = api.StoreEnvironment_SANDBOX Loading @@ -75,6 +70,10 @@ func ValidatePurchasesApple(ctx context.Context, logger *zap.Logger, db *sql.DB, storagePurchases := make([]*storagePurchase, 0, len(validation.Receipt.InApp)) for _, purchase := range validation.Receipt.InApp { if purchase.ExpiresDateMs != "" { continue } purchaseTime, err := strconv.ParseInt(purchase.PurchaseDateMs, 10, 64) if err != nil { return nil, err Loading @@ -91,6 +90,11 @@ func ValidatePurchasesApple(ctx context.Context, logger *zap.Logger, db *sql.DB, }) } if len(storagePurchases) == 0 && len(validation.Receipt.InApp) > 0 { // All purchases in this receipt are subscriptions. return nil, status.Error(codes.FailedPrecondition, "Subscription Receipt. Use the appropriate function instead.") } if !persist { // Skip storing the receipts validatedPurchases := make([]*api.ValidatedPurchase, 0, len(storagePurchases)) Loading server/core_subscription.go +18 −10 Original line number Diff line number Diff line Loading @@ -248,24 +248,32 @@ func ValidateSubscriptionApple(ctx context.Context, logger *zap.Logger, db *sql. return nil, status.Error(codes.FailedPrecondition, fmt.Sprintf("Invalid Receipt. Status: %d", validation.Status)) } if validation.LatestReceipt == "" { // Receipt is for a purchase, ValidatePurchaseApple should be used instead. return nil, status.Error(codes.FailedPrecondition, "Purchase Receipt. Use the appropriate function instead.") } env := api.StoreEnvironment_PRODUCTION if validation.Environment == iap.AppleSandboxEnvironment { env = api.StoreEnvironment_SANDBOX } latestSubReceiptInfo := validation.LatestReceiptInfo[0] var found bool var receiptInfo iap.ValidateReceiptAppleResponseLatestReceiptInfo for _, latestReceiptInfo := range validation.LatestReceiptInfo { if latestReceiptInfo.ExpiresDateMs == "" { // Not a subscription, skip. continue } receiptInfo = latestReceiptInfo found = true } if !found { // Receipt is for a purchase (or otherwise has no subscriptions for any reason) so ValidatePurchaseApple should be used instead. return nil, status.Error(codes.FailedPrecondition, "Purchase Receipt. Use the appropriate function instead.") } purchaseTime, err := strconv.ParseInt(latestSubReceiptInfo.OriginalPurchaseDateMs, 10, 64) purchaseTime, err := strconv.ParseInt(receiptInfo.OriginalPurchaseDateMs, 10, 64) if err != nil { return nil, err } expireTimeInt, err := strconv.ParseInt(latestSubReceiptInfo.ExpiresDateMs, 10, 64) expireTimeInt, err := strconv.ParseInt(receiptInfo.ExpiresDateMs, 10, 64) if err != nil { return nil, err } Loading @@ -280,8 +288,8 @@ func ValidateSubscriptionApple(ctx context.Context, logger *zap.Logger, db *sql. storageSub := &storageSubscription{ userID: userID, store: api.StoreProvider_APPLE_APP_STORE, productId: latestSubReceiptInfo.ProductId, originalTransactionId: latestSubReceiptInfo.OriginalTransactionId, productId: receiptInfo.ProductId, originalTransactionId: receiptInfo.OriginalTransactionId, purchaseTime: parseMillisecondUnixTimestamp(purchaseTime), environment: env, expireTime: expireTime, Loading Loading
server/core_purchase.go +9 −5 Original line number Diff line number Diff line Loading @@ -63,11 +63,6 @@ func ValidatePurchasesApple(ctx context.Context, logger *zap.Logger, db *sql.DB, return nil, status.Error(codes.FailedPrecondition, fmt.Sprintf("Invalid Receipt. Status: %d", validation.Status)) } if validation.LatestReceipt != "" { // Receipt is for a subscription, ValidateSubscriptionApple should be used instead. return nil, status.Error(codes.FailedPrecondition, "Subscription Receipt. Use the appropriate function instead.") } env := api.StoreEnvironment_PRODUCTION if validation.Environment == iap.AppleSandboxEnvironment { env = api.StoreEnvironment_SANDBOX Loading @@ -75,6 +70,10 @@ func ValidatePurchasesApple(ctx context.Context, logger *zap.Logger, db *sql.DB, storagePurchases := make([]*storagePurchase, 0, len(validation.Receipt.InApp)) for _, purchase := range validation.Receipt.InApp { if purchase.ExpiresDateMs != "" { continue } purchaseTime, err := strconv.ParseInt(purchase.PurchaseDateMs, 10, 64) if err != nil { return nil, err Loading @@ -91,6 +90,11 @@ func ValidatePurchasesApple(ctx context.Context, logger *zap.Logger, db *sql.DB, }) } if len(storagePurchases) == 0 && len(validation.Receipt.InApp) > 0 { // All purchases in this receipt are subscriptions. return nil, status.Error(codes.FailedPrecondition, "Subscription Receipt. Use the appropriate function instead.") } if !persist { // Skip storing the receipts validatedPurchases := make([]*api.ValidatedPurchase, 0, len(storagePurchases)) Loading
server/core_subscription.go +18 −10 Original line number Diff line number Diff line Loading @@ -248,24 +248,32 @@ func ValidateSubscriptionApple(ctx context.Context, logger *zap.Logger, db *sql. return nil, status.Error(codes.FailedPrecondition, fmt.Sprintf("Invalid Receipt. Status: %d", validation.Status)) } if validation.LatestReceipt == "" { // Receipt is for a purchase, ValidatePurchaseApple should be used instead. return nil, status.Error(codes.FailedPrecondition, "Purchase Receipt. Use the appropriate function instead.") } env := api.StoreEnvironment_PRODUCTION if validation.Environment == iap.AppleSandboxEnvironment { env = api.StoreEnvironment_SANDBOX } latestSubReceiptInfo := validation.LatestReceiptInfo[0] var found bool var receiptInfo iap.ValidateReceiptAppleResponseLatestReceiptInfo for _, latestReceiptInfo := range validation.LatestReceiptInfo { if latestReceiptInfo.ExpiresDateMs == "" { // Not a subscription, skip. continue } receiptInfo = latestReceiptInfo found = true } if !found { // Receipt is for a purchase (or otherwise has no subscriptions for any reason) so ValidatePurchaseApple should be used instead. return nil, status.Error(codes.FailedPrecondition, "Purchase Receipt. Use the appropriate function instead.") } purchaseTime, err := strconv.ParseInt(latestSubReceiptInfo.OriginalPurchaseDateMs, 10, 64) purchaseTime, err := strconv.ParseInt(receiptInfo.OriginalPurchaseDateMs, 10, 64) if err != nil { return nil, err } expireTimeInt, err := strconv.ParseInt(latestSubReceiptInfo.ExpiresDateMs, 10, 64) expireTimeInt, err := strconv.ParseInt(receiptInfo.ExpiresDateMs, 10, 64) if err != nil { return nil, err } Loading @@ -280,8 +288,8 @@ func ValidateSubscriptionApple(ctx context.Context, logger *zap.Logger, db *sql. storageSub := &storageSubscription{ userID: userID, store: api.StoreProvider_APPLE_APP_STORE, productId: latestSubReceiptInfo.ProductId, originalTransactionId: latestSubReceiptInfo.OriginalTransactionId, productId: receiptInfo.ProductId, originalTransactionId: receiptInfo.OriginalTransactionId, purchaseTime: parseMillisecondUnixTimestamp(purchaseTime), environment: env, expireTime: expireTime, Loading