disbursement_service.go   A
last analyzed

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 87
dl 0
loc 152
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A mtnmomo.*disbursementsService.Token 0 19 4
B mtnmomo.*disbursementsService.Transfer 0 26 5
A mtnmomo.*disbursementsService.tokenIsValid 0 2 1
A mtnmomo.*disbursementsService.refreshToken 0 17 3
B mtnmomo.*disbursementsService.GetTransferStatus 0 29 5
A mtnmomo.*disbursementsService.GetAccountBalance 0 25 5
1
package mtnmomo
2
3
import (
4
	"context"
5
	"encoding/json"
6
	"net/http"
7
	"time"
8
)
9
10
// disbursementService is the API client for the `/disbursement` endpoint
11
type disbursementsService 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/disbursement/operations/CreateAccessToken
16
func (service *disbursementsService) Token(ctx context.Context) (*AuthToken, *Response, error) {
17
	request, err := service.client.newRequest(ctx, http.MethodPost, "/disbursement/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, response, 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
// Transfer is used to transfer an amount from the owner account to a payee account.
38
//
39
// API Docs: https://momodeveloper.mtn.com/docs/services/disbursement/operations/Transfer?
40
func (service *disbursementsService) Transfer(
41
	ctx context.Context,
42
	referenceID string,
43
	params *TransferParams,
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, "/disbursement/v1_0/transfer", 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.addAccessToken(request)
63
64
	response, err := service.client.do(request)
65
	return response, err
66
}
67
68
// GetTransferStatus is used to get the status of a transfer.
69
//
70
// API Docs: https://momodeveloper.mtn.com/docs/services/disbursement/operations/GetTransferStatus
71
func (service *disbursementsService) GetTransferStatus(
72
	ctx context.Context,
73
	referenceID string,
74
) (*DisbursementTransactionStatus, *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, "/disbursement/v1_0/transfer/"+referenceID, nil)
81
	if err != nil {
82
		return nil, nil, err
83
	}
84
85
	service.client.addTargetEnvironment(request)
86
	service.client.addAccessToken(request)
87
88
	response, err := service.client.do(request)
89
	if err != nil {
90
		return nil, response, err
91
	}
92
93
	status := new(DisbursementTransactionStatus)
94
	if err = json.Unmarshal(*response.Body, status); err != nil {
95
		return nil, response, err
96
	}
97
98
	status.ReferenceID = referenceID
99
	return status, response, err
100
}
101
102
// GetAccountBalance returns the balance of the account.
103
//
104
// API Docs: https://momodeveloper.mtn.com/docs/services/disbursement/operations/GetAccountBalance
105
func (service *disbursementsService) GetAccountBalance(ctx context.Context) (*AccountBalance, *Response, error) {
106
	err := service.refreshToken(ctx)
107
	if err != nil {
108
		return nil, nil, err
109
	}
110
111
	request, err := service.client.newRequest(ctx, http.MethodGet, "/disbursement/v1_0/account/balance", nil)
112
	if err != nil {
113
		return nil, nil, err
114
	}
115
116
	service.client.addAccessToken(request)
117
	service.client.addTargetEnvironment(request)
118
119
	response, err := service.client.do(request)
120
	if err != nil {
121
		return nil, response, err
122
	}
123
124
	balance := new(AccountBalance)
125
	if err = json.Unmarshal(*response.Body, balance); err != nil {
126
		return nil, response, err
127
	}
128
129
	return balance, response, err
130
}
131
132
func (service *disbursementsService) tokenIsValid() bool {
133
	return time.Now().UTC().Unix() < service.client.accessTokenExpiresAt
134
}
135
136
func (service *disbursementsService) refreshToken(ctx context.Context) error {
137
	service.client.accessTokenLock.Lock()
138
	defer service.client.accessTokenLock.Unlock()
139
140
	if service.tokenIsValid() {
141
		return nil
142
	}
143
144
	token, _, err := service.Token(ctx)
145
	if err != nil {
146
		return err
147
	}
148
149
	service.client.accessToken = token.AccessToken
150
	service.client.accessTokenExpiresAt = time.Now().UTC().Unix() + token.ExpiresIn - 100
151
152
	return nil
153
}
154