Saving transaction & customer info

This commit is contained in:
vinchent 2024-08-12 19:10:27 +02:00
parent c3897d47bc
commit 5ab6ad85f7
4 changed files with 115 additions and 18 deletions

View File

@ -3,10 +3,12 @@ package main
import ( import (
"encoding/json" "encoding/json"
"myapp/internal/cards" "myapp/internal/cards"
"myapp/internal/models"
"net/http" "net/http"
"strconv" "strconv"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
"github.com/stripe/stripe-go/v79"
) )
type stripePayload struct { type stripePayload struct {
@ -14,8 +16,14 @@ type stripePayload struct {
Amount string `json:"amount"` Amount string `json:"amount"`
PaymentMethod string `json:"payment_method"` PaymentMethod string `json:"payment_method"`
Email string `json:"email"` Email string `json:"email"`
CardBrand string `json:"card_brand"`
ExpiryMonth int `json:"expiry_month"`
ExpiryYear int `json:"expiry_year"`
LastFour string `json:"last_four"` LastFour string `json:"last_four"`
Plan string `json:"plan"` Plan string `json:"plan"`
ProductID string `json:"product_id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
} }
type jsonResponse struct { type jsonResponse struct {
@ -105,30 +113,77 @@ func (app *application) CreateCustomerAndSubscribeToPlan(w http.ResponseWriter,
Currency: data.Currency, Currency: data.Currency,
} }
okay := true
var subscription *stripe.Subscription
txnMsg := "Transaction successful"
stripeCustomer, msg, err := card.CreateCustomer(data.PaymentMethod, data.Email) stripeCustomer, msg, err := card.CreateCustomer(data.PaymentMethod, data.Email)
if err != nil { if err != nil {
app.errorLog.Println(err) app.errorLog.Println(err)
return okay = false
txnMsg = msg
} }
subscriptionID, err := card.SubscribeToPlan( if okay {
stripeCustomer, subscription, err = card.SubscribeToPlan(
data.Plan, stripeCustomer,
data.Email, data.Plan,
data.LastFour, data.Email,
"", data.LastFour,
) "",
if err != nil { )
app.errorLog.Println(err) if err != nil {
return 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{ resp := jsonResponse{
OK: okay, OK: okay,
Message: msg, Message: txnMsg,
} }
out, err := json.MarshalIndent(resp, "", " ") out, err := json.MarshalIndent(resp, "", " ")
@ -140,3 +195,38 @@ func (app *application) CreateCustomerAndSubscribeToPlan(w http.ResponseWriter,
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Write(out) 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
}

View File

@ -14,7 +14,7 @@ Bronze Plan
class="d-blick needs-validation charge-form" class="d-blick needs-validation charge-form"
autocomplete="off" autocomplete="off"
novalidate=""> novalidate="">
<input type="hidden" name="product_id" value="{{$widget.ID}}"> <input type="hidden" id="product_id" name="product_id" value="{{$widget.ID}}">
<input type="hidden" id="amount" name="amount" value="{{$widget.Price}}"> <input type="hidden" id="amount" name="amount" value="{{$widget.Price}}">
<p class="mt-2 mb-3 text-center">{{$widget.Description}}</p> <p class="mt-2 mb-3 text-center">{{$widget.Description}}</p>
<hr> <hr>

View File

@ -76,7 +76,7 @@ func (c *Card) RetrievePaymentIntent(id string) (*stripe.PaymentIntent, error) {
func (c *Card) SubscribeToPlan( func (c *Card) SubscribeToPlan(
cust *stripe.Customer, cust *stripe.Customer,
plan, email, last4, cardType string, plan, email, last4, cardType string,
) (string, error) { ) (*stripe.Subscription, error) {
stripeCustomerID := cust.ID stripeCustomerID := cust.ID
items := []*stripe.SubscriptionItemsParams{ items := []*stripe.SubscriptionItemsParams{
{Plan: stripe.String(plan)}, {Plan: stripe.String(plan)},
@ -92,9 +92,9 @@ func (c *Card) SubscribeToPlan(
params.AddExpand("latest_invoice.payment_intent") params.AddExpand("latest_invoice.payment_intent")
subscription, err := subscription.New(params) subscription, err := subscription.New(params)
if err != nil { 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) { func (c *Card) CreateCustomer(pm, email string) (*stripe.Customer, string, error) {

View File

@ -39,10 +39,17 @@ function stripePaymentMethodHandler(result, plan_id, api) {
} else { } else {
// create a customer and subscribe to plan // create a customer and subscribe to plan
let payload = { let payload = {
product_id: document.getElementById("product_id").value,
plan: plan_id, plan: plan_id,
payment_method: result.paymentMethod.id, payment_method: result.paymentMethod.id,
email: document.getElementById("cardholder-email").value, email: document.getElementById("cardholder-email").value,
last_four: result.paymentMethod.card.last4, 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 = { const requestOptions = {