@@ -2,7 +2,6 @@ package skus
2
2
3
3
import (
4
4
"context"
5
- "errors"
6
5
"fmt"
7
6
"net/http"
8
7
"net/http/httputil"
@@ -17,45 +16,11 @@ import (
17
16
"github.com/brave-intl/bat-go/services/skus/model"
18
17
)
19
18
20
- const (
21
- androidPaymentStatePending int64 = iota
22
- androidPaymentStatePaid
23
- androidPaymentStateTrial
24
- androidPaymentStatePendingDeferred
25
- )
26
-
27
- const (
28
- androidCancelReasonUser int64 = 0
29
- androidCancelReasonSystem int64 = 1
30
- androidCancelReasonReplaced int64 = 2
31
- androidCancelReasonDeveloper int64 = 3
32
-
33
- purchasePendingErrCode = "purchase_pending"
34
- purchaseDeferredErrCode = "purchase_deferred"
35
- purchaseStatusUnknownErrCode = "purchase_status_unknown"
36
- purchaseFailedErrCode = "purchase_failed"
37
- purchaseValidationErrCode = "validation_failed"
38
- )
39
-
40
19
const (
41
20
errNoInAppTx model.Error = "no in app info in response"
42
21
errIOSPurchaseNotFound model.Error = "ios: purchase not found"
43
22
)
44
23
45
- var (
46
- errPurchaseUserCanceled = errors .New ("purchase is canceled by user" )
47
- errPurchaseSystemCanceled = errors .New ("purchase is canceled by google playstore" )
48
- errPurchaseReplacedCanceled = errors .New ("purchase is canceled and replaced" )
49
- errPurchaseDeveloperCanceled = errors .New ("purchase is canceled by developer" )
50
-
51
- errPurchasePending = errors .New ("purchase is pending" )
52
- errPurchaseDeferred = errors .New ("purchase is deferred" )
53
- errPurchaseStatusUnknown = errors .New ("purchase status is unknown" )
54
- errPurchaseFailed = errors .New ("purchase failed" )
55
-
56
- errPurchaseExpired = errors .New ("purchase expired" )
57
- )
58
-
59
24
type dumpTransport struct {}
60
25
61
26
func (dt * dumpTransport ) RoundTrip (r * http.Request ) (* http.Response , error ) {
@@ -111,6 +76,8 @@ func newReceiptVerifier(cl *http.Client, asKey string, playKey []byte) (*receipt
111
76
}
112
77
113
78
// validateApple validates Apple App Store receipt.
79
+ //
80
+ // TODO(pavelb): Propagate expiry time for properly updating the order.
114
81
func (v * receiptVerifier ) validateApple (ctx context.Context , req model.ReceiptRequest ) (string , error ) {
115
82
asreq := appstore.IAPRequest {
116
83
Password : v .asKey ,
@@ -163,54 +130,29 @@ func (v *receiptVerifier) validateApple(ctx context.Context, req model.ReceiptRe
163
130
return item .OriginalTransactionID , nil
164
131
}
165
132
166
- // validateGoogle validates Google Store receipt.
133
+ // validateGoogle validates a Play Store receipt.
134
+ //
135
+ // TODO(pavelb): Propagate expiry time for properly updating the order.
167
136
func (v * receiptVerifier ) validateGoogle (ctx context.Context , req model.ReceiptRequest ) (string , error ) {
168
- l := logging .Logger (ctx , "skus" ).With ().Str ("func" , "validateReceiptGoogle" ).Logger ()
169
-
170
- l .Debug ().Str ("receipt" , fmt .Sprintf ("%+v" , req )).Msg ("about to verify subscription" )
137
+ return v .validateGoogleTime (ctx , req , time .Now ())
138
+ }
171
139
172
- resp , err := v .playStoreCl .VerifySubscription (ctx , req .Package , req .SubscriptionID , req .Blob )
140
+ func (v * receiptVerifier ) validateGoogleTime (ctx context.Context , req model.ReceiptRequest , now time.Time ) (string , error ) {
141
+ sub , err := v .playStoreCl .VerifySubscription (ctx , req .Package , req .SubscriptionID , req .Blob )
173
142
if err != nil {
174
- l .Error ().Err (err ).Msg ("failed to verify subscription" )
175
- return "" , errPurchaseFailed
143
+ return "" , fmt .Errorf ("failed to fetch subscription purchase: %w" , err )
176
144
}
177
145
178
- // Check order expiration.
179
- if time . Unix ( 0 , resp . ExpiryTimeMillis * int64 ( time . Millisecond )). Before ( time . Now () ) {
180
- return "" , errPurchaseExpired
146
+ psub := ( * playStoreSubPurchase )( sub )
147
+ if psub . hasExpired ( now ) {
148
+ return "" , errExpiredGPSSubPurchase
181
149
}
182
150
183
- l .Debug ().Msgf ("resp: %+v" , resp )
184
-
185
- if resp .PaymentState == nil {
186
- l .Error ().Err (err ).Msg ("failed to verify subscription: no payment state" )
187
- return "" , errPurchaseFailed
151
+ if psub .isPending () {
152
+ return "" , errPendingGPSSubPurchase
188
153
}
189
154
190
- // Check that the order was paid.
191
- switch * resp .PaymentState {
192
- case androidPaymentStatePaid , androidPaymentStateTrial :
193
- return req .Blob , nil
194
-
195
- case androidPaymentStatePending :
196
- // Check for cancel reason.
197
- switch resp .CancelReason {
198
- case androidCancelReasonUser :
199
- return "" , errPurchaseUserCanceled
200
- case androidCancelReasonSystem :
201
- return "" , errPurchaseSystemCanceled
202
- case androidCancelReasonReplaced :
203
- return "" , errPurchaseReplacedCanceled
204
- case androidCancelReasonDeveloper :
205
- return "" , errPurchaseDeveloperCanceled
206
- }
207
- return "" , errPurchasePending
208
-
209
- case androidPaymentStatePendingDeferred :
210
- return "" , errPurchaseDeferred
211
- default :
212
- return "" , errPurchaseStatusUnknown
213
- }
155
+ return req .Blob , nil
214
156
}
215
157
216
158
func findInAppBySubID (iap []appstore.InApp , subID string ) (* appstore.InApp , bool ) {
0 commit comments