forked from heroiclabs/nakama
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpipeline_purchase.go
108 lines (89 loc) · 3.47 KB
/
pipeline_purchase.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2017 The Nakama Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package server
import (
"errors"
"nakama/pkg/iap"
"strings"
"go.uber.org/zap"
)
func (p *pipeline) purchaseValidate(logger *zap.Logger, session *session, envelope *Envelope) {
purchase := envelope.GetPurchase()
var validationResponse *iap.PurchaseVerifyResponse
switch purchase.Id.(type) {
case *TPurchaseValidation_ApplePurchase_:
ap, err := p.convertApplePurchase(purchase.GetApplePurchase())
if err != nil {
logger.Warn("Could not process purchases", zap.Error(err))
session.Send(ErrorMessageBadInput(envelope.CollationId, err.Error()))
return
}
validationResponse = p.purchaseService.ValidateApplePurchase(session.userID, ap)
case *TPurchaseValidation_GooglePurchase_:
gp, err := p.convertGooglePurchase(purchase.GetGooglePurchase())
if err != nil {
logger.Warn("Could not process purchases", zap.Error(err))
session.Send(ErrorMessageBadInput(envelope.CollationId, err.Error()))
return
}
switch gp.ProductType {
case "product":
validationResponse = p.purchaseService.ValidateGooglePurchaseProduct(session.userID, gp)
case "subscription":
validationResponse = p.purchaseService.ValidateGooglePurchaseSubscription(session.userID, gp)
}
}
response := &Envelope_PurchaseRecord{PurchaseRecord: &TPurchaseRecord{
Success: validationResponse.Success,
PurchaseProviderReachable: validationResponse.PurchaseProviderReachable,
SeenBefore: validationResponse.SeenBefore,
Message: validationResponse.Message.Error(),
Data: validationResponse.Data,
}}
session.Send(&Envelope{CollationId: envelope.CollationId, Payload: response})
}
func (p *pipeline) convertApplePurchase(purchase *TPurchaseValidation_ApplePurchase) (*iap.ApplePurchase, error) {
if p.purchaseService.AppleClient == nil {
return nil, errors.New("Apple in-app purchase environment is not setup.")
}
if purchase.ReceiptData == "" {
return nil, errors.New("Missing receipt data.")
}
if purchase.ProductId == "" {
return nil, errors.New("Missing product ID.")
}
return &iap.ApplePurchase{
ProductId: purchase.ProductId,
ReceiptData: purchase.ReceiptData,
}, nil
}
func (p *pipeline) convertGooglePurchase(purchase *TPurchaseValidation_GooglePurchase) (*iap.GooglePurchase, error) {
if p.purchaseService.AppleClient == nil {
return nil, errors.New("Google in-app purchase environment is not setup.")
}
if !(purchase.ProductType == "product" || purchase.ProductType == "subscription") {
return nil, errors.New("Product type is required and must be one of: product, subscription")
}
if purchase.ProductId == "" {
return nil, errors.New("Missing product ID.")
}
if purchase.PurchaseToken == "" {
return nil, errors.New("Missing purchase token.")
}
return &iap.GooglePurchase{
ProductType: strings.ToLower(purchase.ProductType),
ProductId: purchase.ProductId,
PurchaseToken: purchase.PurchaseToken,
}, nil
}