#johnl_code
1 messages ¡ Page 1 of 1 (latest)
đ Welcome to your new thread!
â˛ď¸ We'll be here soon! We typically respond in a few minutes, but in some cases we might need a bit more time (e.g., server's busy, you've got a complex question, etc.).
âąď¸ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can start a new thread if you have another question.
đ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1259705764717662282
đ Have more to share? Add details, code, screenshots, videos, etc. below.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Fund Account</title>
<meta name="description" content="A demo of a payment on Stripe" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="https://loyae.com/assets/logos/logo.png" type="image/x-icon">
<link rel="stylesheet" href="checkout.css" />
<script src="https://js.stripe.com/v3/"></script>
<script src="checkout.js" defer></script>
</head>
<body>
<!-- Display a payment form -->
<header>
<div class="logo">
<img src="https://www.loyae.com/assets/logos/logo.png" alt="logo" height="30px" width="30px" style="margin: 3px;"/>
Loyae
</div>
</header>
<form id="payment-form">
<h2>Create/Fund Account (Generate 6-Digit Code)</h2>
Amount: <span id="amount">$0.00</span>
<br/><br/>
Email: <input type="email" id="email" name="email" required><br/><br/>
First Name: <input type="text" id="fname" name="fname" required><br/><br/>
Last Name: <input type="text" id="lname" name="lname" required><br/><br/>
<br/><br/>
<div id="payment-element">
<!--Stripe.js injects the Payment Element-->
</div>
<button id="submit">
<div class="spinner hidden" id="spinner"></div>
<span id="button-text">Pay now</span>
</button>
<div id="payment-message" class="hidden"></div>
</form>
</body>
</html>
Server:
func handleCreatePaymentIntent(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
///I only get these values when it's previlled on load. not when submitted'
var req struct {
Cost float64 `json:"cost"`
Fname string `json:"fname"`
Lname string `json:"lname"`
Email string `json:"email"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Printf("json.NewDecoder.Decode: %v", err)
return
}
log.Printf("%v",req.Cost, req.Fname)
// Create a PaymentIntent with amount and currency
params := &stripe.PaymentIntentParams{
Amount: stripe.Int64((int64)(req.Cost*100)),
Currency: stripe.String(string(stripe.CurrencyUSD)),
// In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
AutomaticPaymentMethods: &stripe.PaymentIntentAutomaticPaymentMethodsParams{
Enabled: stripe.Bool(true),
},
}
pi, err := paymentintent.New(params)
log.Printf("pi.New: %v", pi.ClientSecret)
if err != nil {
log.Println("ERROR")
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Printf("pi.New: %v", err)
return
}
log.Println("here")
var fundCode string = genCode()
// Parse form data
err = r.ParseForm()
if err != nil {
http.Error(w, "Error parsing form", http.StatusBadRequest)
return
}
// email := "stripe@loyae.com"
// fname := "John"
// lname := "Lins"
// amount := 10.0
// Extract customer information from form
fname := req.Fname
lname := req.Lname
email := req.Email
amount := req.Cost
log.Println(req)
///....add funds to account bwlow
}
Part of JS:
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
const email = document.getElementById('email').value;
const fname = document.getElementById('fname').value;
const lname = document.getElementById('lname').value;
const response = await fetch("/create-payment-intent", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
cost,
email,
fname,
lname
}),
});
const { clientSecret } = await response.json();
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: "https://loyae.com?code=ABC123",
},
});
if (error) {
if (error.type === "card_error" || error.type === "validation_error") {
showMessage(error.message);
} else {
showMessage("An unexpected error occurred.");
}
setLoading(false);
}
}
// Fetches the payment intent status after payment submission
async function checkStatus() {
const clientSecret = new URLSearchParams(window.location.search).get(
"payment_intent_client_secret"
);
if (!clientSecret) {
return;
}
const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret);
switch (paymentIntent.status) {
case "succeeded":
showMessage("Payment succeeded!");
break;
case "processing":
showMessage("Your payment is processing.");
break;
case "requires_payment_method":
showMessage("Your payment was not successful, please try again.");
break;
default:
showMessage("Something went wrong.");
break;
}
}
Name and email can be set under defaultValues.billingDetails: https://docs.stripe.com/js/elements_object/create_payment_element when creating a Payment Intent with StripeJS
So I added this to the JS, but how do I receive it on the server side?