From 0c43d5d337b49a560b435d35ee619b98e9e500b1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Jun 2018 16:21:59 +0700 Subject: [PATCH 01/18] Add Bank unit test Add bank_test just like the others constant --- bank_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 bank_test.go diff --git a/bank_test.go b/bank_test.go new file mode 100644 index 0000000..426a54c --- /dev/null +++ b/bank_test.go @@ -0,0 +1,19 @@ +package midtrans_test + +import ( + "testing" + + "github.com/cheekybits/is" + midtrans "github.com/veritrans/go-midtrans" +) + +func TestBank(t *testing.T) { + is := is.New(t) + is.Equal("bni", midtrans.BankBni) + is.Equal("mandiri", midtrans.BankMandiri) + is.Equal("cimb", midtrans.BankCimb) + is.Equal("bca", midtrans.BankBca) + is.Equal("bri", midtrans.BankBri) + is.Equal("maybank", midtrans.BankMaybank) + is.Equal("permata", midtrans.BankPermata) +} From 535198e574f743d64b6124dcca681a61928cb802 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 2 Jul 2018 13:25:19 +0700 Subject: [PATCH 02/18] Change Snap Example to Core Example Change snap_index link to index.html so the examples are linked --- example/simplepay/templates/snap_index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/simplepay/templates/snap_index.html b/example/simplepay/templates/snap_index.html index e0fb163..3555541 100644 --- a/example/simplepay/templates/snap_index.html +++ b/example/simplepay/templates/snap_index.html @@ -23,7 +23,7 @@
- via SNAP + via CORE Checkout
From ce91e1ed0247018469d487491a13cdf3ef46f0de Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 2 Jul 2018 13:26:49 +0700 Subject: [PATCH 03/18] Change URL to Midtrans and reformat struct --- example/simplepay/template_handler.go | 40 +++++++++++++------------- example/simplepay/templates/index.html | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/example/simplepay/template_handler.go b/example/simplepay/template_handler.go index b864ede..1fadfcc 100644 --- a/example/simplepay/template_handler.go +++ b/example/simplepay/template_handler.go @@ -1,32 +1,32 @@ package main import ( - "sync" - "html/template" - "net/http" - "path/filepath" + "html/template" + "net/http" + "path/filepath" + "sync" ) type templateHandler struct { - once sync.Once - filename string - templ *template.Template - data map[string]interface{} - dataInitializer func(t *templateHandler) + once sync.Once + filename string + templ *template.Template + data map[string]interface{} + dataInitializer func(t *templateHandler) } func (t *templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - t.once.Do(func() { - t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename))) - }) + t.once.Do(func() { + t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename))) + }) - if t.dataInitializer != nil { - t.dataInitializer(t) - } else { - t.data = make(map[string]interface{}) - } + if t.dataInitializer != nil { + t.dataInitializer(t) + } else { + t.data = make(map[string]interface{}) + } - t.data["Host"] = r.Host + t.data["Host"] = r.Host - t.templ.Execute(w, t.data) -} \ No newline at end of file + t.templ.Execute(w, t.data) +} diff --git a/example/simplepay/templates/index.html b/example/simplepay/templates/index.html index f23582d..fb7f90d 100644 --- a/example/simplepay/templates/index.html +++ b/example/simplepay/templates/index.html @@ -53,7 +53,7 @@ @@ -44,7 +44,7 @@
- via SNAP + SNAP Example Checkout
diff --git a/example/simplepay/templates/snap_index.html b/example/simplepay/templates/snap_index.html index 25baab1..8049e46 100644 --- a/example/simplepay/templates/snap_index.html +++ b/example/simplepay/templates/snap_index.html @@ -1,7 +1,7 @@ - Simplepay + Simplepay - SNAP @@ -23,7 +23,7 @@ From 3ee5b7562e9d8d23ec5688622fe5f7b98445702b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Jul 2018 17:10:45 +0700 Subject: [PATCH 07/18] Clean warning from golint, go_vet, gofmt and misspell --- README.md | 2 + bank.go | 22 ++++-- client.go | 194 +++++++++++++++++++++++++++------------------------ core.go | 165 ++++++++++++++++++++++++------------------- envtype.go | 8 ++- paysource.go | 115 +++++++++++++++++++----------- request.go | 30 ++++++-- response.go | 5 +- snap.go | 61 ++++++++-------- 9 files changed, 356 insertions(+), 246 deletions(-) diff --git a/README.md b/README.md index ff84d5b..f27f062 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Go Report Card](https://goreportcard.com/badge/github.com/veritrans/go-midtrans)](https://goreportcard.com/report/github.com/veritrans/go-midtrans) + # Midtrans Library for Go(lang) Midtrans :heart: Go ! diff --git a/bank.go b/bank.go index 4322523..fc478be 100644 --- a/bank.go +++ b/bank.go @@ -1,13 +1,27 @@ package midtrans +// Bank value type Bank string const ( - BankBni Bank = "bni" + //BankBni : bni + BankBni Bank = "bni" + + //BankMandiri : mandiri BankMandiri Bank = "mandiri" - BankCimb Bank = "cimb" - BankBca Bank = "bca" - BankBri Bank = "bri" + + //BankCimb : cimb + BankCimb Bank = "cimb" + + //BankBca : bca + BankBca Bank = "bca" + + //BankBri : bri + BankBri Bank = "bri" + + //BankMaybank : maybank BankMaybank Bank = "maybank" + + //BankPermata : permata BankPermata Bank = "permata" ) diff --git a/client.go b/client.go index e3c5905..959e1d0 100644 --- a/client.go +++ b/client.go @@ -1,119 +1,129 @@ package midtrans import ( - "log" - "os" - "net/http" - "time" - "io" - "io/ioutil" - "encoding/json" + "encoding/json" + "io" + "io/ioutil" + "log" + "net/http" + "os" + "time" ) +// Client struct type Client struct { - ApiEnvType EnvironmentType - ClientKey string - ServerKey string + APIEnvType EnvironmentType + ClientKey string + ServerKey string - LogLevel int - Logger *log.Logger + LogLevel int + Logger *log.Logger } -// this function will always be called when the library is in use +// NewClient : this function will always be called when the library is in use func NewClient() Client { - return Client{ - ApiEnvType: Sandbox, - - // LogLevel is the logging level used by the Midtrans library - // 0: No logging - // 1: Errors only - // 2: Errors + informational (default) - // 3: Errors + informational + debug - LogLevel: 2, - Logger: log.New(os.Stderr, "", log.LstdFlags), - } + return Client{ + APIEnvType: Sandbox, + + // LogLevel is the logging level used by the Midtrans library + // 0: No logging + // 1: Errors only + // 2: Errors + informational (default) + // 3: Errors + informational + debug + LogLevel: 2, + Logger: log.New(os.Stderr, "", log.LstdFlags), + } } // ===================== HTTP CLIENT ================================================ -var defHttpTimeout = 80 * time.Second -var httpClient = &http.Client{Timeout: defHttpTimeout} +var defHTTPTimeout = 80 * time.Second +var httpClient = &http.Client{Timeout: defHTTPTimeout} +// NewRequest : send new request func (c *Client) NewRequest(method string, fullPath string, body io.Reader) (*http.Request, error) { - logLevel := c.LogLevel - logger := c.Logger - - req, err := http.NewRequest(method, fullPath, body) - if err != nil { - if logLevel > 0 { - logger.Println("Request creation failed: ", err) - } - return nil, err - } - - req.Header.Add("Content-Type", "application/json") - req.Header.Add("Accept", "application/json") - req.SetBasicAuth(c.ServerKey, "") - - return req, nil + logLevel := c.LogLevel + logger := c.Logger + + req, err := http.NewRequest(method, fullPath, body) + if err != nil { + if logLevel > 0 { + logger.Println("Request creation failed: ", err) + } + return nil, err + } + + req.Header.Add("Content-Type", "application/json") + req.Header.Add("Accept", "application/json") + req.SetBasicAuth(c.ServerKey, "") + + return req, nil } +// ExecuteRequest : execute request func (c *Client) ExecuteRequest(req *http.Request, v interface{}) error { - logLevel := c.LogLevel - logger := c.Logger - - if logLevel > 1 { - logger.Println("Request ", req.Method, ": ", req.URL.Host, req.URL.Path) - } - - start := time.Now() - - res, err := httpClient.Do(req) - defer res.Body.Close() - - if logLevel > 2 { - logger.Println("Completed in ", time.Since(start)) - } - - if err != nil { - if logLevel > 0 { - logger.Println("Request failed: ", err) - } - return err - } - - resBody, err := ioutil.ReadAll(res.Body) - if err != nil { - if logLevel > 0 { - logger.Println("Cannot read response body: ", err) - } - return err - } - - if logLevel > 2 { - logger.Println("Midtrans response: ", resBody) - } - - if v != nil { - return json.Unmarshal(resBody, v) - } - - return nil + logLevel := c.LogLevel + logger := c.Logger + + if logLevel > 1 { + logger.Println("Request ", req.Method, ": ", req.URL.Host, req.URL.Path) + } + + start := time.Now() + + res, err := httpClient.Do(req) + if err != nil { + if logLevel > 0 { + logger.Println("Cannot send request: ", err) + } + return err + } + defer res.Body.Close() + + if logLevel > 2 { + logger.Println("Completed in ", time.Since(start)) + } + + if err != nil { + if logLevel > 0 { + logger.Println("Request failed: ", err) + } + return err + } + + resBody, err := ioutil.ReadAll(res.Body) + if err != nil { + if logLevel > 0 { + logger.Println("Cannot read response body: ", err) + } + return err + } + + if logLevel > 2 { + logger.Println("Midtrans response: ", resBody) + } + + if v != nil { + return json.Unmarshal(resBody, v) + } + + return nil } // Call the Midtrans API at specific `path` using the specified HTTP `method`. The result will be -// given to `v` if there is no error. If any error occured, the return of this function is the error +// given to `v` if there is no error. If any error occurred, the return of this function is the error // itself, otherwise nil. func (c *Client) Call(method, path string, body io.Reader, v interface{}) error { - req, err := c.NewRequest(method, path, body) + req, err := c.NewRequest(method, path, body) - if err != nil { - return err - } + if err != nil { + return err + } - if err := c.ExecuteRequest(req, v); err != nil { - return err - } + if err := c.ExecuteRequest(req, v); err != nil { + return err + } - return nil + return nil } -// ===================== END HTTP CLIENT ================================================ \ No newline at end of file + +// ===================== END HTTP CLIENT ================================================ diff --git a/core.go b/core.go index 5a282cd..8839795 100644 --- a/core.go +++ b/core.go @@ -1,114 +1,133 @@ package midtrans import ( - "encoding/json" - "bytes" - "io" - "strings" + "bytes" + "encoding/json" + "io" + "strings" ) +// CoreGateway struct type CoreGateway struct { - Client Client + Client Client } -func (c *CoreGateway) Call(method, path string, body io.Reader, v interface{}) error { - if !strings.HasPrefix(path, "/") { - path = "/" + path - } +// Call : base method to call Core API +func (gateway *CoreGateway) Call(method, path string, body io.Reader, v interface{}) error { + if !strings.HasPrefix(path, "/") { + path = "/" + path + } - path = c.Client.ApiEnvType.String() + path - return c.Client.Call(method, path, body, v) + path = gateway.Client.APIEnvType.String() + path + return gateway.Client.Call(method, path, body, v) } -func (g *CoreGateway) Charge(req *ChargeReq) (Response, error) { - resp := Response{} - jsonReq, _ := json.Marshal(req) +// Charge : Perform transaction using ChargeReq +func (gateway *CoreGateway) Charge(req *ChargeReq) (Response, error) { + resp := Response{} + jsonReq, _ := json.Marshal(req) - err := g.Call("POST", "v2/charge", bytes.NewBuffer(jsonReq), &resp) - if err != nil { - g.Client.Logger.Println("Error charging: ", err) - return resp, err - } + err := gateway.Call("POST", "v2/charge", bytes.NewBuffer(jsonReq), &resp) + if err != nil { + gateway.Client.Logger.Println("Error charging: ", err) + return resp, err + } - if resp.StatusMessage != "" { - g.Client.Logger.Println(resp.StatusMessage) - } + if resp.StatusMessage != "" { + gateway.Client.Logger.Println(resp.StatusMessage) + } - return resp, nil + return resp, nil } -func (g *CoreGateway) PreauthCard(req *ChargeReq) (Response, error) { - req.CreditCard.Type = "authorize" - return g.Charge(req) +// PreauthCard : Perform authorized transactions using ChargeReq +func (gateway *CoreGateway) PreauthCard(req *ChargeReq) (Response, error) { + req.CreditCard.Type = "authorize" + return gateway.Charge(req) } -func (g *CoreGateway) CaptureCard(req *CaptureReq) (Response, error) { - resp := Response{} - jsonReq, _ := json.Marshal(req) +// CaptureCard : Capture an authorized transaction for card payment +func (gateway *CoreGateway) CaptureCard(req *CaptureReq) (Response, error) { + resp := Response{} + jsonReq, _ := json.Marshal(req) - err := g.Call("POST", "v2/capture", bytes.NewBuffer(jsonReq), &resp) - if err != nil { - g.Client.Logger.Println("Error capturing: ", err) - return resp, err - } + err := gateway.Call("POST", "v2/capture", bytes.NewBuffer(jsonReq), &resp) + if err != nil { + gateway.Client.Logger.Println("Error capturing: ", err) + return resp, err + } - if resp.StatusMessage != "" { g.Client.Logger.Println(resp.StatusMessage) } + if resp.StatusMessage != "" { + gateway.Client.Logger.Println(resp.StatusMessage) + } - return resp, nil + return resp, nil } -func (g *CoreGateway) Approve(orderId string) (Response, error) { - resp := Response{} +// Approve : Approve order using order ID +func (gateway *CoreGateway) Approve(orderID string) (Response, error) { + resp := Response{} - err := g.Call("POST", "v2/" + orderId + "/approve", nil, &resp) - if err != nil { - g.Client.Logger.Println("Error approving: ", err) - return resp, err - } + err := gateway.Call("POST", "v2/"+orderID+"/approve", nil, &resp) + if err != nil { + gateway.Client.Logger.Println("Error approving: ", err) + return resp, err + } - if resp.StatusMessage != "" { g.Client.Logger.Println(resp.StatusMessage) } + if resp.StatusMessage != "" { + gateway.Client.Logger.Println(resp.StatusMessage) + } - return resp, nil + return resp, nil } -func (g *CoreGateway) Cancel(orderId string) (Response, error) { - resp := Response{} +// Cancel : Cancel order using order ID +func (gateway *CoreGateway) Cancel(orderID string) (Response, error) { + resp := Response{} - err := g.Call("POST", "v2/" + orderId + "/cancel", nil, &resp) - if err != nil { - g.Client.Logger.Println("Error approving: ", err) - return resp, err - } + err := gateway.Call("POST", "v2/"+orderID+"/cancel", nil, &resp) + if err != nil { + gateway.Client.Logger.Println("Error approving: ", err) + return resp, err + } - if resp.StatusMessage != "" { g.Client.Logger.Println(resp.StatusMessage) } + if resp.StatusMessage != "" { + gateway.Client.Logger.Println(resp.StatusMessage) + } - return resp, nil + return resp, nil } -func (g *CoreGateway) Expire(orderId string) (Response, error) { - resp := Response{} +// Expire : change order status to expired using order ID +func (gateway *CoreGateway) Expire(orderID string) (Response, error) { + resp := Response{} - err := g.Call("POST", "v2/" + orderId + "/expire", nil, &resp) - if err != nil { - g.Client.Logger.Println("Error approving: ", err) - return resp, err - } + err := gateway.Call("POST", "v2/"+orderID+"/expire", nil, &resp) + if err != nil { + gateway.Client.Logger.Println("Error approving: ", err) + return resp, err + } - if resp.StatusMessage != "" { g.Client.Logger.Println(resp.StatusMessage) } + if resp.StatusMessage != "" { + gateway.Client.Logger.Println(resp.StatusMessage) + } - return resp, nil + return resp, nil } -func (g *CoreGateway) Status(orderId string) (Response, error) { - resp := Response{} +// Status : get order status using order ID +func (gateway *CoreGateway) Status(orderID string) (Response, error) { + resp := Response{} - err := g.Call("GET", "v2/" + orderId + "/status", nil, &resp) - if err != nil { - g.Client.Logger.Println("Error approving: ", err) - return resp, err - } + err := gateway.Call("GET", "v2/"+orderID+"/status", nil, &resp) + if err != nil { + gateway.Client.Logger.Println("Error approving: ", err) + return resp, err + } - if resp.StatusMessage != "" { g.Client.Logger.Println(resp.StatusMessage) } + if resp.StatusMessage != "" { + gateway.Client.Logger.Println(resp.StatusMessage) + } - return resp, nil -} \ No newline at end of file + return resp, nil +} diff --git a/envtype.go b/envtype.go index 739e036..e382ff0 100644 --- a/envtype.go +++ b/envtype.go @@ -2,11 +2,16 @@ package midtrans import "strings" +// EnvironmentType value type EnvironmentType int8 const ( _ EnvironmentType = iota + + // Sandbox : represent sandbox environment Sandbox + + // Production : represent production environment Production ) @@ -25,6 +30,7 @@ func (e EnvironmentType) String() string { return "undefined" } -func (e EnvironmentType) SnapUrl() string { +// SnapURL : Get environment API URL +func (e EnvironmentType) SnapURL() string { return strings.Replace(e.String(), "api.", "app.", 1) } diff --git a/paysource.go b/paysource.go index eaaff0d..9248e28 100644 --- a/paysource.go +++ b/paysource.go @@ -1,47 +1,84 @@ package midtrans +// PaymentType value type PaymentType string const ( - SourceBankTransfer PaymentType = "bank_transfer" - SourcePermataVA PaymentType = "permata_va" - SourceBCAVA PaymentType = "bca_va" - SourceBbmMoney PaymentType = "bbm_money" - SourceBcaKlikpay PaymentType = "bca_klikpay" - SourceBriEpay PaymentType = "bri_epay" - - SourceCreditCard PaymentType = "credit_card" - SourceCimbClicks PaymentType = "cimb_clicks" - SourceConvStore PaymentType = "cstore" - - SourceKlikBca PaymentType = "bca_klikbca" - SourceEchannel PaymentType = "echannel" - SourceMandiriClickpay PaymentType = "mandiri_clickpay" - SourceTelkomselCash PaymentType = "telkomsel_cash" - SourceXlTunai PaymentType = "xl_tunai" - SourceIndosatDompetku PaymentType = "indosat_dompetku" - SourceMandiriEcash PaymentType = "mandiri_ecash" - SourceKioson PaymentType = "kioson" - SourceIndomaret PaymentType = "indomaret" - SourceGiftCardIndo PaymentType = "gci" + // SourceBankTransfer : bank_transfer + SourceBankTransfer PaymentType = "bank_transfer" + + // SourcePermataVA : permata_va + SourcePermataVA PaymentType = "permata_va" + + // SourceBCAVA : bca_va + SourceBCAVA PaymentType = "bca_va" + + // SourceBbmMoney : bbm_money + SourceBbmMoney PaymentType = "bbm_money" + + // SourceBcaKlikpay : bca_klikpay + SourceBcaKlikpay PaymentType = "bca_klikpay" + + // SourceBriEpay : bri_epay + SourceBriEpay PaymentType = "bri_epay" + + // SourceCreditCard : credit_card + SourceCreditCard PaymentType = "credit_card" + + // SourceCimbClicks : cimb_clicks + SourceCimbClicks PaymentType = "cimb_clicks" + + // SourceConvStore : cstore + SourceConvStore PaymentType = "cstore" + + // SourceKlikBca : bca_klikbca + SourceKlikBca PaymentType = "bca_klikbca" + + // SourceEchannel : echannel + SourceEchannel PaymentType = "echannel" + + // SourceMandiriClickpay : mandiri_clickpay + SourceMandiriClickpay PaymentType = "mandiri_clickpay" + + // SourceTelkomselCash : telkomsel_cash + SourceTelkomselCash PaymentType = "telkomsel_cash" + + // SourceXlTunai : xl_tunai + SourceXlTunai PaymentType = "xl_tunai" + + // SourceIndosatDompetku : indosat_dompetku + SourceIndosatDompetku PaymentType = "indosat_dompetku" + + // SourceMandiriEcash : mandiri_ecash + SourceMandiriEcash PaymentType = "mandiri_ecash" + + // SourceKioson : kioson + SourceKioson PaymentType = "kioson" + + // SourceIndomaret : indomaret + SourceIndomaret PaymentType = "indomaret" + + // SourceGiftCardIndo : gci + SourceGiftCardIndo PaymentType = "gci" ) +// AllPaymentSource : Get All available PaymentType var AllPaymentSource = []PaymentType{ - SourceCreditCard, - SourceMandiriClickpay, - SourceCimbClicks, - SourceKlikBca, - SourceBcaKlikpay, - SourceBriEpay, - SourceTelkomselCash, - SourceEchannel, - SourceBbmMoney, - SourceXlTunai, - SourceIndosatDompetku, - SourceMandiriEcash, - SourcePermataVA, - SourceBCAVA, - SourceIndomaret, - SourceKioson, - SourceGiftCardIndo, -} \ No newline at end of file + SourceCreditCard, + SourceMandiriClickpay, + SourceCimbClicks, + SourceKlikBca, + SourceBcaKlikpay, + SourceBriEpay, + SourceTelkomselCash, + SourceEchannel, + SourceBbmMoney, + SourceXlTunai, + SourceIndosatDompetku, + SourceMandiriEcash, + SourcePermataVA, + SourceBCAVA, + SourceIndomaret, + SourceKioson, + SourceGiftCardIndo, +} diff --git a/request.go b/request.go index 7178201..d64f02d 100644 --- a/request.go +++ b/request.go @@ -1,13 +1,14 @@ package midtrans -// Represent the transaction details +// ItemDetail : Represent the transaction details type ItemDetail struct { - Id string `json:"id"` + ID string `json:"id"` Name string `json:"name"` Price int64 `json:"price"` Qty int32 `json:"quantity"` } +// CustAddress : Represent the customer address type CustAddress struct { FName string `json:"first_name"` LName string `json:"last_name"` @@ -18,7 +19,7 @@ type CustAddress struct { CountryCode string `json:"country_code"` } -// Represent the customer detail +// CustDetail : Represent the customer detail type CustDetail struct { // first name FName string `json:"first_name"` @@ -32,11 +33,13 @@ type CustDetail struct { ShipAddr *CustAddress `json:"customer_address,omitempty"` } +// TransactionDetails : Represent transaction details type TransactionDetails struct { OrderID string `json:"order_id"` GrossAmt int64 `json:"gross_amount"` } +// CreditCardDetail : Represent credit card detail type CreditCardDetail struct { Secure bool `json:"secure,omitempty"` TokenID string `json:"token_id"` @@ -46,13 +49,15 @@ type CreditCardDetail struct { Type string `json:"type,omitempty"` // indicate if generated token should be saved for next charge SaveTokenID bool `json:"save_token_id,omitempty"` - SavedTokenIdExpireAt string `json:"saved_token_id_expired_at,omitempty"` + SavedTokenIDExpireAt string `json:"saved_token_id_expired_at,omitempty"` } +// PermataBankTransferDetail : Represent Permata bank_transfer detail type PermataBankTransferDetail struct { Bank Bank `json:"bank"` } +// BCABankTransferLangDetail : Represent BCA bank_transfer lang detail type BCABankTransferLangDetail struct { LangID string `json:"id,omitempty"` LangEN string `json:"en,omitempty"` @@ -72,22 +77,26 @@ type BCABankTransferLangDetail struct { } */ +// BCABankTransferDetailFreeText : Represent BCA bank_transfer detail free_text type BCABankTransferDetailFreeText struct { Inquiry []BCABankTransferLangDetail `json:"inquiry,omitempty"` Payment []BCABankTransferLangDetail `json:"payment,omitempty"` } +// BCABankTransferDetail : Represent BCA bank_transfer detail type BCABankTransferDetail struct { Bank Bank `json:"bank"` VaNumber string `json:"va_number"` FreeText BCABankTransferDetailFreeText `json:"free_text"` } +// MandiriBillBankTransferDetail : Represent Mandiri Bill bank_transfer detail type MandiriBillBankTransferDetail struct { BillInfo1 string `json:"bill_info1,omitempty"` BillInfo2 string `json:"bill_info2,omitempty"` } +// BankTransferDetail : Represent bank_transfer detail type BankTransferDetail struct { Bank Bank `json:"bank,omitempty"` VaNumber string `json:"va_number,omitempty"` @@ -95,7 +104,7 @@ type BankTransferDetail struct { *MandiriBillBankTransferDetail } -// Internet Banking for BCA KlikPay +// BCAKlikPayDetail : Represent Internet Banking for BCA KlikPay type BCAKlikPayDetail struct { // 1 = normal, 2 = installment, 3 = normal + installment Type string `json:"type"` @@ -103,11 +112,13 @@ type BCAKlikPayDetail struct { MiscFee int64 `json:"misc_fee,omitempty"` } +// BCAKlikBCADetail : Represent BCA KlikBCA detail type BCAKlikBCADetail struct { Desc string `json:"description"` UserID string `json:"user_id"` } +// MandiriClickPayDetail : Represent Mandiri ClickPay detail type MandiriClickPayDetail struct { CardNumber string `json:"card_number"` Input1 string `json:"input1"` @@ -116,30 +127,35 @@ type MandiriClickPayDetail struct { Token string `json:"token"` } +// CIMBClicksDetail : Represent CIMB Clicks detail type CIMBClicksDetail struct { Desc string `json:"description"` } +// TelkomselCashDetail : Represent Telkomsel Cash detail type TelkomselCashDetail struct { Promo bool `json:"promo"` IsReversal int8 `json:"is_reversal"` Customer string `json:"customer"` } +// IndosatDompetkuDetail : Represent Indosat Dompetku detail type IndosatDompetkuDetail struct { MSISDN string `json:"msisdn"` } +// MandiriEcashDetail : Represent Mandiri e-Cash detail type MandiriEcashDetail struct { Desc string `json:"description"` } +// ConvStoreDetail : Represent cstore detail type ConvStoreDetail struct { Store string `json:"store"` Message string `json:"message"` } -// Represent the request payload +// ChargeReq : Represent Charge request payload type ChargeReq struct { PaymentType PaymentType `json:"payment_type"` TransactionDetails TransactionDetails `json:"transaction_details"` @@ -163,6 +179,7 @@ type ChargeReq struct { CustField3 string `json:"custom_field3,omitempty"` } +// SnapReq : Represent SNAP API request payload type SnapReq struct { TransactionDetails TransactionDetails `json:"transaction_details"` EnabledPayments []PaymentType `json:"enabled_payments"` @@ -174,6 +191,7 @@ type SnapReq struct { CustomField3 string `json:"custom_field3"` } +// CaptureReq : Represent Capture request payload type CaptureReq struct { TransactionID string `json:"transaction_id"` GrossAmt float64 `json:"gross_amount"` diff --git a/response.go b/response.go index eba7c36..106ed1b 100644 --- a/response.go +++ b/response.go @@ -1,5 +1,6 @@ package midtrans +// VANumber : bank virtual account number type VANumber struct { Bank string `json:"bank"` VANumber string `json:"va_number"` @@ -29,7 +30,7 @@ type Response struct { FraudStatus string `json:"fraud_status"` PaymentType string `json:"payment_type"` OrderID string `json:"order_id"` - TransactionId string `json:"transaction_id"` + TransactionID string `json:"transaction_id"` TransactionTime string `json:"transaction_time"` TransactionStatus string `json:"transaction_status"` GrossAmount string `json:"gross_amount"` @@ -37,7 +38,7 @@ type Response struct { PaymentCode string `json:"payment_code"` } -// Response after calling the Snap API +// SnapResponse : Response after calling the Snap API type SnapResponse struct { StatusCode string `json:"status_code"` Token string `json:"token"` diff --git a/snap.go b/snap.go index 2e9be2e..0b3576a 100644 --- a/snap.go +++ b/snap.go @@ -1,45 +1,48 @@ package midtrans import ( - "encoding/json" - "bytes" - "io" - "strings" + "bytes" + "encoding/json" + "io" + "strings" ) +// SnapGateway struct type SnapGateway struct { - Client Client + Client Client } -func (gway *SnapGateway) Call(method, path string, body io.Reader, v interface{}) error { - if !strings.HasPrefix(path, "/") { - path = "/" + path - } +// Call : base method to call Snap API +func (gateway *SnapGateway) Call(method, path string, body io.Reader, v interface{}) error { + if !strings.HasPrefix(path, "/") { + path = "/" + path + } - path = gway.Client.ApiEnvType.SnapUrl() + path - return gway.Client.Call(method, path, body, v) + path = gateway.Client.APIEnvType.SnapURL() + path + return gateway.Client.Call(method, path, body, v) } -// Quickly get token without constructing the body manually -func (g *SnapGateway) GetTokenQuick(orderId string, gross_amount int64) (SnapResponse, error) { - return g.GetToken(&SnapReq{ - TransactionDetails: TransactionDetails{ - OrderID: orderId, - GrossAmt: gross_amount, - }, - EnabledPayments: AllPaymentSource, - }) +// GetTokenQuick : Quickly get token without constructing the body manually +func (gateway *SnapGateway) GetTokenQuick(orderID string, grossAmount int64) (SnapResponse, error) { + return gateway.GetToken(&SnapReq{ + TransactionDetails: TransactionDetails{ + OrderID: orderID, + GrossAmt: grossAmount, + }, + EnabledPayments: AllPaymentSource, + }) } -func (gway *SnapGateway) GetToken(r *SnapReq) (SnapResponse, error) { - resp := SnapResponse{} - jsonReq, _ := json.Marshal(r) +// GetToken : Get token by consuming SnapReq +func (gateway *SnapGateway) GetToken(r *SnapReq) (SnapResponse, error) { + resp := SnapResponse{} + jsonReq, _ := json.Marshal(r) - err := gway.Call("POST", "snap/v1/transactions", bytes.NewBuffer(jsonReq), &resp) - if err != nil { - gway.Client.Logger.Println("Error getting snap token: ", err) - return resp, err - } + err := gateway.Call("POST", "snap/v1/transactions", bytes.NewBuffer(jsonReq), &resp) + if err != nil { + gateway.Client.Logger.Println("Error getting snap token: ", err) + return resp, err + } - return resp, nil + return resp, nil } From f8868af88fc3ea8ba46618215f40aa8d2dee87c7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Jul 2018 17:18:35 +0700 Subject: [PATCH 08/18] Remove warning : redundant if ...; err != nil check in client.go --- client.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/client.go b/client.go index 959e1d0..4f56713 100644 --- a/client.go +++ b/client.go @@ -119,11 +119,7 @@ func (c *Client) Call(method, path string, body io.Reader, v interface{}) error return err } - if err := c.ExecuteRequest(req, v); err != nil { - return err - } - - return nil + return c.ExecuteRequest(req, v) } // ===================== END HTTP CLIENT ================================================ From e37cfa52c1c4dbb6a86fc9975c503164ad5b33fd Mon Sep 17 00:00:00 2001 From: Harits Fahreza Christyonotoputra Date: Fri, 6 Jul 2018 13:09:33 +0700 Subject: [PATCH 09/18] Create LICENSE --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2a146e9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018 Midtrans + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From b7e3e1793eded191afe74dddb4056b2a6004256d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Jul 2018 13:16:20 +0700 Subject: [PATCH 10/18] Add LICENSE badge and section --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f27f062..c226079 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -[![Go Report Card](https://goreportcard.com/badge/github.com/veritrans/go-midtrans)](https://goreportcard.com/report/github.com/veritrans/go-midtrans) - # Midtrans Library for Go(lang) +[![Go Report Card](https://goreportcard.com/badge/github.com/veritrans/go-midtrans)](https://goreportcard.com/report/github.com/veritrans/go-midtrans) +[![Apache 2.0 license](http://img.shields.io/badge/license-Apache 2.0-brightgreen.svg)](LICENSE) + Midtrans :heart: Go ! Go is a very modern, terse, and combine aspect of dynamic and static typing that in a way very @@ -86,3 +87,7 @@ snap.pay(token, { You may want to override those `onSuccess`, `onPending` and `onError` functions to reflect the behaviour that you wished when the charging result in their respective state. + +## License + +See [LICENSE](LICENSE). From d909ffa4270b86424ec31b4a38951641a409598c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Jul 2018 13:18:40 +0700 Subject: [PATCH 11/18] Fix LICENSE badge link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c226079..d1d3c48 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Midtrans Library for Go(lang) [![Go Report Card](https://goreportcard.com/badge/github.com/veritrans/go-midtrans)](https://goreportcard.com/report/github.com/veritrans/go-midtrans) -[![Apache 2.0 license](http://img.shields.io/badge/license-Apache 2.0-brightgreen.svg)](LICENSE) +[![Apache 2.0 license](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](LICENSE) Midtrans :heart: Go ! From 658fc624c4fa5a8ea75b29fa415cf50146ee61cf Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Jul 2018 10:55:46 +0700 Subject: [PATCH 12/18] Fix client unit test --- client_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client_test.go b/client_test.go index 33e5e2b..b2cd5ab 100644 --- a/client_test.go +++ b/client_test.go @@ -12,5 +12,5 @@ func TestDefaultEnvironmentType(t *testing.T) { is := is.New(t) midclient := midtrans.NewClient() - is.Equal(midtrans.Sandbox, midclient.ApiEnvType) + is.Equal(midtrans.Sandbox, midclient.APIEnvType) } From 4856bd4d731ac9c1c2f19044cbd82d387a855e87 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Jul 2018 11:14:38 +0700 Subject: [PATCH 13/18] Fix APIEnvType on Simplepay --- example/simplepay/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/simplepay/main.go b/example/simplepay/main.go index 27d56a6..1d17aa5 100644 --- a/example/simplepay/main.go +++ b/example/simplepay/main.go @@ -48,7 +48,7 @@ func setupMidtrans() { midclient = midtrans.NewClient() midclient.ServerKey = "VT-server-7CVlR3AJ8Dpkez3k_TeGJQZU" midclient.ClientKey = "VT-client-IKktHiy3aRYHljsw" - midclient.ApiEnvType = midtrans.Sandbox + midclient.APIEnvType = midtrans.Sandbox coreGateway = midtrans.CoreGateway{ Client: midclient, From 645edc46e2704160bb6cb48b7f69d75b982b0feb Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Jul 2018 11:15:35 +0700 Subject: [PATCH 14/18] Fix APIEnvType README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1d3c48..2885446 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Please proceed there for more detail on how to run the example. midclient := midtrans.NewClient() midclient.ServerKey = "YOUR-VT-SERVER-KEY" midclient.ClientKey = "YOUR-VT-CLIENT-KEY" - midclient.ApiEnvType = midtrans.Sandbox + midclient.APIEnvType = midtrans.Sandbox coreGateway := midtrans.CoreGateway{ Client: midclient, From 7e0992682c60dba93f858af943633f92a0b7fac8 Mon Sep 17 00:00:00 2001 From: Arman Date: Wed, 11 Jul 2018 12:58:52 +0700 Subject: [PATCH 15/18] add Gopkg --- Gopkg.lock | 21 +++++++++++++++++++++ Gopkg.toml | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 Gopkg.lock create mode 100644 Gopkg.toml diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..56e7a88 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,21 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "master" + name = "github.com/cheekybits/is" + packages = ["."] + revision = "68e9c0620927fb5427fda3708222d0edee89eae9" + +[[projects]] + branch = "master" + name = "github.com/veritrans/go-midtrans" + packages = ["."] + revision = "234c054b1e868f13513595f3d0927e23336e1abf" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "b610c69f3e94521a405e4cce81013c70eade23fb391662fc9da87df6bdc3a1b8" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..79617f3 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,38 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + branch = "master" + name = "github.com/cheekybits/is" + +[[constraint]] + branch = "master" + name = "github.com/veritrans/go-midtrans" + +[prune] + go-tests = true + unused-packages = true From 6b5f87f83bfea31285d28d5d43624828df62c62e Mon Sep 17 00:00:00 2001 From: Arman Date: Wed, 11 Jul 2018 13:00:08 +0700 Subject: [PATCH 16/18] add gopay as payment source --- paysource.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/paysource.go b/paysource.go index 9248e28..4de26d1 100644 --- a/paysource.go +++ b/paysource.go @@ -4,6 +4,9 @@ package midtrans type PaymentType string const ( + // SourceBankTransfer : gopay + SourceGopay PaymentType = "gopay" + // SourceBankTransfer : bank_transfer SourceBankTransfer PaymentType = "bank_transfer" From 003634a8e8ee30036787a688584c7f4d7c7953e2 Mon Sep 17 00:00:00 2001 From: Arman Date: Wed, 11 Jul 2018 13:00:34 +0700 Subject: [PATCH 17/18] add gopay to `AllPaymentSource` --- paysource.go | 1 + 1 file changed, 1 insertion(+) diff --git a/paysource.go b/paysource.go index 4de26d1..92fcf12 100644 --- a/paysource.go +++ b/paysource.go @@ -67,6 +67,7 @@ const ( // AllPaymentSource : Get All available PaymentType var AllPaymentSource = []PaymentType{ + SourceGopay, SourceCreditCard, SourceMandiriClickpay, SourceCimbClicks, From 3db2741a5317e42d318371c2ffef66b338331de2 Mon Sep 17 00:00:00 2001 From: Arman Date: Wed, 11 Jul 2018 13:03:27 +0700 Subject: [PATCH 18/18] Add action in response --- response.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/response.go b/response.go index 106ed1b..463c3c1 100644 --- a/response.go +++ b/response.go @@ -6,6 +6,12 @@ type VANumber struct { VANumber string `json:"va_number"` } +type Action struct { + Name string `json:"name"` + Method string `json:"method"` + URL string `json:"url"` +} + // Response after calling the API type Response struct { StatusCode string `json:"status_code"` @@ -36,6 +42,7 @@ type Response struct { GrossAmount string `json:"gross_amount"` VANumbers []VANumber `json:"va_numbers"` PaymentCode string `json:"payment_code"` + Actions []Action `json:"actions"` } // SnapResponse : Response after calling the Snap API