@@ -172,6 +172,7 @@ func ValidatePurchaseGoogle(ctx context.Context, logger *zap.Logger, db *sql.DB,
172
172
if ! persist {
173
173
validatedPurchases := []* api.ValidatedPurchase {
174
174
{
175
+ UserId : userID .String (),
175
176
ProductId : sPurchase .productId ,
176
177
TransactionId : sPurchase .transactionId ,
177
178
Store : sPurchase .store ,
@@ -446,6 +447,7 @@ func ListPurchases(ctx context.Context, logger *zap.Logger, db *sql.DB, userID s
446
447
purchase_time,
447
448
create_time,
448
449
update_time,
450
+ refund_time,
449
451
environment
450
452
FROM
451
453
purchase
@@ -472,9 +474,10 @@ func ListPurchases(ctx context.Context, logger *zap.Logger, db *sql.DB, userID s
472
474
var purchaseTime pgtype.Timestamptz
473
475
var createTime pgtype.Timestamptz
474
476
var updateTime pgtype.Timestamptz
477
+ var refundTime pgtype.Timestamptz
475
478
var environment api.StoreEnvironment
476
479
477
- if err = rows .Scan (& dbUserID , & transactionId , & productId , & store , & rawResponse , & purchaseTime , & createTime , & updateTime , & environment ); err != nil {
480
+ if err = rows .Scan (& dbUserID , & transactionId , & productId , & store , & rawResponse , & purchaseTime , & createTime , & updateTime , & refundTime , & environment ); err != nil {
478
481
logger .Error ("Error retrieving purchases." , zap .Error (err ))
479
482
return nil , err
480
483
}
@@ -500,6 +503,9 @@ func ListPurchases(ctx context.Context, logger *zap.Logger, db *sql.DB, userID s
500
503
ProviderResponse : rawResponse ,
501
504
Environment : environment ,
502
505
}
506
+ if refundTime .Time .Unix () != 0 {
507
+ purchase .RefundTime = timestamppb .New (purchase .RefundTime .AsTime ())
508
+ }
503
509
504
510
purchases = append (purchases , purchase )
505
511
@@ -575,6 +581,8 @@ func upsertPurchases(ctx context.Context, db *sql.DB, purchases []*storagePurcha
575
581
return nil , errors .New ("expects at least one receipt" )
576
582
}
577
583
584
+ userIDIn := purchases [0 ].userID
585
+
578
586
statements := make ([]string , 0 , len (purchases ))
579
587
params := make ([]interface {}, 0 , len (purchases )* 8 )
580
588
transactionIDsToPurchase := make (map [string ]* storagePurchase )
@@ -613,72 +621,49 @@ VALUES
613
621
ON CONFLICT
614
622
(transaction_id)
615
623
DO UPDATE SET
616
- refund_time = $8, update_time = now()
624
+ refund_time = $8,
625
+ update_time = now()
617
626
RETURNING
618
- transaction_id, create_time, update_time, refund_time
627
+ user_id,
628
+ transaction_id,
629
+ create_time,
630
+ update_time,
631
+ refund_time
619
632
`
620
- insertedTransactionIDs := make (map [string ]struct {})
621
633
rows , err := db .QueryContext (ctx , query , params ... )
622
634
if err != nil {
623
635
return nil , err
624
636
}
625
637
for rows .Next () {
626
638
// Newly inserted purchases
639
+ var dbUserID uuid.UUID
627
640
var transactionId string
628
641
var createTime pgtype.Timestamptz
629
642
var updateTime pgtype.Timestamptz
630
643
var refundTime pgtype.Timestamptz
631
- if err = rows .Scan (& transactionId , & createTime , & updateTime , & refundTime ); err != nil {
644
+ if err = rows .Scan (& dbUserID , & transactionId , & createTime , & updateTime , & refundTime ); err != nil {
632
645
rows .Close ()
633
646
return nil , err
634
647
}
635
648
storedPurchase , _ := transactionIDsToPurchase [transactionId ]
636
649
storedPurchase .createTime = createTime .Time
637
650
storedPurchase .updateTime = updateTime .Time
638
- storedPurchase .refundTime = refundTime .Time
639
- storedPurchase .seenBefore = false
640
- insertedTransactionIDs [storedPurchase .transactionId ] = struct {}{}
651
+ storedPurchase .seenBefore = updateTime .Time .After (createTime .Time )
652
+ if refundTime .Time .Unix () != 0 {
653
+ storedPurchase .refundTime = refundTime .Time
654
+ }
641
655
}
642
656
rows .Close ()
643
657
if err := rows .Err (); err != nil {
644
658
return nil , err
645
659
}
646
660
647
- // Go over purchases that have not been inserted (already exist in the DB) and fetch createTime and updateTime
648
- if len (transactionIDsToPurchase ) > len (insertedTransactionIDs ) {
649
- seenIDs := make ([]string , 0 , len (transactionIDsToPurchase ))
650
- for tID , _ := range transactionIDsToPurchase {
651
- if _ , ok := insertedTransactionIDs [tID ]; ! ok {
652
- seenIDs = append (seenIDs , tID )
653
- }
654
- }
655
-
656
- rows , err = db .QueryContext (ctx , "SELECT transaction_id, create_time, update_time FROM purchase WHERE transaction_id IN ($1)" , strings .Join (seenIDs , ", " ))
657
- if err != nil {
658
- return nil , err
659
- }
660
- for rows .Next () {
661
- // Already seen purchases
662
- var transactionId string
663
- var createTime pgtype.Timestamptz
664
- var updateTime pgtype.Timestamptz
665
- if err = rows .Scan (& transactionId , & createTime , & updateTime ); err != nil {
666
- rows .Close ()
667
- return nil , err
668
- }
669
- storedPurchase , _ := transactionIDsToPurchase [transactionId ]
670
- storedPurchase .createTime = createTime .Time
671
- storedPurchase .updateTime = updateTime .Time
672
- storedPurchase .seenBefore = true
673
- }
674
- rows .Close ()
675
- if err := rows .Err (); err != nil {
676
- return nil , err
677
- }
678
- }
679
-
680
661
storedPurchases := make ([]* storagePurchase , 0 , len (transactionIDsToPurchase ))
681
662
for _ , purchase := range transactionIDsToPurchase {
663
+ if purchase .seenBefore && purchase .userID != userIDIn {
664
+ // Mismatch between userID requesting validation and existing receipt userID, return error.
665
+ return nil , status .Error (codes .FailedPrecondition , "Invalid receipt for userID." )
666
+ }
682
667
storedPurchases = append (storedPurchases , purchase )
683
668
}
684
669
0 commit comments