Integrate global care #2
			
				
			
		
		
		
	| 
						 | 
					@ -1,9 +0,0 @@
 | 
				
			||||||
package constant
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const natsCommunicationPrefix = "communication_"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	NatsCommunicationSubjectRequestHTTP  = natsCommunicationPrefix + "request_http"
 | 
					 | 
				
			||||||
	NatsCommunicationSubjectResponseHTTP = natsCommunicationPrefix + "response_http"
 | 
					 | 
				
			||||||
	NatsCommunicationSubjectWebhookTNC   = natsCommunicationPrefix + "webhook_tnc"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							| 
						 | 
					@ -36,3 +36,5 @@ require (
 | 
				
			||||||
	golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
 | 
						golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
 | 
				
			||||||
	howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
 | 
						howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//replace github.com/Selly-Modules/natsio => /Users/sinh/Documents/dev/selly-module/natsio
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,21 @@
 | 
				
			||||||
package globalcare
 | 
					package globalcare
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"crypto"
 | 
				
			||||||
 | 
						"crypto/rand"
 | 
				
			||||||
	"crypto/rsa"
 | 
						"crypto/rsa"
 | 
				
			||||||
 | 
						"crypto/sha256"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/Selly-Modules/logger"
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
	"github.com/Selly-Modules/natsio"
 | 
						"github.com/Selly-Modules/natsio"
 | 
				
			||||||
	"github.com/Selly-Modules/natsio/model"
 | 
						"github.com/Selly-Modules/natsio/model"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/natsio/subject"
 | 
				
			||||||
	"github.com/nats-io/nats.go"
 | 
						"github.com/nats-io/nats.go"
 | 
				
			||||||
	"github.com/thoas/go-funk"
 | 
						"github.com/thoas/go-funk"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/Selly-Modules/3pl/constant"
 | 
					 | 
				
			||||||
	"github.com/Selly-Modules/3pl/util/base64"
 | 
						"github.com/Selly-Modules/3pl/util/base64"
 | 
				
			||||||
	"github.com/Selly-Modules/3pl/util/pjson"
 | 
						"github.com/Selly-Modules/3pl/util/pjson"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -27,7 +31,7 @@ type Client struct {
 | 
				
			||||||
// NewClient generate Client
 | 
					// NewClient generate Client
 | 
				
			||||||
// using privateKey to decrypt data from Global Care
 | 
					// using privateKey to decrypt data from Global Care
 | 
				
			||||||
// using publicKey to encrypt data before send to Global Care
 | 
					// using publicKey to encrypt data before send to Global Care
 | 
				
			||||||
func NewClient(env ENV, privateKey, publicKey string) (*Client, error) {
 | 
					func NewClient(env ENV, privateKey, publicKey string, natsClient natsio.Server) (*Client, error) {
 | 
				
			||||||
	validENVs := []ENV{EnvProd, EnvDev, EnvStaging}
 | 
						validENVs := []ENV{EnvProd, EnvDev, EnvStaging}
 | 
				
			||||||
	if !funk.Contains(validENVs, env) {
 | 
						if !funk.Contains(validENVs, env) {
 | 
				
			||||||
		return nil, fmt.Errorf("globalcare.NewClient - invalid_env: %s", env)
 | 
							return nil, fmt.Errorf("globalcare.NewClient - invalid_env: %s", env)
 | 
				
			||||||
| 
						 | 
					@ -43,11 +47,13 @@ func NewClient(env ENV, privateKey, publicKey string) (*Client, error) {
 | 
				
			||||||
	return &Client{
 | 
						return &Client{
 | 
				
			||||||
		privateKey: privKey,
 | 
							privateKey: privKey,
 | 
				
			||||||
		publicKey:  pubKey,
 | 
							publicKey:  pubKey,
 | 
				
			||||||
 | 
							env:        env,
 | 
				
			||||||
 | 
							natsClient: natsClient,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateOrder ...
 | 
					// CreateOrder ...
 | 
				
			||||||
func (c *Client) CreateOrder(p CreateOrderPayload) (*CommonResponse, error) {
 | 
					func (c *Client) CreateOrder(p CreateOrderPayload) (*CreateOrderResponseDecoded, error) {
 | 
				
			||||||
	url := c.getBaseURL() + apiPathCreateOrder
 | 
						url := c.getBaseURL() + apiPathCreateOrder
 | 
				
			||||||
	data := createOrderData{
 | 
						data := createOrderData{
 | 
				
			||||||
		ProductCode: productCodeDefault,
 | 
							ProductCode: productCodeDefault,
 | 
				
			||||||
| 
						 | 
					@ -58,9 +64,14 @@ func (c *Client) CreateOrder(p CreateOrderPayload) (*CommonResponse, error) {
 | 
				
			||||||
		InsuredInfo: p.InsuredInfo,
 | 
							InsuredInfo: p.InsuredInfo,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dataString := base64.Encode(pjson.ToBytes(data))
 | 
				
			||||||
 | 
						sign, err := c.signData(dataString)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("globalcare.Client.CreateOrder - sign_err %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	body := CommonRequestBody{
 | 
						body := CommonRequestBody{
 | 
				
			||||||
		Signature: "", // TODO:implement
 | 
							Signature: sign,
 | 
				
			||||||
		Data:      base64.Encode(pjson.ToBytes(data)),
 | 
							Data:      dataString,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	natsPayload := model.CommunicationRequestHttp{
 | 
						natsPayload := model.CommunicationRequestHttp{
 | 
				
			||||||
		ResponseImmediately: true,
 | 
							ResponseImmediately: true,
 | 
				
			||||||
| 
						 | 
					@ -70,7 +81,7 @@ func (c *Client) CreateOrder(p CreateOrderPayload) (*CommonResponse, error) {
 | 
				
			||||||
			Data:   pjson.ToJSONString(body),
 | 
								Data:   pjson.ToJSONString(body),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	msg, err := c.requestNats(constant.NatsCommunicationSubjectRequestHTTP, natsPayload)
 | 
						msg, err := c.requestNats(subject.Communication.RequestHTTP, natsPayload)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logger.Error("globalcare.Client.CreateOrder", logger.LogData{
 | 
							logger.Error("globalcare.Client.CreateOrder", logger.LogData{
 | 
				
			||||||
			"err":     err.Error(),
 | 
								"err":     err.Error(),
 | 
				
			||||||
| 
						 | 
					@ -85,12 +96,30 @@ func (c *Client) CreateOrder(p CreateOrderPayload) (*CommonResponse, error) {
 | 
				
			||||||
	if err = pjson.Unmarshal(msg.Data, &r); err != nil {
 | 
						if err = pjson.Unmarshal(msg.Data, &r); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = r.ParseResponseData(&res)
 | 
						if err = r.ParseResponseData(&res); err != nil {
 | 
				
			||||||
	return &res, err
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if r.Response == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("globalcare.Client.CreateOrder create_order_empty_response")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.Response.StatusCode >= http.StatusBadRequest {
 | 
				
			||||||
 | 
							info, err := res.DecodeError()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil, errors.New(info.Message)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						info, err := res.DecodeCreateOrderSuccess()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &info, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetOrder ...
 | 
					// GetOrder ...
 | 
				
			||||||
func (c *Client) GetOrder(orderCode string) (*CommonResponse, error) {
 | 
					func (c *Client) GetOrder(orderCode string) (*GetOrderResponseDecoded, error) {
 | 
				
			||||||
	url := c.getBaseURL() + fmt.Sprintf(apiPathGetOrder, orderCode)
 | 
						url := c.getBaseURL() + fmt.Sprintf(apiPathGetOrder, orderCode)
 | 
				
			||||||
	natsPayload := model.CommunicationRequestHttp{
 | 
						natsPayload := model.CommunicationRequestHttp{
 | 
				
			||||||
		ResponseImmediately: true,
 | 
							ResponseImmediately: true,
 | 
				
			||||||
| 
						 | 
					@ -99,7 +128,7 @@ func (c *Client) GetOrder(orderCode string) (*CommonResponse, error) {
 | 
				
			||||||
			Method: http.MethodGet,
 | 
								Method: http.MethodGet,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	msg, err := c.requestNats(constant.NatsCommunicationSubjectRequestHTTP, natsPayload)
 | 
						msg, err := c.requestNats(subject.Communication.RequestHTTP, natsPayload)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logger.Error("globalcare.Client.GetOrder", logger.LogData{
 | 
							logger.Error("globalcare.Client.GetOrder", logger.LogData{
 | 
				
			||||||
			"err":     err.Error(),
 | 
								"err":     err.Error(),
 | 
				
			||||||
| 
						 | 
					@ -114,8 +143,25 @@ func (c *Client) GetOrder(orderCode string) (*CommonResponse, error) {
 | 
				
			||||||
	if err = pjson.Unmarshal(msg.Data, &r); err != nil {
 | 
						if err = pjson.Unmarshal(msg.Data, &r); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = r.ParseResponseData(&res)
 | 
						if err = r.ParseResponseData(&res); err != nil {
 | 
				
			||||||
	return &res, err
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if r.Response == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("globalcare.Client.GetOrder get_order_empty_response")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.Response.StatusCode >= http.StatusBadRequest {
 | 
				
			||||||
 | 
							info, err := res.DecodeError()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil, errors.New(info.Message)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						info, err := res.DecodeGetOrderSuccess()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &info, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Client) requestNats(subject string, data interface{}) (*nats.Msg, error) {
 | 
					func (c *Client) requestNats(subject string, data interface{}) (*nats.Msg, error) {
 | 
				
			||||||
| 
						 | 
					@ -126,3 +172,18 @@ func (c *Client) requestNats(subject string, data interface{}) (*nats.Msg, error
 | 
				
			||||||
func (c *Client) getBaseURL() string {
 | 
					func (c *Client) getBaseURL() string {
 | 
				
			||||||
	return baseURLENVMapping[c.env]
 | 
						return baseURLENVMapping[c.env]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Client) signData(s string) (string, error) {
 | 
				
			||||||
 | 
						msgHash := sha256.New()
 | 
				
			||||||
 | 
						_, err := msgHash.Write([]byte(s))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						msgHashSum := msgHash.Sum(nil)
 | 
				
			||||||
 | 
						signature, err := rsa.SignPKCS1v15(rand.Reader, c.privateKey, crypto.SHA256, msgHashSum)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return base64.Encode(signature), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,87 @@
 | 
				
			||||||
package globalcare
 | 
					package globalcare
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "encoding/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CommonResponse ...
 | 
					// CommonResponse ...
 | 
				
			||||||
type CommonResponse struct {
 | 
					type CommonResponse struct {
 | 
				
			||||||
	StatusCode int         `json:"statusCode"`
 | 
						Data      string `json:"data"`
 | 
				
			||||||
	Message    string      `json:"message"`
 | 
						Signature string `json:"signature"`
 | 
				
			||||||
	Result     interface{} `json:"result"`
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DecodeCreateOrderSuccess ...
 | 
				
			||||||
 | 
					func (r *CommonResponse) DecodeCreateOrderSuccess() (res CreateOrderResponseDecoded, err error) {
 | 
				
			||||||
 | 
						err = r.Decode(res)
 | 
				
			||||||
 | 
						return res, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DecodeGetOrderSuccess ...
 | 
				
			||||||
 | 
					func (r *CommonResponse) DecodeGetOrderSuccess() (res GetOrderResponseDecoded, err error) {
 | 
				
			||||||
 | 
						err = r.Decode(res)
 | 
				
			||||||
 | 
						return res, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DecodeError ...
 | 
				
			||||||
 | 
					func (r *CommonResponse) DecodeError() (res ResponseError, err error) {
 | 
				
			||||||
 | 
						err = r.Decode(res)
 | 
				
			||||||
 | 
						return res, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Decode ...
 | 
				
			||||||
 | 
					func (r *CommonResponse) Decode(resultPointer interface{}) error {
 | 
				
			||||||
 | 
						return json.Unmarshal([]byte(r.Data), resultPointer)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CreateOrderResponseDecoded ...
 | 
				
			||||||
 | 
					type CreateOrderResponseDecoded struct {
 | 
				
			||||||
 | 
						StatusCode int               `json:"statusCode"`
 | 
				
			||||||
 | 
						Result     CreateOrderResult `json:"result"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CreateOrderResult ...
 | 
				
			||||||
 | 
					type CreateOrderResult struct {
 | 
				
			||||||
 | 
						OrderCode   string `json:"orderCode"`
 | 
				
			||||||
 | 
						PaymentLink string `json:"paymentLink"`
 | 
				
			||||||
 | 
						Fees        int    `json:"fees"`
 | 
				
			||||||
 | 
						StatusId    int    `json:"statusId"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ResponseError ...
 | 
				
			||||||
 | 
					type ResponseError struct {
 | 
				
			||||||
 | 
						StatusCode int    `json:"statusCode"`
 | 
				
			||||||
 | 
						Message    string `json:"message"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetOrderResponseDecoded ...
 | 
				
			||||||
 | 
					type GetOrderResponseDecoded struct {
 | 
				
			||||||
 | 
						StatusCode int            `json:"statusCode"`
 | 
				
			||||||
 | 
						Result     GetOrderResult `json:"result"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetOrderResult ...
 | 
				
			||||||
 | 
					type GetOrderResult struct {
 | 
				
			||||||
 | 
						ProviderTitle string        `json:"providerTitle"`
 | 
				
			||||||
 | 
						BeginDate     string        `json:"beginDate"`
 | 
				
			||||||
 | 
						EndDate       string        `json:"endDate"`
 | 
				
			||||||
 | 
						Amount        string        `json:"amount"`
 | 
				
			||||||
 | 
						CertLink      string        `json:"certLink"`
 | 
				
			||||||
 | 
						StatusId      int           `json:"statusId"`
 | 
				
			||||||
 | 
						StatusTitle   string        `json:"statusTitle"`
 | 
				
			||||||
 | 
						Buyer         BuyerInfo     `json:"buyer"`
 | 
				
			||||||
 | 
						InsuredInfo   InsuranceInfo `json:"insuredInfo"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// InsuranceInfo ...
 | 
				
			||||||
 | 
					type InsuranceInfo struct {
 | 
				
			||||||
 | 
						TypeId                       int    `json:"typeId"`
 | 
				
			||||||
 | 
						TypeName                     string `json:"typeName"`
 | 
				
			||||||
 | 
						CarOccupantAccidentInsurance int    `json:"carOccupantAccidentInsurance"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// BuyerInfo ...
 | 
				
			||||||
 | 
					type BuyerInfo struct {
 | 
				
			||||||
 | 
						BuyerName      string      `json:"buyerName"`
 | 
				
			||||||
 | 
						BuyerPrivateId interface{} `json:"buyerPrivateId"`
 | 
				
			||||||
 | 
						BuyerPhone     string      `json:"buyerPhone"`
 | 
				
			||||||
 | 
						BuyerAddress   string      `json:"buyerAddress"`
 | 
				
			||||||
 | 
						BuyerEmail     string      `json:"buyerEmail"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,9 +9,9 @@ import (
 | 
				
			||||||
	"github.com/Selly-Modules/logger"
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
	"github.com/Selly-Modules/natsio"
 | 
						"github.com/Selly-Modules/natsio"
 | 
				
			||||||
	"github.com/Selly-Modules/natsio/model"
 | 
						"github.com/Selly-Modules/natsio/model"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/natsio/subject"
 | 
				
			||||||
	"github.com/nats-io/nats.go"
 | 
						"github.com/nats-io/nats.go"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/Selly-Modules/3pl/constant"
 | 
					 | 
				
			||||||
	"github.com/Selly-Modules/3pl/util/pjson"
 | 
						"github.com/Selly-Modules/3pl/util/pjson"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -288,7 +288,7 @@ func (c *Client) getRequestHeader() map[string]string {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Client) requestHttpViaNats(data model.CommunicationRequestHttp) (*nats.Msg, error) {
 | 
					func (c *Client) requestHttpViaNats(data model.CommunicationRequestHttp) (*nats.Msg, error) {
 | 
				
			||||||
	s := constant.NatsCommunicationSubjectRequestHTTP
 | 
						s := subject.Communication.RequestHTTP
 | 
				
			||||||
	b := pjson.ToBytes(data)
 | 
						b := pjson.ToBytes(data)
 | 
				
			||||||
	return c.natsClient.Request(s, b)
 | 
						return c.natsClient.Request(s, b)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue