diff --git a/Makefile b/Makefile
index 8b37b88..87b70e6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,12 @@
BIN = builder
SRC = main.go
GOFILES = go.sum go.mod
-GOMODS = github.com/joho/godotenv
+GOMODS = github.com/joho/godotenv github.com/lib/pq
all: ${BIN}
${BIN}: ${SRC} ${GOFILES}
- go build -o $@
+ go build -o builder
${GOFILES}:
go mod init ${BIN}
diff --git a/main.go b/main.go
index 8856da3..834dbff 100644
--- a/main.go
+++ b/main.go
@@ -1,89 +1,141 @@
package main
import (
+ "bytes"
+ "database/sql"
"encoding/json"
+ "fmt"
+ "io/ioutil"
"log"
"net/http"
- "strings"
"os"
- "fmt"
"os/signal"
+ "strings"
"syscall"
- "bytes"
- // "time"
+ "time"
"github.com/joho/godotenv"
+ _ "github.com/lib/pq"
)
-type OrderData struct {
+var (
+ baseURL string
+ clientID string
+ clientSecret string
+ planID string
+ returnUrl string
+ cancelUrl string
+
+ exists bool
+ err error
+
+ dbHost string
+ dbPort string
+ dbUser string
+ dbPass string
+ dbName string
+ db *sql.DB
+ query string
+)
+
+func init() {
+ // Load .env
+ if err := godotenv.Load(); err != nil {
+ log.Fatalf("Error loading .env file: %v", err)
+ }
+
+ // Set variables
+ baseURL = os.Getenv("BASE_URL")
+ clientID = os.Getenv("CLIENT_ID")
+ clientSecret = os.Getenv("CLIENT_SECRET")
+ planID = os.Getenv("PLAN_ID")
+ returnUrl = os.Getenv("RETURN_URL")
+ cancelUrl = os.Getenv("CANCEL_URL")
+ // DB creds
+ dbHost = os.Getenv("DB_HOST")
+ dbPort = os.Getenv("DB_PORT")
+ dbUser = os.Getenv("DB_USER")
+ dbPass = os.Getenv("DB_PASS")
+ dbName = os.Getenv("DB_NAME")
+
+ // Error if empty
+ if baseURL == "" || clientID == "" || clientSecret == "" || planID == "" || returnUrl == "" || cancelUrl == "" ||
+ dbHost == "" || dbPort == "" || dbUser == "" || dbPass == "" || dbName == "" {
+ log.Fatalf("Error setting credentials")
+ }
+
+ // Connect to DB
+ var err error
+ connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
+ dbHost, dbPort, dbUser, dbPass, dbName)
+ db, err = sql.Open("postgres", connStr)
+ if err != nil {
+ log.Fatalf("Failed to connect to database: %v", err)
+ }
+
+ // Ping DB
+ if err = db.Ping(); err != nil {
+ log.Fatalf("Failed to ping database: %v", err)
+ }
+}
+
+type CreateOrderResponse struct {
+ ID string `json:"id"`
+}
+
+type OrderResponse struct {
ID string `json:"id"`
Status string `json:"status"`
PurchaseUnits []struct {
Payments struct {
Captures []struct {
- ID string `json:"id"`
- Status string `json:"status"`
+ ID string `json:"id"`
+ Status string `json:"status"`
+ CreateTime time.Time `json:"create_time"`
} `json:"captures"`
} `json:"payments"`
} `json:"purchase_units"`
+ Payer struct {
+ Name struct {
+ GivenName string `json:"given_name"`
+ Surname string `json:"surname"`
+ } `json:"name"`
+ EmailAddress string `json:"email_address"`
+ Phone struct {
+ PhoneType string `json:"phone_type"`
+ PhoneNumber struct {
+ NationalNumber string `json:"national_number"`
+ } `json:"phone_number"`
+ } `json:"phone"`
+ Address struct {
+ CountryCode string `json:"country_code"`
+ } `json:"address"`
+ } `json:"payer"`
}
-type SubscriptionData struct {
- ID string `json:"id"`
+type SubscriptionResponse struct {
Status string `json:"status"`
- // StatusUpdateTime time.Time `json:"status_update_time"`
- PlanID string `json:"plan_id"`
- PlanOverridden bool `json:"plan_overridden"`
- // StartTime time.Time `json:"start_time"`
- Quantity string `json:"quantity"`
- ShippingAmount struct {
- CurrencyCode string `json:"currency_code"`
- Value string `json:"value"`
- } `json:"shipping_amount"`
+ StatusUpdateTime time.Time `json:"status_update_time"`
+ StartTime time.Time `json:"start_time"`
Subscriber struct {
Name struct {
GivenName string `json:"given_name"`
Surname string `json:"surname"`
} `json:"name"`
EmailAddress string `json:"email_address"`
- PayerID string `json:"payer_id"`
- ShippingAddress struct {
- Name struct {
- FullName string `json:"full_name"`
- } `json:"name"`
- Address struct {
- AddressLine1 string `json:"address_line_1"`
- AddressLine2 string `json:"address_line_2"`
- AdminArea2 string `json:"admin_area_2"`
- AdminArea1 string `json:"admin_area_1"`
- PostalCode string `json:"postal_code"`
- CountryCode string `json:"country_code"`
- } `json:"address"`
- } `json:"shipping_address"`
} `json:"subscriber"`
- // CreateTime time.Time `json:"create_time"`
- Links []struct {
- Href string `json:"href"`
- Rel string `json:"rel"`
- Method string `json:"method"`
- } `json:"links"`
+ CreateTime time.Time `json:"create_time"`
}
-var (
- baseURL = "https://api-m.sandbox.paypal.com"
-)
-
-func init() {
- if err := godotenv.Load() ; err != nil {
- log.Fatalf("Error loading .env file: %v", err)
- }
+type Cart struct {
+ Directory string `json:"directory"`
}
func main() {
- // Handlers
- http.HandleFunc("/api/orders", CreateOrder)
- http.HandleFunc("/api/orders/", CaptureOrder)
- http.HandleFunc("/api/paypal/create-subscription", CreateSubscription)
+ http.HandleFunc("/api/order", CreateOrder)
+ http.HandleFunc("/api/order/", CaptureOrder)
+ http.HandleFunc("/api/paypal/subscribe", CreateSubscription)
+ http.HandleFunc("/api/paypal/subscribe/", CaptureSubscription)
http.Handle("/", http.FileServer(http.Dir("./public")))
// Channel to listen for signals
@@ -103,13 +155,13 @@ func main() {
}
func Token() (string, error) {
- // Create request
+ // Create
req, err := http.NewRequest("POST", baseURL+"/v1/oauth2/token", strings.NewReader(`grant_type=client_credentials`))
if err != nil {
return "", fmt.Errorf("Error creating request: %v", err)
}
- // Make POST req, should return JSON with AccessToken
+ // Send
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.SetBasicAuth(os.Getenv("CLIENT_ID"), os.Getenv("CLIENT_SECRET"))
resp, err := http.DefaultClient.Do(req)
@@ -118,7 +170,7 @@ func Token() (string, error) {
}
defer resp.Body.Close()
- // Decode response into result
+ // Decode
var result struct {
AccessToken string `json:"access_token"`
}
@@ -126,9 +178,64 @@ func Token() (string, error) {
return "", fmt.Errorf("Error decoding response: %v", err)
}
+ // Return
return result.AccessToken, nil
}
+func RegisterOrder(order OrderResponse, directory string) {
+ var (
+ capture string
+ status string
+ name string
+ surname string
+ email string
+ phone string
+ country string
+ date time.Time
+ )
+
+ for _, Unit := range order.PurchaseUnits {
+ for _, Capture := range Unit.Payments.Captures {
+ capture = Capture.ID
+ status = Capture.Status
+ date = Capture.CreateTime
+ }
+ }
+
+ name = order.Payer.Name.GivenName
+ surname = order.Payer.Name.Surname
+ email = order.Payer.EmailAddress
+ phone = order.Payer.Phone.PhoneNumber.NationalNumber
+ country = order.Payer.Address.CountryCode
+
+ // Register Payment
+ _, err = db.Exec(`INSERT INTO payments (id, client, directory, status, step, date) VALUES ($1, $2, $3, $4, $5, $6);`,
+ capture, email, directory, status, "REGISTERED", date)
+ if err != nil {
+ fmt.Printf("$v", err) // TODO consider logging in server
+ }
+
+ // Register Client
+ err = db.QueryRow(`SELECT EXISTS(SELECT 1 FROM clients WHERE email = $1);`, email).Scan(&exists)
+ if err != nil {
+ fmt.Printf("$v", err) // TODO consider logging in server
+ }
+ if !exists {
+ _, err = db.Exec(`INSERT INTO clients (email, name, surname, phone, country) VALUES ($1, $2, $3, $4, $5);`,
+ email, name, surname, phone, country)
+ if err != nil {
+ fmt.Printf("$v", err) // TODO consider logging in server
+ }
+ }
+
+ // Register Site
+ _, err = db.Exec(`INSERT INTO sites (directory, client, status, ends) VALUES ($1, $2, $3, $4);`,
+ directory, email, "ACTIVE", date.AddDate(1, 0, 0)) // Ends a year later
+ if err != nil {
+ fmt.Printf("$v", err) // TODO consider logging in server
+ }
+}
+
func CreateOrder(w http.ResponseWriter, r *http.Request) {
token, err := Token()
if err != nil {
@@ -144,17 +251,26 @@ func CreateOrder(w http.ResponseWriter, r *http.Request) {
"value": "20.00"
}
}],
+ "payment_source": {
+ "paypal": {
+ "address" : {
+ "country_code": "CR"
+ }
+ }
+ },
"application_context": {
"shipping_preference": "NO_SHIPPING"
}
}`
+ // Create
req, err := http.NewRequest("POST", baseURL+"/v2/checkout/orders", bytes.NewBuffer([]byte(data)))
if err != nil {
http.Error(w, "Failed to create request", http.StatusInternalServerError)
return
}
+ // Send
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
@@ -164,74 +280,110 @@ func CreateOrder(w http.ResponseWriter, r *http.Request) {
}
defer resp.Body.Close()
- var result map[string]interface{}
+ // Decode
+ var result CreateOrderResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
http.Error(w, "Failed to decode response", http.StatusInternalServerError)
return
}
- if id, ok := result["id"].(string); ok {
- json.NewEncoder(w).Encode(map[string]string{"id": id})
- return
- } else {
- http.Error(w, "Order ID not found", http.StatusInternalServerError)
- return
- }
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(map[string]string{"id": result.ID})
+ return
}
func CaptureOrder(w http.ResponseWriter, r *http.Request) {
+ // Read body from order
+ body, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, "Failed to read request body", http.StatusInternalServerError)
+ return
+ }
+
+ // Parse to get directory
+ var cart Cart
+ err = json.Unmarshal(body, &cart)
+ if err != nil {
+ http.Error(w, "Failed to parse request body", http.StatusBadRequest)
+ return
+ }
+ directory := cart.Directory
+
+ // Get orderID
path := strings.TrimPrefix(r.URL.Path, "/api/orders/")
parts := strings.Split(path, "/")
orderID := parts[0]
+ if orderID == "" {
+ http.Error(w, "Failed to get orderID from client URL", http.StatusInternalServerError)
+ return
+ }
- client := &http.Client{}
+ token, err := Token()
+ if err != nil {
+ http.Error(w, "Failed to get access token", http.StatusInternalServerError)
+ return
+ }
+
+ // Create
req, err := http.NewRequest("POST", baseURL+"/v2/checkout/orders/"+orderID+"/capture", nil)
if err != nil {
http.Error(w, "Failed to create request", http.StatusInternalServerError)
return
}
- token, err := Token()
+ // Check if directory already exists
+ err = db.QueryRow("SELECT EXISTS (SELECT 1 FROM sites WHERE directory = $1 LIMIT 1);", directory).Scan(&exists)
if err != nil {
- http.Error(w, "Failed to get access token", http.StatusInternalServerError)
+ http.Error(w, "Failed to check directory ID against database", http.StatusBadRequest)
+ return
+ }
+ if exists {
+ http.Error(w, "This directory ID is already taken", http.StatusBadRequest)
return
}
+ // Send, PAYMENT MADE HERE
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
- resp, err := client.Do(req)
+ resp, err := http.DefaultClient.Do(req)
if err != nil {
http.Error(w, "Failed to send request", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
- // Create an instance of AutoGenerated
- var result OrderData
-
- // Decode the response into the AutoGenerated struct
- if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
+ // Decode
+ var order OrderResponse
+ if err := json.NewDecoder(resp.Body).Decode(&order); err != nil {
http.Error(w, "Failed to decode response", http.StatusInternalServerError)
return
}
- // Now, `result` contains the entire structured response
- // You can send the whole `result` back to the client, or you can selectively send fields.
+ RegisterOrder(order, directory)
+
+ // Respond
w.Header().Set("Content-Type", "application/json")
- if err := json.NewEncoder(w).Encode(result); err != nil {
+ if err := json.NewEncoder(w).Encode(order); err != nil {
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
- return
}
}
func CreateSubscription(w http.ResponseWriter, r *http.Request) {
- log.Printf("asked to create sub")
+ // Read body from order
+ body, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, "Failed to read request body", http.StatusInternalServerError)
+ return
+ }
- planID := os.Getenv("PLAN_ID")
- returnUrl := "https://suckless.org"
- cancelUrl := "https://suckless.org"
-
- log.Printf("This is the planid: %s", planID)
+ // Parse to get directory
+ var cart Cart
+ err = json.Unmarshal(body, &cart)
+ if err != nil {
+ http.Error(w, "Failed to parse request body", http.StatusBadRequest)
+ return
+ }
+ directory := cart.Directory
token, err := Token()
if err != nil {
@@ -239,9 +391,7 @@ func CreateSubscription(w http.ResponseWriter, r *http.Request) {
return
}
- log.Printf("This is the token: %s", token)
-
- body := map[string]interface{}{
+ payload := map[string]interface{}{
"plan_id": planID,
"application_context": map[string]string{
"shipping_preference": "NO_SHIPPING",
@@ -249,12 +399,13 @@ func CreateSubscription(w http.ResponseWriter, r *http.Request) {
"cancel_url": cancelUrl,
},
}
- jsonData, err := json.Marshal(body)
+ jsonData, err := json.Marshal(payload)
if err != nil {
http.Error(w, "Server error", http.StatusInternalServerError)
return
}
+ // Create request
log.Printf("Creating request")
req, err := http.NewRequest("POST", baseURL+"/v1/billing/subscriptions", bytes.NewBuffer(jsonData))
if err != nil {
@@ -262,38 +413,69 @@ func CreateSubscription(w http.ResponseWriter, r *http.Request) {
return
}
+ // Check if directory already exists
+ err = db.QueryRow("SELECT EXISTS (SELECT 1 FROM sites WHERE directory = $1 LIMIT 1);", directory).Scan(&exists)
+ if err != nil {
+ http.Error(w, "Failed to check directory ID against database", http.StatusBadRequest)
+ return
+ }
+ if exists {
+ http.Error(w, "This directory ID is already taken", http.StatusBadRequest)
+ return
+ }
+
+ // Send
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Accept", "application/json")
req.Header.Set("Prefer", "return=representation")
-
- log.Printf("Sending request")
- client := &http.Client{}
- resp, err := client.Do(req)
+ resp, err := http.DefaultClient.Do(req)
if err != nil {
http.Error(w, "Failed to send request", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
- log.Printf("Request sent")
- // Create an instance of AutoGenerated
- // var result SubscriptionData
+ // Decode
var result map[string]interface{}
-
- // Decode the response into the AutoGenerated struct
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
http.Error(w, "Failed to decode response", http.StatusInternalServerError)
return
}
- log.Printf("Raw JSON Response: %v", result)
- // Now, `result` contains the entire structured response
- // You can send the whole `result` back to the client, or you can selectively send fields.
+ // Respond
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(result); err != nil {
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
}
log.Printf("sent response to client")
-
+}
+
+// Capture just like CaptureOrder, but with response from paypal
+// https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_get
+func CaptureSubscription(w http.ResponseWriter, r *http.Request) {
+ // Read body from order
+ body, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, "Failed to read request body", http.StatusInternalServerError)
+ return
+ }
+
+ // Parse to get directory
+ var cart Cart
+ err = json.Unmarshal(body, &cart)
+ if err != nil {
+ http.Error(w, "Failed to parse request body", http.StatusBadRequest)
+ return
+ }
+ // directory := cart.Directory
+
+ // Get subID
+ path := strings.TrimPrefix(r.URL.Path, "/api/subscribe/")
+ parts := strings.Split(path, "/")
+ subID := parts[0]
+ if subID == "" {
+ http.Error(w, "Failed to get subID from client URL", http.StatusInternalServerError)
+ return
+ }
}
diff --git a/public/form.js b/public/app.js
similarity index 57%
rename from public/form.js
rename to public/app.js
index 9ad3d0b..f07f19a 100644
--- a/public/form.js
+++ b/public/app.js
@@ -1,81 +1,62 @@
-// TODO
-//
-// 1. Try to disable asking for shipping info (although could be
-// useful to mark as sent).
-//
-// 2. Read about IPN and Webhooks to automate registering process.
+document.addEventListener("DOMContentLoaded", function() {
+ const dialog = document.getElementById("dialog");
+ const overlay = document.getElementById("overlay");
+ const menu = document.getElementById("floatingButtons");
-const clientId = "";
-const OneTimePID = "";
-const PlanID = "";
+ function openDialog() {
+ dialog.style.display = "block";
+ overlay.style.display = "block";
+ menu.style.display = "none";
+ }
-const form = document.getElementById('mainForm');
+ function closeDialog() {
+ dialog.style.display = "none";
+ overlay.style.display = "none";
+ menu.style.display = "block";
+ }
-['name', 'email', 'phone'].forEach(id => {
- const input = document.createElement('input');
- input.type = 'hidden';
- input.name = id;
- input.value = document.getElementById(id).value;
- form.appendChild(input);
+ function togglePaymentMethod(selectedButtonId) {
+ // Deselect all buttons and hide all PayPal buttons
+ document.querySelectorAll('#method-button-container button').forEach(button => { button.classList.remove('active'); });
+ document.querySelectorAll('#paypal-button-container > div').forEach(div => { div.classList.remove('active'); });
+
+ // Select the clicked button and show the corresponding PayPal button
+ const selectedButton = document.getElementById(selectedButtonId);
+ selectedButton.classList.add('active');
+
+ if (selectedButtonId === 'showOneTimeButton') {
+ document.getElementById('paypal-button-container').classList.add('active');
+ document.getElementById('paypal-button-container-order').classList.add('active');
+ } else if (selectedButtonId === 'showSubButton') {
+ document.getElementById('paypal-button-container').classList.add('active');
+ document.getElementById('paypal-button-container-subscribe').classList.add('active');
+ }
+ }
+
+ document.getElementById('showOneTimeButton').addEventListener('click', function() {
+ document.getElementById('warning-message').style.display = 'none';
+ togglePaymentMethod('showOneTimeButton');
+ });
+
+ document.getElementById('showSubButton').addEventListener('click', function() {
+ document.getElementById('warning-message').style.display = 'none';
+ togglePaymentMethod('showSubButton');
+ });
+
+ document.getElementById("openDialogButton").addEventListener("click", openDialog);
+ document.getElementById("cancelDialogButton").addEventListener("click", closeDialog);
});
-function hideDialog() {
- document.getElementById('overlay').style.display = 'none';
- document.getElementById('dialog').style.display = 'none';
- document.getElementById('openDialogButton').style.display = 'block';
-}
-
-function showDialog() {
- document.getElementById('overlay').style.display = 'block';
- document.getElementById('dialog').style.display = 'block';
- document.getElementById('openDialogButton').style.display = 'none';
-}
-
-function togglePaymentMethod(selectedButtonId) {
- // Deselect all buttons and hide all PayPal buttons
- document.querySelectorAll('#method-button-container button').forEach(button => {
- button.classList.remove('active');
- });
- document.querySelectorAll('#paypal-button-container > div').forEach(div => {
- div.classList.remove('active');
- });
-
- // Select the clicked button and show the corresponding PayPal button
- const selectedButton = document.getElementById(selectedButtonId);
- selectedButton.classList.add('active');
-
- if (selectedButtonId === 'showOneTimeButton') {
- document.getElementById('paypal-button-container').classList.add('active');
- document.getElementById('paypal-button-container-order').classList.add('active');
- } else if (selectedButtonId === 'showSubButton') {
- document.getElementById('paypal-button-container').classList.add('active');
- document.getElementById('paypal-button-container-subscribe').classList.add('active');
- }
-}
-
-function isFormValid(form) {
- return form.checkValidity();
-}
window.paypal_order.Buttons({
style: { shape: 'pill', color: 'black', layout: 'vertical', label: 'pay' },
async createOrder() {
try {
- const response = await fetch("/api/orders", {
+ const response = await fetch("/api/order", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
- // use the "body" param to optionally pass additional order information
- // like product ids and quantities
- body: JSON.stringify({
- cart: [
- {
- id: "YOUR_PRODUCT_ID",
- quantity: "YOUR_PRODUCT_QUANTITY",
- },
- ],
- }),
});
const orderData = await response.json();
@@ -97,11 +78,16 @@ window.paypal_order.Buttons({
},
async onApprove(data, actions) {
try {
- const response = await fetch(`/api/orders/${data.orderID}/capture`, {
+ const response = await fetch(`/api/order/${data.orderID}/capture`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
+ body: JSON.stringify(
+ {
+ directory: "tutorias",
+ }
+ ),
});
const orderData = await response.json();
@@ -149,16 +135,24 @@ window.paypal_subscribe.Buttons({
style: { shape: 'pill', color: 'black', layout: 'vertical', label: 'subscribe' },
async createSubscription() {
try {
- const response = await fetch("/api/paypal/create-subscription", {
+ const response = await fetch("/api/paypal/subscribe", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
- body: JSON.stringify({ userAction: "SUBSCRIBE_NOW" }),
+ body: JSON.stringify(
+ {
+ // userAction: "SUBSCRIBE_NOW"
+ directory: "testsite",
+ }
+ ),
});
const data = await response.json();
if (data?.id) {
- resultMessage(`Successful subscription with ID ${data.id}...
`);
+ const approvalUrl = data.links.find(link => link.rel === "approve").href;
+ window.location.href = approvalUrl;
+ resultMessage(`Successful subscription with ID ${approvalUrl}...
`);
+ // resultMessage(`Successful subscription with ID ${data.id}...
`);
return data.id;
} else {
console.error(
@@ -175,8 +169,6 @@ window.paypal_subscribe.Buttons({
{ hideButtons: true },
);
}
- const approvalUrl = data.links.find(link => link.rel === "approve").href;
- window.location.href = approvalUrl;
} catch (error) {
console.error(error);
resultMessage(
@@ -201,35 +193,3 @@ window.paypal_subscribe.Buttons({
}
},
}).render("#paypal-button-container-subscribe"); // Renders the PayPal button
-
-// Example function to show a result to the user. Your site's UI library can be used instead.
-function resultMessage(message) {
- const container = document.querySelector("#checkout");
- container.innerHTML = message;
-}
-
-document.getElementById('showOneTimeButton').addEventListener('click', function() {
- if (isFormValid(form)) {
- document.getElementById('warning-message').style.display = 'none';
- togglePaymentMethod('showOneTimeButton');
- } else {
- document.getElementById('warning-message').style.display = 'block';
- }
-});
-
-document.getElementById('showSubButton').addEventListener('click', function() {
- if (isFormValid(form)) {
- document.getElementById('warning-message').style.display = 'none';
- togglePaymentMethod('showSubButton');
- } else {
- document.getElementById('warning-message').style.display = 'block';
- }
-});
-
-document.getElementById('openDialogButton').addEventListener('click', () => {
- showDialog();
-});
-
-document.getElementById('cancelDialogButton').addEventListener('click', () => {
- hideDialog();
-});
diff --git a/public/index.html b/public/index.html
index b580f42..cf1349d 100644
--- a/public/index.html
+++ b/public/index.html
@@ -10,9 +10,6 @@
-
-
-
@@ -26,68 +23,67 @@
-