package main import ( "encoding/json" "myapp/internal/cards" "myapp/internal/models" "net/http" "strconv" "github.com/go-chi/chi/v5" "github.com/stripe/stripe-go/v79" ) type stripePayload struct { Currency string `json:"currency"` Amount string `json:"amount"` PaymentMethod string `json:"payment_method"` Email string `json:"email"` CardBrand string `json:"card_brand"` ExpiryMonth int `json:"expiry_month"` ExpiryYear int `json:"expiry_year"` LastFour string `json:"last_four"` Plan string `json:"plan"` ProductID string `json:"product_id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` } type jsonResponse struct { OK bool `json:"ok"` Message string `json:"message,omitempty"` Content string `json:"content,omitempty"` ID int `json:"id,omitempty"` } func (app *application) GetPaymentIntent(w http.ResponseWriter, r *http.Request) { var payload stripePayload err := json.NewDecoder(r.Body).Decode(&payload) if err != nil { app.errorLog.Println(err) return // TODO: return a valid json } amount, err := strconv.Atoi(payload.Amount) if err != nil { app.errorLog.Println(err) return // TODO: return a valid json } card := cards.Card{ Secret: app.config.stripe.secret, Key: app.config.stripe.key, Currency: payload.Currency, } pi, msg, err := card.Charge(payload.Currency, amount) if err != nil { j := jsonResponse{ OK: false, Message: msg, Content: "", } out, err := json.MarshalIndent(j, "", " ") if err != nil { app.errorLog.Println(err) } w.Header().Set("Content-Type", "application/json") w.Write(out) return } out, err := json.MarshalIndent(pi, "", " ") if err != nil { app.errorLog.Println(err) return // TODO: return a valid json } w.Header().Set("Content-Type", "application/json") w.Write(out) } func (app *application) GetWidgetByID(w http.ResponseWriter, r *http.Request) { id := chi.URLParam(r, "id") widgetID, _ := strconv.Atoi(id) widget, err := app.DB.GetWidget(widgetID) if err != nil { app.errorLog.Println(err) } out, err := json.MarshalIndent(widget, "", " ") if err != nil { app.errorLog.Println(err) } w.Header().Set("Content-Type", "application/json") w.Write(out) } func (app *application) CreateCustomerAndSubscribeToPlan(w http.ResponseWriter, r *http.Request) { var data stripePayload err := json.NewDecoder(r.Body).Decode(&data) if err != nil { app.errorLog.Println(err) return } app.infoLog.Println(data.Email, data.LastFour, data.PaymentMethod, data.Plan) card := cards.Card{ Secret: app.config.stripe.secret, Key: app.config.stripe.key, Currency: data.Currency, } okay := true var subscription *stripe.Subscription txnMsg := "Transaction successful" stripeCustomer, msg, err := card.CreateCustomer(data.PaymentMethod, data.Email) if err != nil { app.errorLog.Println(err) okay = false txnMsg = msg } if okay { subscription, err = card.SubscribeToPlan( stripeCustomer, data.Plan, data.Email, data.LastFour, "", ) if err != nil { app.errorLog.Println(err) okay = false txnMsg = "Error subscribing customer" } app.infoLog.Println("subscription id is", subscription.ID) } if okay { productID, _ := strconv.Atoi(data.ProductID) customerID, err := app.SaveCustomer(data.FirstName, data.LastName, data.Email) if err != nil { app.errorLog.Println(err) return } // create a new txn amount, _ := strconv.Atoi(data.Amount) txn := models.Transaction{ Amount: amount, Currency: "eur", LastFour: data.LastFour, ExpiryMonth: data.ExpiryMonth, ExpiryYear: data.ExpiryYear, TransactionStatusID: 2, } txnID, err := app.SaveTransaction(txn) if err != nil { app.errorLog.Println(err) return } // create order order := models.Order{ WidgetID: productID, TransactionID: txnID, CustomerID: customerID, StatusID: 1, Quantity: 1, Amount: amount, } _, err = app.SaveOrder(order) if err != nil { app.errorLog.Println(err) return } } resp := jsonResponse{ OK: okay, Message: txnMsg, } out, err := json.MarshalIndent(resp, "", " ") if err != nil { app.errorLog.Println(err) return } w.Header().Set("Content-Type", "application/json") w.Write(out) } func (app *application) SaveCustomer(firstName, lastName, email string) (int, error) { customer := models.Customer{ FirstName: firstName, LastName: lastName, Email: email, } id, err := app.DB.InsertCustomer(customer) if err != nil { return 0, err } return id, nil } func (app *application) SaveTransaction(txn models.Transaction) (int, error) { txnID, err := app.DB.InsertTransaction(txn) if err != nil { app.errorLog.Println(err) return 0, err } return txnID, nil } func (app *application) SaveOrder(order models.Order) (int, error) { id, err := app.DB.InsertOrder(order) if err != nil { app.errorLog.Println(err) return 0, err } return id, nil } func (app *application) CreateAuthToken(w http.ResponseWriter, r *http.Request) { var userInput struct { Email string `json:"email"` Password string `json:"password"` } err := app.readJSON(w, r, &userInput) if err != nil { app.badRequest(w, r, err) return } var payload struct { Error bool `json:"error"` Message string `json:"message"` } payload.Error = false payload.Message = "Success!" out, _ := json.MarshalIndent(payload, "", "\t") w.Header().Set("Content-Type", "application/json") w.Write(out) }