main.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "flag"
  6. "fmt"
  7. "io"
  8. "net/http"
  9. "os"
  10. "github.com/google/uuid"
  11. "github.com/joho/godotenv"
  12. )
  13. /*
  14. ======================
  15. Models
  16. ======================
  17. */
  18. type CreateChargeRequest struct {
  19. CorrelationID string `json:"correlationID"`
  20. Value int `json:"value"`
  21. ExpiresIn int `json:"expiresIn"`
  22. Comment string `json:"comment,omitempty"`
  23. }
  24. type CreateChargeResponse struct {
  25. Charge struct {
  26. BRCode string `json:"brCode"`
  27. } `json:"charge"`
  28. }
  29. func main() {
  30. /*
  31. ======================
  32. Load .env
  33. ======================
  34. */
  35. _ = godotenv.Load()
  36. appID := os.Getenv("WOOVI_APPID")
  37. baseURL := os.Getenv("WOOVI_BASE_URL")
  38. if appID == "" || baseURL == "" {
  39. fmt.Fprintln(os.Stderr, "Erro: WOOVI_APPID ou WOOVI_BASE_URL não definidos")
  40. os.Exit(1)
  41. }
  42. /*
  43. ======================
  44. CLI flags
  45. ======================
  46. */
  47. value := flag.Int("value", 0, "Valor em centavos")
  48. expires := flag.Int("expires", 900, "Tempo de expiração em segundos")
  49. correlation := flag.String("correlation", "", "CorrelationID (opcional)")
  50. comment := flag.String("comment", "", "Comentário (opcional)")
  51. flag.Parse()
  52. if *value <= 0 {
  53. fmt.Fprintln(os.Stderr, "Erro: -value é obrigatório e deve ser > 0")
  54. os.Exit(1)
  55. }
  56. /*
  57. ======================
  58. CorrelationID
  59. ======================
  60. */
  61. corrID := *correlation
  62. if corrID == "" {
  63. corrID = uuid.New().String()
  64. }
  65. /*
  66. ======================
  67. Payload
  68. ======================
  69. */
  70. payload := CreateChargeRequest{
  71. CorrelationID: corrID,
  72. Value: *value,
  73. ExpiresIn: *expires,
  74. Comment: *comment,
  75. }
  76. bodyJSON, err := json.Marshal(payload)
  77. if err != nil {
  78. fmt.Fprintln(os.Stderr, "Erro ao gerar JSON:", err)
  79. os.Exit(1)
  80. }
  81. /*
  82. ======================
  83. HTTP Request
  84. ======================
  85. */
  86. req, err := http.NewRequest(
  87. "POST",
  88. baseURL+"/api/v1/charge",
  89. bytes.NewBuffer(bodyJSON),
  90. )
  91. if err != nil {
  92. fmt.Fprintln(os.Stderr, "Erro ao criar request:", err)
  93. os.Exit(1)
  94. }
  95. req.Header.Set("Authorization", appID)
  96. req.Header.Set("Content-Type", "application/json")
  97. client := &http.Client{}
  98. res, err := client.Do(req)
  99. if err != nil {
  100. fmt.Fprintln(os.Stderr, "Erro ao chamar API:", err)
  101. os.Exit(1)
  102. }
  103. defer res.Body.Close()
  104. respBody, _ := io.ReadAll(res.Body)
  105. if res.StatusCode < 200 || res.StatusCode >= 300 {
  106. fmt.Fprintln(os.Stderr, string(respBody))
  107. os.Exit(1)
  108. }
  109. /*
  110. ======================
  111. Parse response
  112. ======================
  113. */
  114. var result CreateChargeResponse
  115. if err := json.Unmarshal(respBody, &result); err != nil {
  116. fmt.Fprintln(os.Stderr, "Erro ao parsear resposta:", err)
  117. os.Exit(1)
  118. }
  119. if result.Charge.BRCode == "" {
  120. fmt.Fprintln(os.Stderr, "Erro: BRCode não retornado")
  121. os.Exit(1)
  122. }
  123. /*
  124. ======================
  125. Output CLI (ONLY URL)
  126. ======================
  127. */
  128. fmt.Println(result.Charge.BRCode)
  129. }