diff --git a/cmd/api/handlers-api.go b/cmd/api/handlers-api.go index 1c575a5..39fbb4c 100644 --- a/cmd/api/handlers-api.go +++ b/cmd/api/handlers-api.go @@ -3,10 +3,12 @@ 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 { @@ -14,8 +16,14 @@ type stripePayload struct { 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 { @@ -105,30 +113,77 @@ func (app *application) CreateCustomerAndSubscribeToPlan(w http.ResponseWriter, 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) - return + okay = false + txnMsg = msg } - subscriptionID, err := card.SubscribeToPlan( - stripeCustomer, - data.Plan, - data.Email, - data.LastFour, - "", - ) - if err != nil { - app.errorLog.Println(err) - return + 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) } - app.infoLog.Println("subscription id is", subscriptionID) + 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 + } + } - okay := true resp := jsonResponse{ OK: okay, - Message: msg, + Message: txnMsg, } out, err := json.MarshalIndent(resp, "", " ") @@ -140,3 +195,38 @@ func (app *application) CreateCustomerAndSubscribeToPlan(w http.ResponseWriter, 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 +} diff --git a/cmd/web/templates/bronze-plan.page.gohtml b/cmd/web/templates/bronze-plan.page.gohtml index 8069ac6..b27f159 100644 --- a/cmd/web/templates/bronze-plan.page.gohtml +++ b/cmd/web/templates/bronze-plan.page.gohtml @@ -14,7 +14,7 @@ Bronze Plan class="d-blick needs-validation charge-form" autocomplete="off" novalidate=""> - +

{{$widget.Description}}


diff --git a/internal/cards/cards.go b/internal/cards/cards.go index e2bc9d3..412314b 100644 --- a/internal/cards/cards.go +++ b/internal/cards/cards.go @@ -76,7 +76,7 @@ func (c *Card) RetrievePaymentIntent(id string) (*stripe.PaymentIntent, error) { func (c *Card) SubscribeToPlan( cust *stripe.Customer, plan, email, last4, cardType string, -) (string, error) { +) (*stripe.Subscription, error) { stripeCustomerID := cust.ID items := []*stripe.SubscriptionItemsParams{ {Plan: stripe.String(plan)}, @@ -92,9 +92,9 @@ func (c *Card) SubscribeToPlan( params.AddExpand("latest_invoice.payment_intent") subscription, err := subscription.New(params) if err != nil { - return "", err + return nil, err } - return subscription.ID, nil + return subscription, nil } func (c *Card) CreateCustomer(pm, email string) (*stripe.Customer, string, error) { diff --git a/static/js/stripe-plan.js b/static/js/stripe-plan.js index faa7c21..c99d62c 100644 --- a/static/js/stripe-plan.js +++ b/static/js/stripe-plan.js @@ -39,10 +39,17 @@ function stripePaymentMethodHandler(result, plan_id, api) { } else { // create a customer and subscribe to plan let payload = { + product_id: document.getElementById("product_id").value, plan: plan_id, payment_method: result.paymentMethod.id, email: document.getElementById("cardholder-email").value, last_four: result.paymentMethod.card.last4, + card_brand: result.paymentMethod.card.brand, + expiry_month: result.paymentMethod.card.exp_month, + expiry_year: result.paymentMethod.card.exp_year, + first_name: document.getElementById("first-name").value, + last_name: document.getElementById("last-name").value, + amount: document.getElementById("amount").value, }; const requestOptions = {