Skip to content

Commit

Permalink
Initial Commit (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
abdulahwahdi authored Jan 25, 2021
1 parent e6eb288 commit 2e6aa17
Show file tree
Hide file tree
Showing 16 changed files with 880 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# EditorConfig coding styles definitions. For more information about the
# properties used in this file, please see the EditorConfig documentation:
# http://editorconfig.org/

# indicate this is the root of the project
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

indent_style = space
indent_size = 4

[Makefile]
indent_style = tab

[*.md]
trim_trailing_whitespace = false
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea/
.vscode/
.DS_Store
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2021 Bhinneka.com

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.
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.PHONY: test cover

test:
go test -race

cover:
go test -race -coverprofile=coverage.txt -covermode=atomic
190 changes: 190 additions & 0 deletions cicil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package cicil

import (
"bytes"
"crypto/hmac"
"crypto/sha256"
b64 "encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"strings"
"time"
)

// cicil entry struick for cicil
type cicil struct {
MerchantID string
APIKey string
MerchantSecret string
BaseURL string
client *cicilHttpClient
*logger
}

/*New Function, create cicil pointer
Required parameter :
1. Your MerchantID (this from Team cicil)
2. Your MerchantSecret (this from Team cicil)
3. Your APIKey (this from Team cicil)
3. BaseURL (hit to endpoint ex: https://sandbox-api.cicil.dev/v1 for sandbox.
this value based on https://docs.cicil.app/#introduction)
*/
func New(baseUrl string, apiKey string, merchantId string, merchantSecret string, timeout time.Duration) *cicil {
httpRequest := newRequest(timeout)
return &cicil{
APIKey: apiKey,
MerchantID: merchantId,
MerchantSecret: merchantSecret,
BaseURL: baseUrl,
client: httpRequest,
logger: newLogger(),
}
}

func (c *cicil) call(method string, path string, body io.Reader, v interface{}, headers map[string]string) error {
c.info().Println("Starting http call..")
if !strings.HasPrefix(path, "/") {
path = "/" + path
}

path = fmt.Sprintf("%s%s", c.BaseURL, path)
return c.client.exec(method, path, body, v, headers)
}

func (c *cicil) GetToken() (digest string, dateNowReturn string) {
dateNow := time.Now().Format(time.RFC1123)
formattedMessage := fmt.Sprintf("%s%s", c.MerchantSecret, dateNow)
// Create a new HMAC by defining the hash type and the key (as byte array)
h := hmac.New(sha256.New, []byte(c.APIKey))
// Write Data to it
h.Write([]byte(formattedMessage))

// Get result and encode as hexadecimal string
digestData := hex.EncodeToString(h.Sum(nil))
basicData := fmt.Sprintf("%s:%s", c.MerchantID, digestData)
output := b64.URLEncoding.EncodeToString([]byte(basicData))
return output, dateNow
}

func (c *cicil) GetCheckoutURL(param CheckoutRequest) (resp CheckoutResponse, err error) {
c.info().Println("Starting Get Order URL Cicil")
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
if err != nil {
c.error().Println(err.Error())
}
}()
var getCheckoutURLResponse CheckoutResponse

// get auth data
getDiggest, getDate := c.GetToken()

// set header
headers := make(map[string]string)
headers["Content-Type"] = "application/json"
headers["Date"] = getDate
headers["Authorization"] = fmt.Sprintf("Basic %s", getDiggest)

pathGetOrderURL := "po"
//Marshal Order
payload, errPayload := json.Marshal(param)
if errPayload != nil {
return getCheckoutURLResponse, err
}

err = c.call("POST", pathGetOrderURL, bytes.NewBuffer(payload), &getCheckoutURLResponse, headers)
if err != nil {
return getCheckoutURLResponse, err
}
if len(getCheckoutURLResponse.Message) > 0 {
err = errors.New(getCheckoutURLResponse.Message)
return getCheckoutURLResponse, err
}

return getCheckoutURLResponse, nil
}

func (c *cicil) SetCancelOrder (param CancelOrderRequest) (resp CancelOrderResponse, err error) {
c.info().Println("Starting Set Cancel Order Cicil")
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
if err != nil {
c.error().Println(err.Error())
}
}()
var setCancelOrderResponse CancelOrderResponse

// get auth data
getDiggest, getDate := c.GetToken()

// set header
headers := make(map[string]string)
headers["Content-Type"] = "application/json"
headers["Date"] = getDate
headers["Authorization"] = fmt.Sprintf("Basic %s", getDiggest)

pathGetOrderURL := "po/cancel"
//Marshal Order
payload, errPayload := json.Marshal(param)
if errPayload != nil {
return setCancelOrderResponse, err
}

err = c.call("POST", pathGetOrderURL, bytes.NewBuffer(payload), &setCancelOrderResponse, headers)
if err != nil {
return setCancelOrderResponse, err
}
if len(setCancelOrderResponse.Message) > 0 {
err = errors.New(setCancelOrderResponse.Message)
return setCancelOrderResponse, err
}

return setCancelOrderResponse, nil
}

func (c *cicil) UpdateStatus (param UpdateStatusRequest) (resp UpdateStatusResponse, err error) {
c.info().Println("Starting Set Cancel Order Cicil")
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
if err != nil {
c.error().Println(err.Error())
}
}()
var updateStatusResponse UpdateStatusResponse

// get auth data
getDiggest, getDate := c.GetToken()

// set header
headers := make(map[string]string)
headers["Content-Type"] = "application/json"
headers["Date"] = getDate
headers["Authorization"] = fmt.Sprintf("Basic %s", getDiggest)

pathGetOrderURL := "po/update"
//Marshal Order
payload, errPayload := json.Marshal(param)
if errPayload != nil {
return updateStatusResponse, err
}

err = c.call("POST", pathGetOrderURL, bytes.NewBuffer(payload), &updateStatusResponse, headers)
if err != nil {
return updateStatusResponse, err
}
if len(updateStatusResponse.Message) > 0 {
err = errors.New(updateStatusResponse.Message)
return updateStatusResponse, err
}

return updateStatusResponse, nil
}
Loading

0 comments on commit 2e6aa17

Please sign in to comment.