/
viseca.go
138 lines (111 loc) · 3.36 KB
/
viseca.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package viseca
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
"time"
)
const (
defaultBaseURL = "https://api.one.viseca.ch/v1/"
)
// Client represents an API client.
type Client struct {
HTTPClient *http.Client
BaseURL *url.URL
}
// NewClient returns a new Viseca API client.
func NewClient(httpClient *http.Client) *Client {
if httpClient == nil {
httpClient = &http.Client{}
}
baseURL, _ := url.Parse(defaultBaseURL)
client := &Client{HTTPClient: httpClient, BaseURL: baseURL}
return client
}
const listOptionsDateFormat = "2006-01-02T15:04:05Z"
// ListOptions holds the options for list actions.
type ListOptions struct {
Offset int
PageSize int
StateType string
DateTo time.Time
DateFrom time.Time
}
// NewDefaultListOptions creates new default ListOptions.
func NewDefaultListOptions() ListOptions {
listOptions := ListOptions{}
listOptions.Offset = 0
listOptions.PageSize = 100
listOptions.StateType = "unknown"
return listOptions
}
func addListOptions(url *url.URL, listOptions ListOptions) {
query := url.Query()
query.Add("offset", strconv.Itoa(listOptions.Offset))
query.Add("pagesize", strconv.Itoa(listOptions.PageSize))
query.Add("statetype", listOptions.StateType)
if !listOptions.DateFrom.IsZero() {
query.Add("dateFrom", listOptions.DateFrom.Format(listOptionsDateFormat))
}
if !listOptions.DateTo.IsZero() {
query.Add("dateTo", listOptions.DateTo.Format(listOptionsDateFormat))
}
url.RawQuery = query.Encode()
}
// CardListOptions known CreditIndicators are "credit" and "debit".
type CardListOptions struct {
CreditIndicators []string
}
// NewDefaultCardListOptions creates new default CardListOptions.
func NewDefaultCardListOptions() CardListOptions {
cardListOptions := CardListOptions{}
cardListOptions.CreditIndicators = []string{"credit", "debit"}
return cardListOptions
}
func addCardListOptions(url *url.URL, cardListOptions CardListOptions) {
query := url.Query()
for _, creditIndicator := range cardListOptions.CreditIndicators {
query.Add("creditIndicators", creditIndicator)
}
url.RawQuery = query.Encode()
}
// Do returns the HTTP response and decodes the JSON response body into responseBody.
func (client *Client) Do(ctx context.Context, request *http.Request, responseBody interface{}) (*http.Response, error) {
request = request.WithContext(ctx)
response, err := client.HTTPClient.Do(request)
if err != nil {
return response, err
}
defer response.Body.Close()
if response.StatusCode >= 200 && response.StatusCode < 300 {
if responseBody != nil {
err = json.NewDecoder(response.Body).Decode(responseBody)
}
} else {
err = fmt.Errorf("api call failed with status: %s", response.Status)
}
return response, err
}
// NewRequest returns a new request with the given path (adds the base URL) and method. It further encodes the requestBody as JSON.
func (client *Client) NewRequest(path string, method string, requestBody interface{}) (*http.Request, error) {
requestURL := client.BaseURL.JoinPath(path)
var buffer io.ReadWriter
if requestBody != nil {
buffer := &bytes.Buffer{}
err := json.NewEncoder(buffer).Encode(requestBody)
if err != nil {
return nil, err
}
}
request, err := http.NewRequest(method, requestURL.String(), buffer)
if err != nil {
return nil, err
}
request.Header.Add("Accept", "application/json")
return request, err
}