3pl/partnerapi/globalcare/globale_care.go

193 lines
4.8 KiB
Go
Raw Normal View History

2022-08-15 04:51:07 +00:00
package globalcare
import (
2022-08-28 07:16:27 +00:00
"crypto"
"crypto/rand"
2022-08-15 04:51:07 +00:00
"crypto/rsa"
2022-08-28 07:16:27 +00:00
"crypto/sha256"
"errors"
2022-08-15 04:51:07 +00:00
"fmt"
"net/http"
"github.com/Selly-Modules/logger"
"github.com/Selly-Modules/natsio"
2022-08-18 10:58:22 +00:00
"github.com/Selly-Modules/natsio/model"
2022-08-28 07:16:27 +00:00
"github.com/Selly-Modules/natsio/subject"
2022-08-15 04:51:07 +00:00
"github.com/nats-io/nats.go"
"github.com/thoas/go-funk"
2022-08-18 10:58:22 +00:00
"github.com/Selly-Modules/3pl/util/base64"
"github.com/Selly-Modules/3pl/util/pjson"
2022-08-15 04:51:07 +00:00
)
// Client ...
type Client struct {
privateKey *rsa.PrivateKey
publicKey *rsa.PublicKey
env ENV
natsClient natsio.Server
}
// NewClient generate Client
// using privateKey to decrypt data from Global Care
// using publicKey to encrypt data before send to Global Care
2022-08-28 07:16:27 +00:00
func NewClient(env ENV, privateKey, publicKey string, natsClient natsio.Server) (*Client, error) {
2022-08-15 04:51:07 +00:00
validENVs := []ENV{EnvProd, EnvDev, EnvStaging}
if !funk.Contains(validENVs, env) {
return nil, fmt.Errorf("globalcare.NewClient - invalid_env: %s", env)
}
pubKey, err := generatePublicKeyFromBytes([]byte(publicKey))
if err != nil {
return nil, fmt.Errorf("globalcare.NewClient - invalid_public_key: %v", err)
}
privKey, err := generatePrivateKeyFromBytes([]byte(privateKey))
if err != nil {
return nil, fmt.Errorf("globalcare.NewClient - invalid_private_key: %v", err)
}
return &Client{
privateKey: privKey,
publicKey: pubKey,
2022-08-28 07:16:27 +00:00
env: env,
natsClient: natsClient,
2022-08-15 04:51:07 +00:00
}, nil
}
// CreateOrder ...
2022-08-28 07:16:27 +00:00
func (c *Client) CreateOrder(p CreateOrderPayload) (*CreateOrderResponseDecoded, error) {
2022-08-15 04:51:07 +00:00
url := c.getBaseURL() + apiPathCreateOrder
data := createOrderData{
ProductCode: productCodeDefault,
ProviderID: providerIDDefault,
ProductID: productIDDefault,
PartnerID: p.PartnerOrderCode,
VehicleInfo: p.VehicleInfo,
InsuredInfo: p.InsuredInfo,
}
2022-08-28 07:16:27 +00:00
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)
}
2022-08-15 04:51:07 +00:00
body := CommonRequestBody{
2022-08-28 07:16:27 +00:00
Signature: sign,
Data: dataString,
2022-08-15 04:51:07 +00:00
}
2022-08-18 10:58:22 +00:00
natsPayload := model.CommunicationRequestHttp{
2022-08-15 04:51:07 +00:00
ResponseImmediately: true,
2022-08-18 10:58:22 +00:00
Payload: model.HttpRequest{
2022-08-15 04:51:07 +00:00
URL: url,
Method: http.MethodPost,
Data: pjson.ToJSONString(body),
2022-08-31 10:52:52 +00:00
Header: map[string]string{
"Content-Type": "application/json",
},
2022-08-15 04:51:07 +00:00
},
}
2022-08-28 07:16:27 +00:00
msg, err := c.requestNats(subject.Communication.RequestHTTP, natsPayload)
2022-08-15 04:51:07 +00:00
if err != nil {
logger.Error("globalcare.Client.CreateOrder", logger.LogData{
"err": err.Error(),
"payload": natsPayload,
})
return nil, err
}
var (
2022-08-18 10:58:22 +00:00
r model.CommunicationHttpResponse
2022-08-15 04:51:07 +00:00
res CommonResponse
)
if err = pjson.Unmarshal(msg.Data, &r); err != nil {
return nil, err
}
2022-08-28 07:16:27 +00:00
if err = r.ParseResponseData(&res); err != nil {
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
2022-08-15 04:51:07 +00:00
}
// GetOrder ...
2022-08-28 07:16:27 +00:00
func (c *Client) GetOrder(orderCode string) (*GetOrderResponseDecoded, error) {
2022-08-15 04:51:07 +00:00
url := c.getBaseURL() + fmt.Sprintf(apiPathGetOrder, orderCode)
2022-08-18 10:58:22 +00:00
natsPayload := model.CommunicationRequestHttp{
2022-08-15 04:51:07 +00:00
ResponseImmediately: true,
2022-08-18 10:58:22 +00:00
Payload: model.HttpRequest{
2022-08-15 04:51:07 +00:00
URL: url,
Method: http.MethodGet,
},
}
2022-08-28 07:16:27 +00:00
msg, err := c.requestNats(subject.Communication.RequestHTTP, natsPayload)
2022-08-15 04:51:07 +00:00
if err != nil {
logger.Error("globalcare.Client.GetOrder", logger.LogData{
"err": err.Error(),
"payload": natsPayload,
})
return nil, err
}
var (
2022-08-18 10:58:22 +00:00
r model.CommunicationHttpResponse
2022-08-15 04:51:07 +00:00
res CommonResponse
)
if err = pjson.Unmarshal(msg.Data, &r); err != nil {
return nil, err
}
2022-08-28 07:16:27 +00:00
if err = r.ParseResponseData(&res); err != nil {
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
2022-08-15 04:51:07 +00:00
}
func (c *Client) requestNats(subject string, data interface{}) (*nats.Msg, error) {
b := toBytes(data)
return c.natsClient.Request(subject, b)
}
func (c *Client) getBaseURL() string {
return baseURLENVMapping[c.env]
}
2022-08-28 07:16:27 +00:00
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
}