github.com/mundipagg/boleto-api@v0.0.0-20230620145841-3f9ec742599f/models/boleto.go (about) 1 package models 2 3 import ( 4 "time" 5 6 "github.com/mundipagg/boleto-api/util" 7 "go.mongodb.org/mongo-driver/bson/primitive" 8 9 "github.com/mundipagg/boleto-api/config" 10 11 "github.com/PMoneda/flow" 12 "github.com/google/uuid" 13 14 "fmt" 15 16 "encoding/json" 17 "strconv" 18 ) 19 20 // BoletoRequest entidade de entrada para o boleto 21 type BoletoRequest struct { 22 Authentication Authentication `json:"authentication"` 23 Agreement Agreement `json:"agreement"` 24 Title Title `json:"title"` 25 Recipient Recipient `json:"recipient"` 26 PayeeGuarantor *PayeeGuarantor `json:"payeeGuarantor,omitempty"` 27 Buyer Buyer `json:"buyer"` 28 BankNumber BankNumber `json:"bankNumber"` 29 RequestKey string `json:"requestKey,omitempty"` 30 } 31 32 // BoletoResponse entidade de saída para o boleto 33 type BoletoResponse struct { 34 StatusCode int `json:"-"` 35 Errors Errors `json:"errors,omitempty"` 36 ID string `json:"id,omitempty"` 37 DigitableLine string `json:"digitableLine,omitempty"` 38 BarCodeNumber string `json:"barCodeNumber,omitempty"` 39 OurNumber string `json:"ourNumber,omitempty"` 40 Links []Link `json:"links,omitempty"` 41 } 42 43 //Link é um tipo padrão no restfull para satisfazer o HATEOAS 44 type Link struct { 45 Href string `json:"href,omitempty"` 46 Rel string `json:"rel,omitempty"` 47 Method string `json:"method,omitempty"` 48 } 49 50 // BoletoView contem as informações que serão preenchidas no boleto 51 type BoletoView struct { 52 ID primitive.ObjectID `bson:"_id,omitempty"` 53 UID string `json:"uid,omitempty"` 54 SecretKey string `json:"secretkey,omitempty"` 55 PublicKey string `json:"publickey,omitempty"` 56 Format string `json:"format,omitempty"` 57 Boleto BoletoRequest `json:"boleto,omitempty"` 58 BankID BankNumber `json:"bankId,omitempty"` 59 CreateDate time.Time `json:"createDate,omitempty"` 60 BankNumber string `json:"bankNumber,omitempty"` 61 DigitableLine string `json:"digitableLine,omitempty"` 62 OurNumber string `json:"ourNumber,omitempty"` 63 Barcode string `json:"barcode,omitempty"` 64 Barcode64 string `json:"barcode64,omitempty"` 65 Links []Link `json:"links,omitempty"` 66 } 67 68 // NewBoletoView cria um novo objeto view de boleto a partir de um boleto request, codigo de barras e linha digitavel 69 func NewBoletoView(boleto BoletoRequest, response BoletoResponse, bankName string) BoletoView { 70 boleto.Authentication = Authentication{} 71 uid, _ := uuid.NewUUID() 72 id := primitive.NewObjectID() 73 view := BoletoView{ 74 ID: id, 75 UID: uid.String(), 76 SecretKey: uid.String(), 77 BankID: boleto.BankNumber, 78 Boleto: boleto, 79 Barcode: response.BarCodeNumber, 80 DigitableLine: response.DigitableLine, 81 OurNumber: response.OurNumber, 82 BankNumber: boleto.BankNumber.GetBoletoBankNumberAndDigit(), 83 CreateDate: time.Now(), 84 } 85 view.GeneratePublicKey() 86 view.Links = view.CreateLinks() 87 if len(response.Links) > 0 && bankName == "BradescoShopFacil" { 88 view.Links = append(view.Links, response.Links[0]) 89 } 90 return view 91 } 92 93 //EncodeURL tranforma o boleto view na forma que será escrito na url 94 func (b *BoletoView) EncodeURL(format string) string { 95 idBson := b.ID.Hex() 96 url := fmt.Sprintf("%s?fmt=%s&id=%s&pk=%s", config.Get().AppURL, format, idBson, b.PublicKey) 97 98 return url 99 } 100 101 //CreateLinks cria a lista de links com os formatos suportados 102 func (b *BoletoView) CreateLinks() []Link { 103 links := make([]Link, 0, 3) 104 for _, f := range []string{"html", "pdf"} { 105 links = append(links, Link{Href: b.EncodeURL(f), Rel: f, Method: "GET"}) 106 } 107 return links 108 } 109 110 //ToJSON tranforma o boleto view em json 111 func (b BoletoView) ToJSON() string { 112 json, _ := json.Marshal(b) 113 return string(json) 114 } 115 116 //ToMinifyJSON converte um model BoletoView para um JSON/STRING 117 func (b BoletoView) ToMinifyJSON() string { 118 return util.MinifyString(b.ToJSON(), "application/json") 119 } 120 121 //GeneratePublicKey Gera a chave pública criptografada para geração da URL do boleto 122 func (b *BoletoView) GeneratePublicKey() { 123 s := b.SecretKey + b.CreateDate.String() + b.Barcode + b.Boleto.Buyer.Document.Number + strconv.FormatUint(b.Boleto.Title.AmountInCents, 10) 124 b.PublicKey = util.Sha256(s, "hex") 125 } 126 127 // BankNumber número de identificação do banco 128 type BankNumber int 129 130 // IsBankNumberValid verifica se o banco enviado existe 131 func (b BankNumber) IsBankNumberValid() bool { 132 switch b { 133 case BancoDoBrasil, Itau, Santander, Caixa, Bradesco, Citibank, Pefisa, Stone, JPMorgan: 134 return true 135 default: 136 return false 137 } 138 } 139 140 //GetBoletoBankNumberAndDigit Retorna o numero da conta do banco do boleto 141 func (b BankNumber) GetBoletoBankNumberAndDigit() string { 142 switch b { 143 case BancoDoBrasil: 144 return "001-9" 145 case Caixa: 146 return "104-0" 147 case Citibank: 148 return "745-5" 149 case Santander: 150 return "033-7" 151 case Itau: 152 return "341-7" 153 case Bradesco: 154 return "237-2" 155 case Pefisa: 156 return "174" 157 case Stone: 158 return "197-1" 159 case JPMorgan: 160 return "376" 161 default: 162 return "" 163 } 164 } 165 166 const ( 167 // BancoDoBrasil constante do Banco do Brasil 168 BancoDoBrasil = 1 169 170 // Santander constante do Santander 171 Santander = 33 172 173 // Itau constante do Itau 174 Itau = 341 175 176 //Bradesco constante do Bradesco 177 Bradesco = 237 178 // Caixa constante do Caixa 179 Caixa = 104 180 181 // Citibank constante do Citi 182 Citibank = 745 183 184 //Real constante do REal 185 Real = 9 186 187 // Pefisa constante do Pefisa 188 Pefisa = 174 189 190 // Stone constante do Stone 191 Stone = 197 192 193 JPMorgan = 376 194 ) 195 196 // BoletoErrorConector é um connector flow para criar um objeto de erro 197 func BoletoErrorConector(e *flow.ExchangeMessage, u flow.URI, params ...interface{}) error { 198 b := "Erro interno" 199 switch t := e.GetBody().(type) { 200 case error: 201 b = t.Error() 202 case string: 203 b = t 204 case *BoletoResponse: 205 if len(t.Errors) > 0 { 206 return nil 207 } 208 } 209 210 st, err := strconv.Atoi(e.GetHeader("status")) 211 if err != nil { 212 st = 0 213 } 214 resp := BoletoResponse{} 215 resp.Errors = make(Errors, 0, 0) 216 resp.Errors.Append("MP"+e.GetHeader("status"), b) 217 resp.StatusCode = st 218 e.SetBody(resp) 219 return nil 220 } 221 222 //HasErrors verify if Response has any error 223 func (b *BoletoResponse) HasErrors() bool { 224 return b.Errors != nil && len(b.Errors) > 0 225 } 226 227 //HasPayeeGuarantor verify if PayeeGuarantor is not nil 228 func (b BoletoRequest) HasPayeeGuarantor() bool { 229 return b.PayeeGuarantor != nil 230 } 231 232 //MaskBoletoRequest Retorna um BoletoRequest com os campos sensiveis mascarados 233 func (b BoletoRequest) MaskBoletoRequest() BoletoRequest { 234 return BoletoRequest{ 235 Authentication: b.Authentication.maskAuthenticationNode(), 236 Agreement: b.Agreement, 237 Title: b.Title, 238 Recipient: b.Recipient, 239 PayeeGuarantor: b.PayeeGuarantor, 240 Buyer: b.Buyer, 241 BankNumber: b.BankNumber, 242 RequestKey: b.RequestKey, 243 } 244 } 245 246 //GetBoletoResponseError Retorna um BoletoResponse com um erro específico 247 func GetBoletoResponseError(code, message string) BoletoResponse { 248 resp := BoletoResponse{} 249 resp.Errors = make(Errors, 0, 0) 250 resp.Errors.Append(code, message) 251 return resp 252 }