Saving more details, redirecting and simplifying the succeed handler
This commit is contained in:
		@ -21,14 +21,29 @@ func (app *application) VirtualTerminal(w http.ResponseWriter, r *http.Request)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (app *application) PaymentSucceeded(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
type TransactionData struct {
 | 
			
		||||
	FirstName       string
 | 
			
		||||
	LastName        string
 | 
			
		||||
	Email           string
 | 
			
		||||
	PaymentIntentID string
 | 
			
		||||
	PaymentMethodID string
 | 
			
		||||
	PaymentAmount   int
 | 
			
		||||
	PaymentCurrency string
 | 
			
		||||
	LastFour        string
 | 
			
		||||
	ExpiryMonth     int
 | 
			
		||||
	ExpiryYear      int
 | 
			
		||||
	BankReturnCode  string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (app *application) GetTransactionData(r *http.Request) (TransactionData, error) {
 | 
			
		||||
	var txnData TransactionData
 | 
			
		||||
 | 
			
		||||
	err := r.ParseForm()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return
 | 
			
		||||
		return txnData, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// read posted data
 | 
			
		||||
	firstName := r.Form.Get("first_name")
 | 
			
		||||
	lastName := r.Form.Get("last_name")
 | 
			
		||||
	email := r.Form.Get("cardholder_email")
 | 
			
		||||
@ -36,7 +51,9 @@ func (app *application) PaymentSucceeded(w http.ResponseWriter, r *http.Request)
 | 
			
		||||
	paymentMethod := r.Form.Get("payment_method")
 | 
			
		||||
	paymentAmount := r.Form.Get("payment_amount")
 | 
			
		||||
	paymentCurrency := r.Form.Get("payment_currency")
 | 
			
		||||
	widgetID, _ := strconv.Atoi(r.Form.Get("product_id"))
 | 
			
		||||
	amount, _ := strconv.Atoi(paymentAmount)
 | 
			
		||||
 | 
			
		||||
	// TODO: validation of the data
 | 
			
		||||
 | 
			
		||||
	card := cards.Card{
 | 
			
		||||
		Secret: app.config.stripe.secret,
 | 
			
		||||
@ -46,34 +63,67 @@ func (app *application) PaymentSucceeded(w http.ResponseWriter, r *http.Request)
 | 
			
		||||
	pi, err := card.RetrievePaymentIntent(paymentIntent)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return
 | 
			
		||||
		return txnData, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pm, err := card.GetPaymentMethod(paymentMethod)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return
 | 
			
		||||
		return txnData, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lastFour := pm.Card.Last4
 | 
			
		||||
	expiryMonth := pm.Card.ExpMonth
 | 
			
		||||
	expiryYear := pm.Card.ExpYear
 | 
			
		||||
 | 
			
		||||
	customerID, err := app.SaveCustomer(firstName, lastName, email)
 | 
			
		||||
	txnData = TransactionData{
 | 
			
		||||
		FirstName:       firstName,
 | 
			
		||||
		LastName:        lastName,
 | 
			
		||||
		Email:           email,
 | 
			
		||||
		PaymentIntentID: paymentIntent,
 | 
			
		||||
		PaymentMethodID: paymentMethod,
 | 
			
		||||
		PaymentAmount:   amount,
 | 
			
		||||
		PaymentCurrency: paymentCurrency,
 | 
			
		||||
		LastFour:        lastFour,
 | 
			
		||||
		ExpiryMonth:     int(expiryMonth),
 | 
			
		||||
		ExpiryYear:      int(expiryYear),
 | 
			
		||||
		BankReturnCode:  pi.LatestCharge.ID,
 | 
			
		||||
	}
 | 
			
		||||
	return txnData, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (app *application) PaymentSucceeded(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	// read posted data
 | 
			
		||||
	err := r.ParseForm()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	widgetID, _ := strconv.Atoi(r.Form.Get("product_id"))
 | 
			
		||||
 | 
			
		||||
	txnData, err := app.GetTransactionData(r)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	customerID, err := app.SaveCustomer(txnData.FirstName, txnData.LastName, txnData.Email)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	app.infoLog.Printf("custumer id: %d", customerID)
 | 
			
		||||
 | 
			
		||||
	amount, _ := strconv.Atoi(paymentAmount)
 | 
			
		||||
	transaction := models.Transaction{
 | 
			
		||||
		Amount:              amount,
 | 
			
		||||
		Currency:            paymentCurrency,
 | 
			
		||||
		LastFour:            lastFour,
 | 
			
		||||
		ExpiryMonth:         int(expiryMonth),
 | 
			
		||||
		ExpiryYear:          int(expiryYear),
 | 
			
		||||
		BankReturnCode:      pi.LatestCharge.ID,
 | 
			
		||||
		Amount:              txnData.PaymentAmount,
 | 
			
		||||
		Currency:            txnData.PaymentCurrency,
 | 
			
		||||
		LastFour:            txnData.LastFour,
 | 
			
		||||
		ExpiryMonth:         txnData.ExpiryMonth,
 | 
			
		||||
		ExpiryYear:          txnData.ExpiryYear,
 | 
			
		||||
		PaymentIntent:       txnData.PaymentIntentID,
 | 
			
		||||
		PaymentMethod:       txnData.PaymentMethodID,
 | 
			
		||||
		BankReturnCode:      txnData.BankReturnCode,
 | 
			
		||||
		TransactionStatusID: 2, // TODO: use an enum
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -90,7 +140,7 @@ func (app *application) PaymentSucceeded(w http.ResponseWriter, r *http.Request)
 | 
			
		||||
		CustomerID:    customerID,
 | 
			
		||||
		StatusID:      1,
 | 
			
		||||
		Quantity:      1,
 | 
			
		||||
		Amount:        amount,
 | 
			
		||||
		Amount:        txnData.PaymentAmount,
 | 
			
		||||
	}
 | 
			
		||||
	orderID, err := app.SaveOrder(order)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@ -99,22 +149,16 @@ func (app *application) PaymentSucceeded(w http.ResponseWriter, r *http.Request)
 | 
			
		||||
	}
 | 
			
		||||
	app.infoLog.Printf("order id: %d", orderID)
 | 
			
		||||
 | 
			
		||||
	app.Session.Put(r.Context(), "txn", txnData)
 | 
			
		||||
 | 
			
		||||
	http.Redirect(w, r, "/receipt", http.StatusSeeOther)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (app *application) Receipt(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	txn := app.Session.Pop(r.Context(), "txn").(TransactionData)
 | 
			
		||||
	data := make(map[string]interface{})
 | 
			
		||||
	data["email"] = email
 | 
			
		||||
	data["pi"] = paymentIntent
 | 
			
		||||
	data["pm"] = paymentMethod
 | 
			
		||||
	data["pa"] = paymentAmount
 | 
			
		||||
	data["pc"] = paymentCurrency
 | 
			
		||||
	data["last_four"] = lastFour
 | 
			
		||||
	data["expiry_month"] = expiryMonth
 | 
			
		||||
	data["expiry_year"] = expiryYear
 | 
			
		||||
	data["bank_return_code"] = pi.LatestCharge.ID
 | 
			
		||||
	data["first_name"] = firstName
 | 
			
		||||
	data["last_name"] = lastName
 | 
			
		||||
 | 
			
		||||
	// should write this data to session, and then redirect user to the new page
 | 
			
		||||
 | 
			
		||||
	if err := app.renderTemplate(w, r, "succeeded", &templateData{
 | 
			
		||||
	data["txn"] = txn
 | 
			
		||||
	if err := app.renderTemplate(w, r, "receipt", &templateData{
 | 
			
		||||
		Data: data,
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/gob"
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"html/template"
 | 
			
		||||
@ -63,6 +64,8 @@ func (app *application) serve() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	gob.Register(TransactionData{})
 | 
			
		||||
 | 
			
		||||
	var cfg config
 | 
			
		||||
 | 
			
		||||
	flag.IntVar(&cfg.port, "port", 4000, "Server port to listen on")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								cmd/web/middleware.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cmd/web/middleware.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func SessionLoad(next http.Handler) http.Handler {
 | 
			
		||||
	return session.LoadAndSave(next)
 | 
			
		||||
}
 | 
			
		||||
@ -13,6 +13,7 @@ func (app *application) routes() http.Handler {
 | 
			
		||||
	mux.Get("/", app.Home)
 | 
			
		||||
	mux.Get("/virtual-terminal", app.VirtualTerminal)
 | 
			
		||||
	mux.Post("/payment-succeeded", app.PaymentSucceeded)
 | 
			
		||||
	mux.Get("/receipt", app.Receipt)
 | 
			
		||||
	mux.Get("/widget/{id}", app.ChargeOnce)
 | 
			
		||||
 | 
			
		||||
	fileServer := http.FileServer(http.Dir("./static"))
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								cmd/web/templates/home.page.gohtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								cmd/web/templates/home.page.gohtml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
{{ template "base" . }}
 | 
			
		||||
{{ define "title" }}
 | 
			
		||||
Widget
 | 
			
		||||
{{ end }}
 | 
			
		||||
{{ define "content" }}
 | 
			
		||||
<h2 class="mt-5">Widget</h2>
 | 
			
		||||
{{ end }}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								cmd/web/templates/receipt.page.gohtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								cmd/web/templates/receipt.page.gohtml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
{{ template "base" . }}
 | 
			
		||||
{{ define "title" }}
 | 
			
		||||
Payment Succedded!
 | 
			
		||||
{{ end }}
 | 
			
		||||
{{ define "content" }}
 | 
			
		||||
{{$txn := index .Data "txn"}}
 | 
			
		||||
<h2 class="mt-5">Payment Succeeded</h2>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>Payment Intent: {{$txn.PaymentIntentID}}</p>
 | 
			
		||||
<p>Customer Name: {{ $txn.FirstName }} {{ $txn.LastName }}</p>
 | 
			
		||||
<p>Email: {{ $txn.Email }}</p>
 | 
			
		||||
<p>Payment Method: {{ $txn.PaymentMethodID }}</p>
 | 
			
		||||
<p>Payment Amount: {{ $txn.PaymentAmount }}</p>
 | 
			
		||||
<p>Currency: {{ $txn.PaymentCurrency }}</p>
 | 
			
		||||
<p>Last Four: {{ $txn.LastFour }}</p>
 | 
			
		||||
<p>Bank Return Code: {{ $txn.BankReturnCode }}</p>
 | 
			
		||||
<p>Expiry Date: {{ $txn.ExpiryMonth }}/{{$txn.ExpiryYear}}</p>
 | 
			
		||||
{{ end }}
 | 
			
		||||
@ -1,17 +0,0 @@
 | 
			
		||||
{{ template "base" . }}
 | 
			
		||||
{{ define "title" }}
 | 
			
		||||
Payment Succedded!
 | 
			
		||||
{{ end }}
 | 
			
		||||
{{ define "content" }}
 | 
			
		||||
<h2 class="mt-5">Payment Succeeded</h2>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>Payment Intent: {{ index .Data "pi" }}</p>
 | 
			
		||||
<p>Customer Name: {{ index .Data "first_name" }} {{ index .Data "last_name" }}</p>
 | 
			
		||||
<p>Email: {{ index .Data "email" }}</p>
 | 
			
		||||
<p>Payment Method: {{ index .Data "pm" }}</p>
 | 
			
		||||
<p>Payment Amount: {{ index .Data "pa" }}</p>
 | 
			
		||||
<p>Currency: {{ index .Data "pc" }}</p>
 | 
			
		||||
<p>Last Four: {{ index .Data "last_four" }}</p>
 | 
			
		||||
<p>Bank Return Code: {{ index .Data "bank_return_code" }}</p>
 | 
			
		||||
<p>Expiry Date: {{ index .Data "expiry_month" }}/{{index .Data "expiry_year"}}</p>
 | 
			
		||||
{{ end }}
 | 
			
		||||
@ -72,6 +72,8 @@ type Transaction struct {
 | 
			
		||||
	LastFour            string    `json:"last_four"`
 | 
			
		||||
	ExpiryMonth         int       `json:"expiry_month"`
 | 
			
		||||
	ExpiryYear          int       `json:"expiry_year"`
 | 
			
		||||
	PaymentIntent       string    `json:"payment_intent"`
 | 
			
		||||
	PaymentMethod       string    `json:"payment_method"`
 | 
			
		||||
	BankReturnCode      string    `json:"bank_return_code"`
 | 
			
		||||
	TransactionStatusID int       `json:"transaction_status_id"`
 | 
			
		||||
	CreatedAt           time.Time `json:"-"`
 | 
			
		||||
@ -134,9 +136,9 @@ func (m *DBModel) InsertTransaction(txn Transaction) (int, error) {
 | 
			
		||||
 | 
			
		||||
	stmt := `INSERT INTO transactions
 | 
			
		||||
             (amount, currency, last_four, expiry_month, expiry_year,
 | 
			
		||||
             bank_return_code,
 | 
			
		||||
             payment_intent, payment_method, bank_return_code,
 | 
			
		||||
             transaction_status_id, created_at, updated_at)
 | 
			
		||||
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
 | 
			
		||||
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
 | 
			
		||||
 | 
			
		||||
	result, err := m.DB.ExecContext(ctx, stmt,
 | 
			
		||||
		txn.Amount,
 | 
			
		||||
@ -144,6 +146,8 @@ func (m *DBModel) InsertTransaction(txn Transaction) (int, error) {
 | 
			
		||||
		txn.LastFour,
 | 
			
		||||
		txn.ExpiryMonth,
 | 
			
		||||
		txn.ExpiryYear,
 | 
			
		||||
		txn.PaymentIntent,
 | 
			
		||||
		txn.PaymentMethod,
 | 
			
		||||
		txn.BankReturnCode,
 | 
			
		||||
		txn.TransactionStatusID,
 | 
			
		||||
		time.Now(),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								migrations/20240810091357_add_cols_to_txn.down.fizz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								migrations/20240810091357_add_cols_to_txn.down.fizz
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
drop_column("transactions", "payment_intent")
 | 
			
		||||
drop_column("transactions", "payment_method")
 | 
			
		||||
							
								
								
									
										3
									
								
								migrations/20240810091357_add_cols_to_txn.up.fizz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								migrations/20240810091357_add_cols_to_txn.up.fizz
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
add_column("transactions", "payment_intent", "string", {"default":""})
 | 
			
		||||
add_column("transactions", "payment_method", "string", {"default":""})
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user