-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpayload.go
119 lines (104 loc) · 4.04 KB
/
payload.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
109
110
111
112
113
114
115
116
117
118
119
package webhook
import (
"context"
"strings"
"github.com/pkg/errors"
currency_lib "github.com/code-payments/code-server/pkg/currency"
code_data "github.com/code-payments/code-server/pkg/code/data"
"github.com/code-payments/code-server/pkg/code/data/account"
"github.com/code-payments/code-server/pkg/code/data/action"
"github.com/code-payments/code-server/pkg/code/data/intent"
"github.com/code-payments/code-server/pkg/code/data/webhook"
)
type jsonPayloadProvider func(ctx context.Context, data code_data.Provider, record *webhook.Record) (map[string]interface{}, error)
var jsonPayloadProviders = map[webhook.Type]jsonPayloadProvider{
webhook.TypeIntentSubmitted: intentSubmittedJsonPayloadProvider,
webhook.TypeTest: testJsonPayloadProvider,
}
func intentSubmittedJsonPayloadProvider(ctx context.Context, data code_data.Provider, webhookRecord *webhook.Record) (map[string]interface{}, error) {
if webhookRecord.Type != webhook.TypeIntentSubmitted {
return nil, errors.New("invalid webhook type")
}
intentRecord, err := data.GetIntent(ctx, webhookRecord.WebhookId)
if err != nil {
return nil, errors.Wrap(err, "error getting intent record")
} else if intentRecord.State == intent.StateRevoked {
return nil, errors.New("intent is revoked")
}
var currency currency_lib.Code
var amount float64
var exchangeRate float64
var quarks uint64
var destination string
var isMicroPayment bool
switch intentRecord.IntentType {
case intent.SendPrivatePayment:
currency = intentRecord.SendPrivatePaymentMetadata.ExchangeCurrency
amount = intentRecord.SendPrivatePaymentMetadata.NativeAmount
exchangeRate = intentRecord.SendPrivatePaymentMetadata.ExchangeRate
quarks = intentRecord.SendPrivatePaymentMetadata.Quantity
destination = intentRecord.SendPrivatePaymentMetadata.DestinationTokenAccount
isMicroPayment = intentRecord.SendPrivatePaymentMetadata.IsMicroPayment
default:
return nil, errors.Errorf("%d intent type is not supported", intentRecord.IntentType)
}
if !isMicroPayment {
return nil, errors.New("intent is not a micro payment")
}
paymentRequestRecord, err := data.GetPaymentRequest(ctx, webhookRecord.WebhookId)
if err != nil {
return nil, errors.Wrap(err, "error getting payment request record")
}
// todo: Use a more efficient DB query or stuff fee metadata directly in the intent record
actionRecords, err := data.GetAllActionsByIntent(ctx, intentRecord.IntentId)
if err != nil {
return nil, errors.Wrap(err, "error getting action records")
}
var thirdPartyPaymentAction *action.Record
for _, actionRecord := range actionRecords {
if actionRecord.ActionType != action.NoPrivacyWithdraw {
continue
}
if *actionRecord.Destination == destination {
thirdPartyPaymentAction = actionRecord
break
}
}
if thirdPartyPaymentAction == nil {
return nil, errors.New("third party payment action not found")
}
var user *string
if paymentRequestRecord.Domain != nil && paymentRequestRecord.IsVerified {
relationshipAccountInfoRecord, err := data.GetRelationshipAccountInfoByOwnerAddress(ctx, intentRecord.InitiatorOwnerAccount, *paymentRequestRecord.Domain)
if err == nil {
user = &relationshipAccountInfoRecord.AuthorityAccount
} else if err != account.ErrAccountInfoNotFound {
return nil, errors.Wrap(err, "error querying for relationship account")
}
}
kvs := map[string]interface{}{
"intent": intentRecord.IntentId,
"currency": strings.ToUpper(string(currency)),
"amount": amount,
"exchangeRate": exchangeRate,
"quarks": quarks,
"fees": quarks - *thirdPartyPaymentAction.Quantity,
"destination": destination,
"state": "SUBMITTED",
}
if user != nil {
kvs["user"] = *user
}
return kvs, nil
}
func testJsonPayloadProvider(ctx context.Context, data code_data.Provider, webhookRecord *webhook.Record) (map[string]interface{}, error) {
if webhookRecord.Type != webhook.TypeTest {
return nil, errors.New("invalid webhook type")
}
return map[string]interface{}{
"string": "string_value",
"int": 42,
"float": 123.45,
"bool": true,
}, nil
}