Compare commits
No commits in common. "d32667acd168e7e28e0dddb73f1d4db5e5ac1b96" and "7e0df51d881d1fb92c2058a5efc6ed63b3ef4adc" have entirely different histories.
d32667acd1
...
7e0df51d88
2
Makefile
2
Makefile
@ -2,7 +2,7 @@ STRIPE_SECRET=$(shell sed '2q;d' cred.txt)
|
|||||||
STRIPE_KEY=$(shell sed '2q;d' cred.txt)
|
STRIPE_KEY=$(shell sed '2q;d' cred.txt)
|
||||||
GOSTRIPE_PORT=4000
|
GOSTRIPE_PORT=4000
|
||||||
API_PORT=4001
|
API_PORT=4001
|
||||||
DSN=vinchent:secret@tcp(localhost:3306)/widgets?parseTime=true&tls=false
|
DSN=root@tcp(localhost:6379)/widgets?parseTime=true&tls=false
|
||||||
|
|
||||||
## build: builds all binaries
|
## build: builds all binaries
|
||||||
build: clean build_front build_back
|
build: clean build_front build_back
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"myapp/internal/driver"
|
"myapp/internal/driver"
|
||||||
"myapp/internal/models"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@ -32,7 +31,6 @@ type application struct {
|
|||||||
infoLog *log.Logger
|
infoLog *log.Logger
|
||||||
errorLog *log.Logger
|
errorLog *log.Logger
|
||||||
version string
|
version string
|
||||||
DB models.DBModel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *application) serve() error {
|
func (app *application) serve() error {
|
||||||
@ -89,7 +87,6 @@ func main() {
|
|||||||
config: cfg,
|
config: cfg,
|
||||||
infoLog: infoLog,
|
infoLog: infoLog,
|
||||||
errorLog: errorLog,
|
errorLog: errorLog,
|
||||||
DB: models.DBModel{DB: conn},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.infoLog.Println("Connected to MariaDB")
|
app.infoLog.Println("Connected to MariaDB")
|
||||||
|
@ -5,8 +5,6 @@ import (
|
|||||||
"myapp/internal/cards"
|
"myapp/internal/cards"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type stripePayload struct {
|
type stripePayload struct {
|
||||||
@ -67,19 +65,3 @@ func (app *application) GetPaymentIntent(w http.ResponseWriter, r *http.Request)
|
|||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.Write(out)
|
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)
|
|
||||||
}
|
|
||||||
|
@ -19,6 +19,5 @@ func (app *application) routes() http.Handler {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
mux.Post("/api/payment-intent", app.GetPaymentIntent)
|
mux.Post("/api/payment-intent", app.GetPaymentIntent)
|
||||||
mux.Get("/api/widget/{id}", app.GetWidgetByID)
|
|
||||||
return mux
|
return mux
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"myapp/internal/models"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (app *application) VirtualTerminal(w http.ResponseWriter, r *http.Request) {
|
func (app *application) VirtualTerminal(w http.ResponseWriter, r *http.Request) {
|
||||||
if err := app.renderTemplate(w, r, "terminal", &templateData{}, "stripe-js"); err != nil {
|
stringMap := make(map[string]string)
|
||||||
|
stringMap["publishable_key"] = app.config.stripe.key
|
||||||
|
if err := app.renderTemplate(w, r, "terminal", &templateData{
|
||||||
|
StringMap: stringMap,
|
||||||
|
}, "stripe-js"); err != nil {
|
||||||
app.errorLog.Println(err)
|
app.errorLog.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,20 +46,7 @@ func (app *application) PaymentSucceeded(w http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
// ChargeOnce displays the page to buy one widget
|
// ChargeOnce displays the page to buy one widget
|
||||||
func (app *application) ChargeOnce(w http.ResponseWriter, r *http.Request) {
|
func (app *application) ChargeOnce(w http.ResponseWriter, r *http.Request) {
|
||||||
widget := models.Widget{
|
if err := app.renderTemplate(w, r, "buy-once", nil, "stripe-js"); err != nil {
|
||||||
ID: 1,
|
|
||||||
Name: "Custom Widget",
|
|
||||||
Description: "Paris 2024",
|
|
||||||
InventoryLevel: 10,
|
|
||||||
Price: 1000,
|
|
||||||
}
|
|
||||||
|
|
||||||
data := make(map[string]interface{})
|
|
||||||
data["widget"] = widget
|
|
||||||
|
|
||||||
if err := app.renderTemplate(w, r, "buy-once", &templateData{
|
|
||||||
Data: data,
|
|
||||||
}, "stripe-js"); err != nil {
|
|
||||||
app.errorLog.Println(err)
|
app.errorLog.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
"myapp/internal/driver"
|
"myapp/internal/driver"
|
||||||
"myapp/internal/models"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@ -36,7 +35,6 @@ type application struct {
|
|||||||
errorLog *log.Logger
|
errorLog *log.Logger
|
||||||
templateCache map[string]*template.Template
|
templateCache map[string]*template.Template
|
||||||
version string
|
version string
|
||||||
DB models.DBModel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *application) serve() error {
|
func (app *application) serve() error {
|
||||||
@ -97,7 +95,6 @@ func main() {
|
|||||||
errorLog: errorLog,
|
errorLog: errorLog,
|
||||||
templateCache: tc,
|
templateCache: tc,
|
||||||
version: version,
|
version: version,
|
||||||
DB: models.DBModel{DB: conn},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.infoLog.Println("Connected to MariaDB")
|
app.infoLog.Println("Connected to MariaDB")
|
||||||
|
@ -20,26 +20,15 @@ type templateData struct {
|
|||||||
API string
|
API string
|
||||||
CSSVersion string
|
CSSVersion string
|
||||||
IsAuthenticated int
|
IsAuthenticated int
|
||||||
StripeSecretKey string
|
|
||||||
StripePubKey string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var functions = template.FuncMap{
|
var functions = template.FuncMap{}
|
||||||
"formatCurrency": formatCurrency,
|
|
||||||
}
|
|
||||||
|
|
||||||
func formatCurrency(n int) string {
|
|
||||||
f := float32(n / 100)
|
|
||||||
return fmt.Sprintf("€%.2f", f)
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:embed templates
|
//go:embed templates
|
||||||
var templateFS embed.FS
|
var templateFS embed.FS
|
||||||
|
|
||||||
func (app *application) addDefaultData(td *templateData, r *http.Request) *templateData {
|
func (app *application) addDefaultData(td *templateData, r *http.Request) *templateData {
|
||||||
td.API = app.config.api
|
td.API = app.config.api
|
||||||
td.StripePubKey = app.config.stripe.key
|
|
||||||
td.StripeSecretKey = app.config.stripe.secret
|
|
||||||
return td
|
return td
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
Buy one widget
|
Buy one widget
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ define "content" }}
|
{{ define "content" }}
|
||||||
{{$widget := index .Data "widget"}}
|
|
||||||
<h2 class="mt-3 text-center">Buy One Widget</h2>
|
<h2 class="mt-3 text-center">Buy One Widget</h2>
|
||||||
<hr>
|
<hr>
|
||||||
<img src="/static/img/widget.jpeg"
|
<img src="/static/img/widget.jpeg"
|
||||||
@ -18,12 +17,15 @@ Buy one widget
|
|||||||
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}}">
|
<div class="mb-3">
|
||||||
<input type="hidden" id="amount" name="amount" value="{{$widget.Price}}">
|
<label for="amount" class="form-label">Amount</label>
|
||||||
<h3 class="mt-2 mb-3 text-center">{{$widget.Name}}: {{formatCurrency $widget.Price}}</h3>
|
<input type="text"
|
||||||
<p class="mt-2 mb-3 text-center">{{$widget.Description}}</p>
|
id="amount"
|
||||||
<hr>
|
name="amount"
|
||||||
|
autocomplete="amount-new"
|
||||||
|
required=""
|
||||||
|
class="form-control">
|
||||||
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="cardholder-name" class="form-label">Cardholder Name</label>
|
<label for="cardholder-name" class="form-label">Cardholder Name</label>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
|
@ -8,7 +8,7 @@ const cardMessages = document.getElementById("card-messages");
|
|||||||
const payButton = document.getElementById("pay-button");
|
const payButton = document.getElementById("pay-button");
|
||||||
const processing = document.getElementById("processing-payment");
|
const processing = document.getElementById("processing-payment");
|
||||||
|
|
||||||
stripe = Stripe('{{.StripePubKey}}');
|
stripe = Stripe('{{index .StringMap "publishable_key"}}');
|
||||||
|
|
||||||
function hidePayButton() {
|
function hidePayButton() {
|
||||||
payButton.classList.add("d-none");
|
payButton.classList.add("d-none");
|
||||||
@ -46,7 +46,7 @@ function val() {
|
|||||||
form.classList.add("was-validated");
|
form.classList.add("was-validated");
|
||||||
hidePayButton();
|
hidePayButton();
|
||||||
|
|
||||||
let amountToCharge = String(parseFloat(document.getElementById("amount").value));
|
let amountToCharge = String(parseFloat(document.getElementById("amount").value) * 100);
|
||||||
let payload = {
|
let payload = {
|
||||||
amount: amountToCharge,
|
amount: amountToCharge,
|
||||||
currency: 'eur',
|
currency: 'eur',
|
||||||
@ -61,7 +61,7 @@ function val() {
|
|||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch("{{.API}}/api/payment-intent", requestOptions)
|
fetch("{{index .API}}/api/payment-intent", requestOptions)
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(response => {
|
.then(response => {
|
||||||
let data;
|
let data;
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DBModel is the type for database connection values
|
|
||||||
type DBModel struct {
|
|
||||||
DB *sql.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
// Models is the wrapper for all models
|
|
||||||
type Models struct {
|
|
||||||
DB DBModel
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewModels returns a model type with database connection pool
|
|
||||||
func NewModels(db *sql.DB) Models {
|
|
||||||
return Models{
|
|
||||||
DB: DBModel{DB: db},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Widget is the type for all widgets
|
|
||||||
type Widget struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
InventoryLevel int `json:"inventory_level"`
|
|
||||||
Price int `json:"price"`
|
|
||||||
CreatedAt time.Time `json:"-"`
|
|
||||||
UpdatedAt time.Time `json:"-"`
|
|
||||||
Image string `json:"image"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Order is the type for all orders
|
|
||||||
type Order struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
WidgetID int `json:"widget_id"`
|
|
||||||
TransactionID int `json:"transaction_id"`
|
|
||||||
StatusID int `json:"status_id"`
|
|
||||||
Quantity int `json:"quantity"`
|
|
||||||
Amount int `json:"amount"`
|
|
||||||
CreatedAt time.Time `json:"-"`
|
|
||||||
UpdatedAt time.Time `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status is the type for orders statuses
|
|
||||||
type Status struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
CreatedAt time.Time `json:"-"`
|
|
||||||
UpdatedAt time.Time `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// TransactionStatus is the type for transaction statuses
|
|
||||||
type TransactionStatus struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
CreatedAt time.Time `json:"-"`
|
|
||||||
UpdatedAt time.Time `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transaction is the type for transactions
|
|
||||||
type Transaction struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Amount int `json:"amount"`
|
|
||||||
Currency string `json:"currency"`
|
|
||||||
LastFour string `json:"last_four"`
|
|
||||||
BankReturnCode string `json:bank_return_code`
|
|
||||||
TransactionStatusID int `json:transaction_status_id`
|
|
||||||
CreatedAt time.Time `json:"-"`
|
|
||||||
UpdatedAt time.Time `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// User is the type for users
|
|
||||||
type User struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
FirstName string `json:"first_name"`
|
|
||||||
LastName string `json:"last_name"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
CreatedAt time.Time `json:"-"`
|
|
||||||
UpdatedAt time.Time `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *DBModel) GetWidget(id int) (Widget, error) {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
var widget Widget
|
|
||||||
|
|
||||||
query := `SELECT id, name FROM widgets WHERE id = ?`
|
|
||||||
|
|
||||||
row := m.DB.QueryRowContext(ctx, query, id)
|
|
||||||
err := row.Scan(&widget.ID, &widget.Name)
|
|
||||||
if err != nil {
|
|
||||||
return widget, err
|
|
||||||
}
|
|
||||||
return widget, nil
|
|
||||||
}
|
|
BIN
migrations/migrations/.DS_Store
vendored
BIN
migrations/migrations/.DS_Store
vendored
Binary file not shown.
@ -1,12 +0,0 @@
|
|||||||
create_table("widgets") {
|
|
||||||
t.Column("id", "integer", {primary: true})
|
|
||||||
t.Column("name", "string", {"default": ""})
|
|
||||||
t.Column("description", "text", {"default": ""})
|
|
||||||
t.Column("inventory_level", "integer", {})
|
|
||||||
t.Column("price", "integer", {})
|
|
||||||
}
|
|
||||||
|
|
||||||
sql("alter table widgets alter column created_at set default now();")
|
|
||||||
sql("alter table widgets alter column updated_at set default now();")
|
|
||||||
|
|
||||||
sql("insert into widgets (name, description, inventory_level, price, created_at, updated_at) values ('Widget', 'A very nice widget.', 10, 1000, now(), now());")
|
|
@ -1,13 +0,0 @@
|
|||||||
create_table("transaction_statuses") {
|
|
||||||
t.Column("id", "integer", {primary: true})
|
|
||||||
t.Column("name", "string", {})
|
|
||||||
}
|
|
||||||
|
|
||||||
sql("alter table transaction_statuses alter column created_at set default now();")
|
|
||||||
sql("alter table transaction_statuses alter column updated_at set default now();")
|
|
||||||
|
|
||||||
sql("insert into transaction_statuses (name) values ('Pending');")
|
|
||||||
sql("insert into transaction_statuses (name) values ('Cleared');")
|
|
||||||
sql("insert into transaction_statuses (name) values ('Declined');")
|
|
||||||
sql("insert into transaction_statuses (name) values ('Refunded');")
|
|
||||||
sql("insert into transaction_statuses (name) values ('Partially refunded');")
|
|
@ -1 +0,0 @@
|
|||||||
drop_table("transactions")
|
|
@ -1,16 +0,0 @@
|
|||||||
create_table("transactions") {
|
|
||||||
t.Column("id", "integer", {primary: true})
|
|
||||||
t.Column("amount", "integer", {})
|
|
||||||
t.Column("currency", "string", {})
|
|
||||||
t.Column("last_four", "string", {})
|
|
||||||
t.Column("bank_return_code", "string", {})
|
|
||||||
t.Column("transaction_status_id", "integer", {"unsigned": true})
|
|
||||||
}
|
|
||||||
|
|
||||||
sql("alter table transactions alter column created_at set default now();")
|
|
||||||
sql("alter table transactions alter column updated_at set default now();")
|
|
||||||
|
|
||||||
add_foreign_key("transactions", "transaction_status_id", {"transaction_statuses": ["id"]}, {
|
|
||||||
"on_delete": "cascade",
|
|
||||||
"on_update": "cascade",
|
|
||||||
})
|
|
@ -1 +0,0 @@
|
|||||||
drop_table("orders")
|
|
@ -1,21 +0,0 @@
|
|||||||
create_table("orders") {
|
|
||||||
t.Column("id", "integer", {primary: true})
|
|
||||||
t.Column("widget_id", "integer", {"unsigned":true})
|
|
||||||
t.Column("transaction_id", "integer", {"unsigned":true})
|
|
||||||
t.Column("status_id", "integer", {"unsigned":true})
|
|
||||||
t.Column("quantity", "integer", {})
|
|
||||||
t.Column("amount", "integer", {})
|
|
||||||
}
|
|
||||||
|
|
||||||
sql("alter table orders alter column created_at set default now();")
|
|
||||||
sql("alter table orders alter column updated_at set default now();")
|
|
||||||
|
|
||||||
add_foreign_key("orders", "widget_id", {"widgets": ["id"]}, {
|
|
||||||
"on_delete": "cascade",
|
|
||||||
"on_update": "cascade",
|
|
||||||
})
|
|
||||||
|
|
||||||
add_foreign_key("orders", "transaction_id", {"transactions": ["id"]}, {
|
|
||||||
"on_delete": "cascade",
|
|
||||||
"on_update": "cascade",
|
|
||||||
})
|
|
@ -1 +0,0 @@
|
|||||||
drop_table("statuses")
|
|
@ -1,16 +0,0 @@
|
|||||||
create_table("statuses") {
|
|
||||||
t.Column("id", "integer", {primary: true})
|
|
||||||
t.Column("name", "string", {})
|
|
||||||
}
|
|
||||||
|
|
||||||
sql("alter table statuses alter column created_at set default now();")
|
|
||||||
sql("alter table statuses alter column updated_at set default now();")
|
|
||||||
|
|
||||||
sql("insert into statuses (name) values ('Cleared');")
|
|
||||||
sql("insert into statuses (name) values ('Refunded');")
|
|
||||||
sql("insert into statuses (name) values ('Cancelled');")
|
|
||||||
|
|
||||||
add_foreign_key("orders", "status_id", {"statuses": ["id"]}, {
|
|
||||||
"on_delete": "cascade",
|
|
||||||
"on_update": "cascade",
|
|
||||||
})
|
|
@ -1 +0,0 @@
|
|||||||
drop_table("users")
|
|
@ -1,12 +0,0 @@
|
|||||||
create_table("users") {
|
|
||||||
t.Column("id", "integer", {primary: true})
|
|
||||||
t.Column("first_name", "string", {"size": 255})
|
|
||||||
t.Column("last_name", "string", {"size": 255})
|
|
||||||
t.Column("email", "string", {})
|
|
||||||
t.Column("password", "string", {"size": 60})
|
|
||||||
}
|
|
||||||
|
|
||||||
sql("alter table users alter column created_at set default now();")
|
|
||||||
sql("alter table users alter column updated_at set default now();")
|
|
||||||
|
|
||||||
sql("insert into users (first_name, last_name, email, password) values ('Admin','User','admin@example.com', '$2a$12$VR1wDmweaF3ZTVgEHiJrNOSi8VcS4j0eamr96A/7iOe8vlum3O3/q');")
|
|
@ -1 +0,0 @@
|
|||||||
drop_column("widgets", "image")
|
|
@ -1 +0,0 @@
|
|||||||
add_column("widgets", "image", "string", {"default":""})
|
|
@ -4,7 +4,8 @@ const cardMessages = document.getElementById("card-messages");
|
|||||||
const payButton = document.getElementById("pay-button");
|
const payButton = document.getElementById("pay-button");
|
||||||
const processing = document.getElementById("processing-payment");
|
const processing = document.getElementById("processing-payment");
|
||||||
|
|
||||||
stripe = Stripe('{{.StripePubKey}}');
|
// FIXME: not working in this way
|
||||||
|
stripe = Stripe('{{index .StringMap "publishable_key"}}');
|
||||||
|
|
||||||
function hidePayButton() {
|
function hidePayButton() {
|
||||||
payButton.classList.add("d-none");
|
payButton.classList.add("d-none");
|
||||||
@ -30,7 +31,7 @@ function showCardSuccess() {
|
|||||||
cardMessages.innerText = "Trasaction successful";
|
cardMessages.innerText = "Trasaction successful";
|
||||||
}
|
}
|
||||||
|
|
||||||
function val(stripe) {
|
function val() {
|
||||||
let form = document.getElementById("charge_form");
|
let form = document.getElementById("charge_form");
|
||||||
|
|
||||||
if (form.checkValidity() === false) {
|
if (form.checkValidity() === false) {
|
||||||
@ -42,7 +43,7 @@ function val(stripe) {
|
|||||||
form.classList.add("was-validated");
|
form.classList.add("was-validated");
|
||||||
hidePayButton();
|
hidePayButton();
|
||||||
|
|
||||||
let amountToCharge = String(parseFloat(document.getElementById("amount").value));
|
let amountToCharge = String(parseFloat(document.getElementById("amount").value) * 100);
|
||||||
let payload = {
|
let payload = {
|
||||||
amount: amountToCharge,
|
amount: amountToCharge,
|
||||||
currency: 'eur',
|
currency: 'eur',
|
||||||
@ -57,7 +58,7 @@ function val(stripe) {
|
|||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch("{{.API}}/api/payment-intent", requestOptions)
|
fetch("{{index .API}}/api/payment-intent", requestOptions)
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(response => {
|
.then(response => {
|
||||||
let data;
|
let data;
|
||||||
@ -127,3 +128,4 @@ function val(stripe) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user