Test Setup Failed
Push — main ( 9ac765...66eca5 )
by Acho
01:51
created

mtnmomo.*collectionService.GetAccountBalance   A

Complexity

Conditions 5

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nop 1
dl 0
loc 25
rs 9.1333
c 0
b 0
f 0
1
package mtnmomo
2
3
import (
4
	"context"
5
	"encoding/json"
6
	"net/http"
7
	"time"
8
)
9
10
// collectionService is the API client for the `/collection` endpoint
11
type collectionService service
12
13
// Token is used to create an access token which can then be used to authorize and authenticate towards the other end-points of the API.
14
//
15
// API Docs: https://momodeveloper.mtn.com/docs/services/collection/operations/token-POST
16
func (service *collectionService) Token(ctx context.Context) (*AuthToken, *Response, error) {
17
	request, err := service.client.newRequest(ctx, http.MethodPost, "/collection/token/", nil)
18
	if err != nil {
19
		return nil, nil, err
20
	}
21
22
	service.client.addBasicAuth(request)
23
24
	response, err := service.client.do(request)
25
	if err != nil {
26
		return nil, nil, err
27
	}
28
29
	authToken := new(AuthToken)
30
	if err = json.Unmarshal(*response.Body, authToken); err != nil {
31
		return nil, response, err
32
	}
33
34
	return authToken, response, err
35
}
36
37
// RequestToPay is used to request a payment from a consumer (Payer).
38
//
39
// API Docs: https://momodeveloper.mtn.com/docs/services/collection/operations/requesttopay-POST
40
func (service *collectionService) RequestToPay(
41
	ctx context.Context,
42
	referenceID string,
43
	params *RequestToPayParams,
44
	callbackURL *string,
45
) (*Response, error) {
46
	err := service.refreshToken(ctx)
47
	if err != nil {
48
		return nil, err
49
	}
50
51
	request, err := service.client.newRequest(ctx, http.MethodPost, "/collection/v1_0/requesttopay", params)
52
	if err != nil {
53
		return nil, err
54
	}
55
56
	if callbackURL != nil && len(*callbackURL) != 0 {
57
		service.client.addCallbackURL(request, *callbackURL)
58
	}
59
60
	service.client.addTargetEnvironment(request)
61
	service.client.addReferenceID(request, referenceID)
62
	service.client.addCollectionAccessToken(request)
63
64
	response, err := service.client.do(request)
65
	return response, err
66
}
67
68
// GetRequestToPayStatus is used to get the status of a request to pay.
69
//
70
// API Docs: https://momodeveloper.mtn.com/docs/services/collection/operations/requesttopay-referenceId-GET
71
func (service *collectionService) GetRequestToPayStatus(
72
	ctx context.Context,
73
	referenceID string,
74
) (*RequestToPayStatus, *Response, error) {
75
	err := service.refreshToken(ctx)
76
	if err != nil {
77
		return nil, nil, err
78
	}
79
80
	request, err := service.client.newRequest(ctx, http.MethodGet, "/collection/v1_0/requesttopay/"+referenceID, nil)
81
	if err != nil {
82
		return nil, nil, err
83
	}
84
85
	service.client.addTargetEnvironment(request)
86
	service.client.addCollectionAccessToken(request)
87
88
	response, err := service.client.do(request)
89
	if err != nil {
90
		return nil, nil, err
91
	}
92
93
	status := new(RequestToPayStatus)
94
	if err = json.Unmarshal(*response.Body, status); err != nil {
95
		return nil, response, err
96
	}
97
98
	return status, response, err
99
}
100
101
// GetAccountBalance returns the balance of the account.
102
//
103
// API Docs: https://momodeveloper.mtn.com/docs/services/collection/operations/get-v1_0-account-balance?
104
func (service *collectionService) GetAccountBalance(ctx context.Context) (*AccountBalance, *Response, error) {
105
	err := service.refreshToken(ctx)
106
	if err != nil {
107
		return nil, nil, err
108
	}
109
110
	request, err := service.client.newRequest(ctx, http.MethodGet, "/collection/v1_0/account/balance", nil)
111
	if err != nil {
112
		return nil, nil, err
113
	}
114
115
	service.client.addCollectionAccessToken(request)
116
	service.client.addTargetEnvironment(request)
117
118
	response, err := service.client.do(request)
119
	if err != nil {
120
		return nil, nil, err
121
	}
122
123
	balance := new(AccountBalance)
124
	if err = json.Unmarshal(*response.Body, balance); err != nil {
125
		return nil, response, err
126
	}
127
128
	return balance, response, err
129
}
130
131
func (service *collectionService) tokenIsValid() bool {
132
	return time.Now().UTC().Unix() < service.client.collectionAccessTokenExpiresAt
133
}
134
135
func (service *collectionService) refreshToken(ctx context.Context) error {
136
	service.client.collectionLock.Lock()
137
	defer service.client.collectionLock.Unlock()
138
139
	if service.tokenIsValid() {
140
		return nil
141
	}
142
143
	token, _, err := service.Token(ctx)
144
	if err != nil {
145
		return err
146
	}
147
148
	service.client.collectionAccessToken = token.AccessToken
149
	service.client.collectionAccessTokenExpiresAt = time.Now().UTC().Unix() + token.ExpiresIn - 100
150
151
	return nil
152
}
153