Passed
Push — main ( 50455e...dee0b0 )
by Acho
01:58
created

client.go   A

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 83
dl 0
loc 135
rs 10
c 0
b 0
f 0
1
package afrikpay
2
3
import (
4
	"bytes"
5
	"context"
6
	"encoding/base64"
7
	"encoding/json"
8
	"fmt"
9
	"io"
10
	"io/ioutil"
11
	"net/http"
12
)
13
14
type service struct {
15
	client *Client
16
}
17
18
// Client is the afrikpay API client.
19
// Exec not instantiate this client with Client{}. Use the New method instead.
20
type Client struct {
21
	httpClient          *http.Client
22
	common              service
23
	baseURL             string
24
	apiKey              string
25
	authorizationHeader string
26
	walletPin           string
27
28
	ENEOPrepaid *eneoPrepaidService
29
}
30
31
// New creates and returns a new *Client from a slice of Option.
32
func New(options ...Option) *Client {
33
	config := defaultClientConfig()
34
35
	for _, option := range options {
36
		option.apply(config)
37
	}
38
39
	client := &Client{
40
		httpClient:          config.httpClient,
41
		baseURL:             config.baseURL,
42
		apiKey:              config.apiKey,
43
		authorizationHeader: base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", config.walletUsername, config.walletPassword))),
44
		walletPin:           config.walletPin,
45
	}
46
47
	client.common.client = client
48
	client.ENEOPrepaid = &eneoPrepaidService{
49
		paymentService: &paymentService[ENEOPrepaidPaymentRequest, ENEOPrepaidPaymentResponse]{
50
			service: &client.common,
51
			slug:    "eneo-prepaid-bill-service-feature",
52
		},
53
	}
54
55
	return client
56
}
57
58
// newRequest creates an API request.
59
// A relative URL must be provided in uri in which case it is resolved relative to the BaseURL of the Client.
60
// URI's should always be specified with a preceding slash.
61
func (client *Client) newRequest(ctx context.Context, method, uri string, body any) (*http.Request, error) {
62
	var buf io.ReadWriter
63
	if body != nil {
64
		buf = &bytes.Buffer{}
65
		enc := json.NewEncoder(buf)
66
		enc.SetEscapeHTML(false)
67
		err := enc.Encode(body)
68
		if err != nil {
69
			return nil, err
70
		}
71
	}
72
73
	req, err := http.NewRequestWithContext(ctx, method, client.baseURL+uri, buf)
74
	if err != nil {
75
		return nil, err
76
	}
77
78
	req.Header.Set("Content-Type", "application/json")
79
	req.Header.Set("Accept", "application/json")
80
	req.Header.Set("ApiKey", client.apiKey)
81
	req.Header.Set("X-Authorization", client.authorizationHeader)
82
83
	return req, nil
84
}
85
86
// do carries out an HTTP request and returns a Response
87
func (client *Client) do(request *http.Request) (*Response, error) {
88
	httpResponse, err := client.httpClient.Do(request)
89
	if err != nil {
90
		return nil, err
91
	}
92
93
	defer func() { _ = httpResponse.Body.Close() }()
94
95
	resp, err := client.newResponse(httpResponse)
96
	if err != nil {
97
		return resp, err
98
	}
99
100
	_, err = io.Copy(io.Discard, httpResponse.Body)
101
	if err != nil {
102
		return resp, err
103
	}
104
105
	return resp, nil
106
}
107
108
// newResponse converts an *http.Response to *Response
109
func (client *Client) newResponse(httpResponse *http.Response) (*Response, error) {
110
	if httpResponse == nil {
111
		return nil, fmt.Errorf("%T cannot be nil", httpResponse)
112
	}
113
114
	resp := new(Response)
115
	resp.HTTPResponse = httpResponse
116
117
	buf, err := ioutil.ReadAll(resp.HTTPResponse.Body)
118
	if err != nil {
119
		return nil, err
120
	}
121
	resp.Body = &buf
122
123
	return resp, resp.Error()
124
}
125