github.com/mundipagg/boleto-api@v0.0.0-20230620145841-3f9ec742599f/pefisa/pefisa.go (about) 1 package pefisa 2 3 import ( 4 "errors" 5 "strconv" 6 "strings" 7 "sync" 8 9 . "github.com/PMoneda/flow" 10 "github.com/mundipagg/boleto-api/config" 11 "github.com/mundipagg/boleto-api/log" 12 "github.com/mundipagg/boleto-api/metrics" 13 "github.com/mundipagg/boleto-api/models" 14 "github.com/mundipagg/boleto-api/tmpl" 15 "github.com/mundipagg/boleto-api/util" 16 "github.com/mundipagg/boleto-api/validations" 17 ) 18 19 var o = &sync.Once{} 20 var m map[string]string 21 22 type bankPefisa struct { 23 validate *models.Validator 24 log *log.Log 25 } 26 27 func New() bankPefisa { 28 b := bankPefisa{ 29 validate: models.NewValidator(), 30 log: log.CreateLog(), 31 } 32 33 b.validate.Push(validations.ValidateAmount) 34 b.validate.Push(validations.ValidateExpireDate) 35 b.validate.Push(validations.ValidateBuyerDocumentNumber) 36 b.validate.Push(validations.ValidateRecipientDocumentNumber) 37 b.validate.Push(pefisaBoletoTypeValidate) 38 39 return b 40 } 41 42 func (b bankPefisa) Log() *log.Log { 43 return b.log 44 } 45 46 func (b bankPefisa) GetToken(boleto *models.BoletoRequest) (string, error) { 47 48 pipe := NewFlow() 49 url := config.Get().URLPefisaToken 50 51 pipe.From("message://?source=inline", boleto, getRequestToken(), tmpl.GetFuncMaps()) 52 pipe.To("log://?type=request&format=json&url="+url, b.log) 53 54 duration := util.Duration(func() { 55 pipe.To(url, map[string]string{"method": "POST", "insecureSkipVerify": "true", "timeout": config.Get().TimeoutToken}) 56 }) 57 metrics.PushTimingMetric("pefisa-get-token-boleto-time", duration.Seconds()) 58 pipe.To("log://?type=response&format=json&url="+url, b.log) 59 ch := pipe.Choice() 60 ch.When(Header("status").IsEqualTo("200")) 61 ch.To("transform://?format=json", getTokenResponse(), `{{.access_token}}`, tmpl.GetFuncMaps()) 62 63 ch.When(Header("status").IsEqualTo("401")) 64 ch.To("transform://?format=json", getTokenErrorResponse(), `{{.error_description}}`, tmpl.GetFuncMaps()) 65 ch.To("set://?prop=body", errors.New(pipe.GetBody().(string))) 66 67 ch.Otherwise() 68 ch.To("log://?type=request&url="+url, b.log).To("print://?msg=${body}").To("set://?prop=body", errors.New("integration error")) 69 switch t := pipe.GetBody().(type) { 70 case string: 71 72 return t, nil 73 case error: 74 return "", t 75 } 76 return "", nil 77 78 } 79 80 func (b bankPefisa) RegisterBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) { 81 pefisaURL := config.Get().URLPefisaRegister 82 83 boleto.Title.BoletoType, boleto.Title.BoletoTypeCode = getBoletoType(boleto) 84 85 exec := NewFlow().From("message://?source=inline", boleto, getRequestPefisa(), tmpl.GetFuncMaps()) 86 exec.To("log://?type=request&url="+pefisaURL, b.log) 87 88 var response string 89 var status int 90 var err error 91 duration := util.Duration(func() { 92 response, status, err = b.sendRequest(exec.GetBody().(string), boleto.Authentication.AuthorizationToken) 93 }) 94 if err != nil { 95 return models.BoletoResponse{}, err 96 } 97 98 metrics.PushTimingMetric("pefisa-register-boleto-time", duration.Seconds()) 99 exec.To("set://?prop=header", map[string]string{"status": strconv.Itoa(status)}) 100 exec.To("set://?prop=body", response) 101 exec.To("log://?type=response&url="+pefisaURL, b.log) 102 103 if status == 200 || status == 401 { 104 exec.To("set://?prop=body", response) 105 } else { 106 dataError := util.ParseJSON(response, new(models.ArrayDataError)).(*models.ArrayDataError) 107 exec.To("set://?prop=body", strings.Replace(util.Stringify(dataError.Error[0]), "\\\"", "", -1)) 108 } 109 110 ch := exec.Choice() 111 ch.When(Header("status").IsEqualTo("200")) 112 ch.To("transform://?format=json", getResponsePefisa(), getAPIResponsePefisa(), tmpl.GetFuncMaps()) 113 ch.To("unmarshall://?format=json", new(models.BoletoResponse)) 114 115 ch.When(Header("status").IsEqualTo("400")) 116 ch.To("transform://?format=json", getResponseErrorPefisaArray(), getAPIResponsePefisa(), tmpl.GetFuncMaps()) 117 ch.To("unmarshall://?format=json", new(models.BoletoResponse)) 118 119 ch.When(Header("status").IsEqualTo("401")) 120 ch.To("transform://?format=json", getResponseErrorPefisa(), getAPIResponsePefisa(), tmpl.GetFuncMaps()) 121 ch.To("unmarshall://?format=json", new(models.BoletoResponse)) 122 123 ch.Otherwise() 124 ch.To("log://?type=response&url="+pefisaURL, b.log).To("apierro://") 125 126 switch t := exec.GetBody().(type) { 127 case *models.BoletoResponse: 128 return *t, nil 129 case error: 130 return models.BoletoResponse{}, t 131 } 132 return models.BoletoResponse{}, models.NewInternalServerError("MP500", "Internal error") 133 } 134 135 func (b bankPefisa) ProcessBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) { 136 errs := b.ValidateBoleto(boleto) 137 138 if len(errs) > 0 { 139 return models.BoletoResponse{Errors: errs}, nil 140 } 141 if token, err := b.GetToken(boleto); err != nil { 142 return models.BoletoResponse{Errors: errs}, err 143 } else { 144 boleto.Authentication.AuthorizationToken = token 145 } 146 147 return b.RegisterBoleto(boleto) 148 149 } 150 151 func (b bankPefisa) ValidateBoleto(boleto *models.BoletoRequest) models.Errors { 152 return models.Errors(b.validate.Assert(boleto)) 153 } 154 155 //GetBankNumber retorna o codigo do banco 156 func (b bankPefisa) GetBankNumber() models.BankNumber { 157 return models.Pefisa 158 } 159 160 func (b bankPefisa) GetBankNameIntegration() string { 161 return "Pefisa" 162 } 163 164 func (b bankPefisa) GetErrorsMap() map[string]int { 165 return nil 166 } 167 168 func (b bankPefisa) sendRequest(body string, token string) (string, int, error) { 169 serviceURL := config.Get().URLPefisaRegister 170 171 h := map[string]string{"Authorization": "Bearer " + token, "Content-Type": "application/json"} 172 return util.Post(serviceURL, body, config.Get().TimeoutRegister, h) 173 } 174 175 func pefisaBoletoTypes() map[string]string { 176 o.Do(func() { 177 m = make(map[string]string) 178 179 m["DM"] = "1" //Duplicata Mercantil 180 m["DS"] = "2" //Duplicata de serviços 181 m["NP"] = "3" //Nota promissória 182 m["SE"] = "4" //Seguro 183 m["CH"] = "10" //Cheque 184 m["OUT"] = "99" //Outros 185 }) 186 return m 187 } 188 189 func getBoletoType(boleto *models.BoletoRequest) (bt string, btc string) { 190 if len(boleto.Title.BoletoType) < 1 { 191 return "DM", "1" 192 } 193 btm := pefisaBoletoTypes() 194 195 if btm[strings.ToUpper(boleto.Title.BoletoType)] == "" { 196 return "DM", "1" 197 } 198 199 return boleto.Title.BoletoType, btm[strings.ToUpper(boleto.Title.BoletoType)] 200 }