-
Notifications
You must be signed in to change notification settings - Fork 0
/
general.go
101 lines (86 loc) · 3.02 KB
/
general.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
package gomonnify
import (
"crypto/sha512"
"fmt"
"net/http"
"strings"
)
// VerifyTransaction validates that the payload received is actually from monnify. It computes the transaction hash and compares.
// twoStep if set to true will make a request to monnify to confirm that the transaction exists and was successful
// we cannot implement 3 step verification without some knowledge of your persistence layer. Need it? Open an Issue/PR :)
// Docs: https://docs.teamapt.com/pages/viewpage.action?pageId=13828139
func (g *general) VerifyTransaction(payload *GeneralTransaction, twoStep bool) bool {
rawStr := fmt.Sprintf("%v|%v|%v|%v|%v", g.Config.SecretKey, payload.PaymentReference, payload.AmountPaid, payload.PaidOn, payload.TransactionReference)
h := sha512.New()
h.Write([]byte(rawStr))
hashed := fmt.Sprintf("%x", h.Sum(nil))
if hashed != payload.TransactionHash {
return false
}
if twoStep {
t, err := g.GetTransaction(payload.TransactionReference)
if err != nil {
return false
}
if t.ResponseBody.PaymentStatus == PaymentStatusPaid {
return true
}
return false
}
return true
}
// GetTransaction retrieves the transaction specified by reference from the Monnify API.
// Docs: https://docs.teamapt.com/display/MON/Get+Transaction+Status
func (g *general) GetTransaction(reference string) (*GeneralTransactionResponse, error) {
url := fmt.Sprintf("%v/v2/transactions/%v", g.APIBaseUrl, reference)
rawResponse, statusCode, err := g.getRequest(url, requestAuthTypeBearer)
if err != nil {
fmt.Println(err)
return nil, err
}
result := GeneralTransactionResponse{}
err = g.unmarshallJson(strings.NewReader(rawResponse), &result)
if err != nil {
return nil, err
}
if statusCode != http.StatusOK {
return nil, failedRequestMessage(statusCode, result.ResponseCode, result.ResponseMessage)
}
return &result, nil
}
// GetBanks fetches a list of banks and their USSD codes from the monnify api.
// Docs: https://docs.teamapt.com/display/MON/Get+Banks
func (g *general) GetBanks() (*BanksResponse, error) {
url := fmt.Sprintf("%v/v1/banks", g.APIBaseUrl)
rawResponse, statusCode, err := g.getRequest(url, requestAuthTypeBearer)
if err != nil {
return nil, err
}
result := BanksResponse{}
err = g.unmarshallJson(strings.NewReader(rawResponse), &result)
if err != nil {
return nil, err
}
if statusCode != http.StatusOK {
return nil, failedRequestMessage(statusCode, result.ResponseCode, result.ResponseMessage)
}
return &result, nil
}
// GetBanksUseCache checks if the bank list is already in the struct
// and simply reuses that instead of making a HTTP call. If the list is not already in the struct, it fetches and saves
// a copy to the struct for future use.
func (g *general) GetBanksUseCache() (*BanksResponse, error) {
if g.banks != nil {
return g.banks, nil
}
b, err := g.GetBanks()
if err != nil {
return nil, err
}
g.banks = b
return b, nil
}
// InvalidateBankCache empties the cache from the struct so the next call will make an API Call
func (g *general) InvalidateBankCache() {
g.banks = nil
}