github.com/mundipagg/boleto-api@v0.0.0-20230620145841-3f9ec742599f/caixa/caixa.go (about) 1 package caixa 2 3 import ( 4 "fmt" 5 "strings" 6 "sync" 7 8 "github.com/mundipagg/boleto-api/metrics" 9 10 "github.com/PMoneda/flow" 11 12 "github.com/mundipagg/boleto-api/config" 13 "github.com/mundipagg/boleto-api/log" 14 "github.com/mundipagg/boleto-api/models" 15 "github.com/mundipagg/boleto-api/tmpl" 16 "github.com/mundipagg/boleto-api/util" 17 "github.com/mundipagg/boleto-api/validations" 18 ) 19 20 var o = &sync.Once{} 21 var m map[string]string 22 23 type bankCaixa struct { 24 validate *models.Validator 25 log *log.Log 26 } 27 28 func New() bankCaixa { 29 b := bankCaixa{ 30 validate: models.NewValidator(), 31 log: log.CreateLog(), 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(validations.ValidatePayeeGuarantorDocumentNumber) 38 b.validate.Push(validations.ValidatePayeeGuarantorName) 39 b.validate.Push(caixaValidateAgency) 40 b.validate.Push(validadeOurNumber) 41 b.validate.Push(caixaValidateBoletoType) 42 b.validate.Push(validations.ValidateInterest) 43 b.validate.Push(validations.ValidateFine) 44 return b 45 } 46 47 //Log retorna a referencia do log 48 func (b bankCaixa) Log() *log.Log { 49 return b.log 50 } 51 func (b bankCaixa) RegisterBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) { 52 53 boleto.Title.BoletoType, boleto.Title.BoletoTypeCode = getBoletoType(boleto) 54 55 r := flow.NewFlow() 56 urlCaixa := config.Get().URLCaixaRegisterBoleto 57 from := getResponseCaixa() 58 to := getAPIResponseCaixa() 59 60 bod := r.From("message://?source=inline", boleto, getRequestCaixa(), tmpl.GetFuncMaps()) 61 bod = bod.To("log://?type=request&format=xml&url="+urlCaixa, b.log) 62 duration := util.Duration(func() { 63 bod = bod.To(urlCaixa, map[string]string{"method": "POST", "insecureSkipVerify": "true", "timeout": config.Get().TimeoutDefault}) 64 }) 65 metrics.PushTimingMetric("caixa-register-time", duration.Seconds()) 66 bod = bod.To("log://?type=response&format=xml&url="+urlCaixa, b.log) 67 ch := bod.Choice() 68 ch = ch.When(flow.Header("status").IsEqualTo("200")) 69 ch = ch.To("transform://?format=xml", from, to, tmpl.GetFuncMaps()) 70 ch = ch.Otherwise() 71 ch = ch.To("log://?type=response&url="+urlCaixa, b.log).To("apierro://") 72 73 switch t := bod.GetBody().(type) { 74 case string: 75 response := util.ParseJSON(t, new(models.BoletoResponse)).(*models.BoletoResponse) 76 return *response, nil 77 case models.BoletoResponse: 78 return t, nil 79 } 80 return models.BoletoResponse{}, models.NewInternalServerError("MP500", "Internal error") 81 } 82 func (b bankCaixa) ProcessBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) { 83 errs := b.ValidateBoleto(boleto) 84 if len(errs) > 0 { 85 return models.BoletoResponse{Errors: errs}, nil 86 } 87 88 boleto.Title.OurNumber = b.FormatOurNumber(boleto.Title.OurNumber) 89 90 checkSum := b.getCheckSumCode(*boleto) 91 92 boleto.Authentication.AuthorizationToken = b.getAuthToken(checkSum) 93 return b.RegisterBoleto(boleto) 94 } 95 96 func (b bankCaixa) ValidateBoleto(boleto *models.BoletoRequest) models.Errors { 97 return models.Errors(b.validate.Assert(boleto)) 98 } 99 100 func (b bankCaixa) FormatOurNumber(ourNumber uint) uint { 101 102 if ourNumber != 0 { 103 ourNumberFormatted := 14000000000000000 + ourNumber 104 105 return ourNumberFormatted 106 } 107 108 return ourNumber 109 } 110 111 //getCheckSumCode Código do Cedente (7 posições) + Nosso Número (17 posições) + Data de Vencimento (DDMMAAAA) + Valor (15 posições) + CPF/CNPJ (14 Posições) 112 func (b bankCaixa) getCheckSumCode(boleto models.BoletoRequest) string { 113 114 return fmt.Sprintf("%07d%017d%s%015d%014s", 115 boleto.Agreement.AgreementNumber, 116 boleto.Title.OurNumber, 117 boleto.Title.ExpireDateTime.Format("02012006"), 118 boleto.Title.AmountInCents, 119 boleto.Recipient.Document.Number) 120 } 121 122 func (b bankCaixa) getAuthToken(info string) string { 123 return util.Sha256(info, "base64") 124 } 125 126 //GetBankNumber retorna o codigo do banco 127 func (b bankCaixa) GetBankNumber() models.BankNumber { 128 return models.Caixa 129 } 130 131 func (b bankCaixa) GetBankNameIntegration() string { 132 return "Caixa" 133 } 134 135 func (b bankCaixa) GetErrorsMap() map[string]int { 136 return nil 137 } 138 139 func caixaBoletoTypes() map[string]string { 140 o.Do(func() { 141 m = make(map[string]string) 142 143 m["OUT"] = "99" //Duplicata Mercantil p/ Indicação 144 }) 145 return m 146 } 147 148 func getBoletoType(boleto *models.BoletoRequest) (bt string, btc string) { 149 if len(boleto.Title.BoletoType) < 1 { 150 return "OUT", "99" 151 } 152 btm := caixaBoletoTypes() 153 154 if btm[strings.ToUpper(boleto.Title.BoletoType)] == "" { 155 return "OUT", "99" 156 } 157 158 return boleto.Title.BoletoType, btm[strings.ToUpper(boleto.Title.BoletoType)] 159 }