-
Notifications
You must be signed in to change notification settings - Fork 0
/
model.go
311 lines (273 loc) · 8.85 KB
/
model.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
package yigim
import (
"crypto/md5"
"encoding/base64"
"fmt"
"net/http"
"strconv"
"strings"
)
// IEncodable type of model that can be encoded within query params
type IEncodable interface {
Encode(*http.Request, *Configuration)
}
// PaymentCreate includes the parameters to initialise the payment - link the card
type PaymentCreate struct {
//Unique reference number
Reference string `json:"reference"`
//Type of payment - SMS or DMS
Type string `json:"type"`
//Unique token to use for card linking
Token string `json:"token"`
//Save the card or not - y or n
Save string `json:"save"`
//Amount multiplied by 100, so 50.55 = 5055
Amount int `json:"amount"`
//Currency to charge in, default: 944
Currency string `json:"currency"`
//Current biller
Biller string `json:"biller"`
//Description for the payment
Description string `json:"description"`
//Template to use
Template string `json:"template"`
//Language code: az,en or ru
Language string `json:"language"`
//Callback url to call after successful card linking
Callback string `json:"callback"`
//Extra information
Extra map[string]string `json:"extra"`
}
// Make a base64-md5 signature
func generateSignature(value string) string {
md5Bytes := md5.Sum([]byte(value))
return base64.StdEncoding.EncodeToString(md5Bytes[:])
}
// Encode the payment create into the request
func (model *PaymentCreate) Encode(req *http.Request, appConfig *Configuration) {
query := req.URL.Query()
query.Add("reference", model.Reference)
query.Add("type", model.Type)
query.Add("token", model.Token)
query.Add("save", model.Save)
query.Add("amount", strconv.Itoa(model.Amount))
query.Add("currency", model.Currency)
query.Add("biller", model.Biller)
query.Add("description", model.Description)
query.Add("template", model.Template)
query.Add("language", model.Language)
query.Add("callback", model.Callback)
extra := ""
for key, value := range model.Extra {
extra += fmt.Sprintf("%s=%s;", key, value)
}
query.Add("extra", extra)
req.URL.RawQuery = query.Encode()
//Now encode
signature := generateSignature(strings.Join([]string{
model.Reference,
model.Type,
model.Token,
model.Save,
strconv.Itoa(model.Amount),
model.Currency,
model.Biller,
model.Description,
model.Template,
model.Language,
model.Callback,
extra,
appConfig.Secret,
}, ""))
req.Header.Add("X-Signature", signature)
}
// PaymentStatusCode represents a status code response from the server
type PaymentStatusCode string
//Different codes
const (
// //Newly created transaction, waiting for card data input
CodeS0 = PaymentStatusCode("S0")
//Pending DMS transaction (pre-authorized, call 'charge' or 'cancel')
CodeS1 = PaymentStatusCode("S1")
//Transaction is in progress
CodeS2 = PaymentStatusCode("S2")
//Unknown error
CodeS3 = PaymentStatusCode("S3")
//Reversed transaction (cancelled)
CodeS4 = PaymentStatusCode("S4")
//Refunded transaction
CodeS5 = PaymentStatusCode("S5")
//System malfunction
CodeS7 = PaymentStatusCode("S7")
//Approved
Code00 = PaymentStatusCode("00")
//Decline, refer to issuer
Code01 = PaymentStatusCode("01")
//Decline, expired card
Code02 = PaymentStatusCode("02")
//Decline, invalid amount
Code03 = PaymentStatusCode("03")
//Decline, inactive card
Code04 = PaymentStatusCode("04")
//Decline, insufficient funds
Code05 = PaymentStatusCode("05")
//Decline, suspected fraud
Code06 = PaymentStatusCode("06")
//Decline, exceeds withdrawal limit
Code07 = PaymentStatusCode("07")
//Format error
Code08 = PaymentStatusCode("08")
)
// ResponseCode response regarding the api code
type ResponseCode int
// Different payment codes
const (
ResponseCode0 = ResponseCode(0)
ResponseCode1 = ResponseCode(1)
ResponseCode2 = ResponseCode(2)
ResponseCode3 = ResponseCode(3)
ResponseCode4 = ResponseCode(4)
ResponseCode5 = ResponseCode(5)
ResponseCode6 = ResponseCode(6)
)
// SuccessCodes contains a list of results that considered successfull
var SuccessCodes = []ResponseCode{
ResponseCode0,
}
// PaymentCreateResult contains the result of payment create operation
type PaymentCreateResult struct {
URL string `json:"url"`
Code ResponseCode `json:"code"`
Message string `json:"message"`
}
// Secure3DStatus contains status of 3ds authorization
type Secure3DStatus string
// Different status codes
const (
Secure3D00 = Secure3DStatus("00")
Secure3D10 = Secure3DStatus("10")
Secure3D20 = Secure3DStatus("20")
Secure3D21 = Secure3DStatus("21")
Secure3D22 = Secure3DStatus("22")
Secure3D23 = Secure3DStatus("23")
Secure3D24 = Secure3DStatus("24")
Secure3D25 = Secure3DStatus("25")
Secure3D30 = Secure3DStatus("30")
)
// PaymentStatus is used to retrieve status for a transaction
type PaymentStatus struct {
//Unique reference number
Reference string `json:"reference"`
}
// Encode the payment status into the request
func (model *PaymentStatus) Encode(req *http.Request, appConfig *Configuration) {
query := req.URL.Query()
query.Add("reference", model.Reference)
req.URL.RawQuery = query.Encode()
//Now encode
signature := generateSignature(strings.Join([]string{
model.Reference,
appConfig.Secret,
}, ""))
req.Header.Add("X-Signature", signature)
}
// PaymentStatusResult contains the result of the payment
type PaymentStatusResult struct {
Reference string `json:"reference"`
Datetime string `json:"datetime"`
Type string `json:"type"`
Token string `json:"token"`
Pan *string `json:"pan"`
Expiry *string `json:"expiry"`
Amount float64 `json:"amount"`
Currency string `json:"currency"`
Biller string `json:"biller"`
System string `json:"system"`
Issuer *string `json:"issuer"`
Rrn string `json:"rrn"`
Secure3DStatus *Secure3DStatus `json:"3ds" bson:"3ds"`
Approval string `json:"approval"`
Status PaymentStatusCode `json:"status"`
Code ResponseCode `json:"code"`
Message string `json:"message"`
Extra []struct {
Name string `json:"name"`
Value string `json:"value"`
} `json:"extra"`
}
// PaymentRefund refunfs the previous locked amount for card verification
type PaymentRefund struct {
Reference string `json:"reference"`
}
// Encode the payment refund into the request
func (model *PaymentRefund) Encode(req *http.Request, appConfig *Configuration) {
query := req.URL.Query()
query.Add("reference", model.Reference)
req.URL.RawQuery = query.Encode()
//Now encode
signature := generateSignature(strings.Join([]string{
model.Reference,
appConfig.Secret,
}, ""))
req.Header.Add("X-Signature", signature)
}
// PaymentRefundResult contains the result of payment refund
type PaymentRefundResult struct {
Code ResponseCode `json:"code"`
Message string `json:"message"`
}
// PaymentExecute stores data to execute a payment using a token
type PaymentExecute struct {
//Unique payment (order) ID for future usage
Reference string `json:"reference"`
//SMS - Single (default), DMS - Dual Message System
Type string `json:"type"`
//Card unique token (optional)
Token string `json:"token"`
//Amount multiplied by 100, so 50.55 = 5055
Amount int `json:"amount"`
//Numeric ISO4712 currency code
Currency string `json:"currency"`
//Current biller
Biller string `json:"biller"`
}
// Encode the payment status into the request
func (model *PaymentExecute) Encode(req *http.Request, appConfig *Configuration) {
query := req.URL.Query()
query.Add("reference", model.Reference)
query.Add("type", model.Type)
query.Add("token", model.Token)
query.Add("amount", strconv.Itoa(model.Amount))
query.Add("currency", model.Currency)
query.Add("biller", model.Biller)
req.URL.RawQuery = query.Encode()
//Now encode
signature := generateSignature(strings.Join([]string{
model.Reference,
model.Type,
model.Token,
strconv.Itoa(model.Amount),
model.Currency,
model.Biller,
appConfig.Secret,
}, ""))
req.Header.Add("X-Signature", signature)
}
// PaymentExecuteResult contains the result of payment execute action
type PaymentExecuteResult struct {
Reference string `json:"reference"`
Datetime string `json:"datetime"`
Type string `json:"type"`
Pan *string `json:"pan"`
Amount float64 `json:"amount"`
Currency string `json:"currency"`
Biller string `json:"biller"`
System string `json:"system"`
Issuer *string `json:"issuer"`
Rrn string `json:"rrn"`
Secure3DStatus *Secure3DStatus `json:"3ds" bson:"3ds"`
Approval string `json:"approval"`
Status PaymentStatusCode `json:"status"`
Code ResponseCode `json:"code"`
Message string `json:"message"`
}