udemy-go-web-2/cmd/api/handlers-api.go

282 lines
6.0 KiB
Go
Raw Normal View History

package main
import (
"encoding/json"
2024-08-04 14:52:03 +00:00
"myapp/internal/cards"
2024-08-12 17:10:27 +00:00
"myapp/internal/models"
"net/http"
2024-08-04 14:52:03 +00:00
"strconv"
"github.com/go-chi/chi/v5"
2024-08-12 17:10:27 +00:00
"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"`
2024-08-12 17:10:27 +00:00
CardBrand string `json:"card_brand"`
ExpiryMonth int `json:"expiry_month"`
ExpiryYear int `json:"expiry_year"`
LastFour string `json:"last_four"`
Plan string `json:"plan"`
2024-08-12 17:10:27 +00:00
ProductID string `json:"product_id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
type jsonResponse struct {
OK bool `json:"ok"`
2024-08-04 14:52:03 +00:00
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) {
2024-08-04 14:52:03 +00:00
var payload stripePayload
err := json.NewDecoder(r.Body).Decode(&payload)
if err != nil {
app.errorLog.Println(err)
return // TODO: return a valid json
}
2024-08-04 14:52:03 +00:00
amount, err := strconv.Atoi(payload.Amount)
if err != nil {
app.errorLog.Println(err)
2024-08-04 14:52:03 +00:00
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
}
2024-08-04 14:52:03 +00:00
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,
}
2024-08-12 17:10:27 +00:00
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)
2024-08-12 17:10:27 +00:00
okay = false
txnMsg = msg
}
2024-08-12 17:10:27 +00:00
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)
}
2024-08-12 17:10:27 +00:00
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,
2024-08-12 17:10:27 +00:00
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)
}
2024-08-12 17:10:27 +00:00
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 {
2024-08-13 12:12:40 +00:00
app.errorLog.Println(err)
app.badRequest(w, r, err)
return
}
2024-08-13 11:47:56 +00:00
// get the user from the db by email, send error if invalid email
user, err := app.DB.GetUserByEmail(userInput.Email)
if err != nil {
2024-08-13 12:12:40 +00:00
app.errorLog.Println(err)
2024-08-13 11:47:56 +00:00
app.invalidCredentials(w)
return
}
// validate the password, send error if invalid password
2024-08-13 11:58:33 +00:00
validPassword, err := app.passwordMatches(user.Password, userInput.Password)
if err != nil {
2024-08-13 12:12:40 +00:00
app.errorLog.Println(err)
2024-08-13 11:58:33 +00:00
app.invalidCredentials(w)
return
}
if !validPassword {
app.invalidCredentials(w)
return
}
2024-08-13 11:47:56 +00:00
// generate the token
// send response
var payload struct {
Error bool `json:"error"`
Message string `json:"message"`
}
payload.Error = false
payload.Message = "Success!"
2024-08-13 11:34:53 +00:00
_ = app.writeJSON(w, http.StatusOK, payload)
}