Started Stripe Integration
This commit is contained in:
@@ -5,6 +5,10 @@ const QRCode=require('qrcode');
|
|||||||
const crypto=require('crypto');
|
const crypto=require('crypto');
|
||||||
const path=require('path');
|
const path=require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
require('dotenv').config();
|
||||||
|
const port=process.env.PORT||3000;
|
||||||
|
const base_url = process.env.BASE_URL;
|
||||||
|
const stripe=require('stripe')(process.env.STRIPE_SECRET_KEY);
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
app.set('view engine','ejs');
|
app.set('view engine','ejs');
|
||||||
@@ -63,6 +67,12 @@ const QRSalt ="!SaltyMagic5392370662";
|
|||||||
// CLAIM ticket email
|
// CLAIM ticket email
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Stripe Integration:
|
||||||
|
// The Stripe CLI is configured for Andrew Tepper with account id acct_1QZlMSCHHjDgpHos
|
||||||
|
// Login on stripe.com is tickets@fallsonfire.net Password is x65195241X.1
|
||||||
|
//
|
||||||
|
|
||||||
function base64ToBase64Url(base64) {
|
function base64ToBase64Url(base64) {
|
||||||
return base64
|
return base64
|
||||||
.replace(/\+/g, '-') // Replace '+' with '-'
|
.replace(/\+/g, '-') // Replace '+' with '-'
|
||||||
@@ -583,6 +593,48 @@ app.post('/update-setting', requireSuperUser, (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
app.get('/checkout', (req, res) => {
|
||||||
|
// We’ll render a payment form here
|
||||||
|
res.render('checkout2');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/charge', async (req, res) => {
|
||||||
|
try {
|
||||||
|
// Token or Payment Method ID from the client
|
||||||
|
const paymentMethodId = req.body.paymentMethodId;
|
||||||
|
|
||||||
|
// Create a PaymentIntent on the server
|
||||||
|
const return_url=base_url+'/mytickets';
|
||||||
|
const paymentIntent = await stripe.paymentIntents.create({
|
||||||
|
amount: 1999, // Amount in cents (e.g., $19.99)
|
||||||
|
currency: 'usd',
|
||||||
|
payment_method: paymentMethodId,
|
||||||
|
confirmation_method: 'automatic',
|
||||||
|
confirm: true, // Attempt to confirm the payment immediately
|
||||||
|
return_url: return_url,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check status of payment intent
|
||||||
|
if (paymentIntent.status === 'requires_action') {
|
||||||
|
// Additional action is required (e.g. 3D Secure)
|
||||||
|
res.json({
|
||||||
|
requiresAction: true,
|
||||||
|
paymentIntentClientSecret: paymentIntent.client_secret,
|
||||||
|
});
|
||||||
|
} else if (paymentIntent.status === 'succeeded') {
|
||||||
|
// Payment is complete
|
||||||
|
console.log("Returning json success: true");
|
||||||
|
res.json({ success: true, redirect_url: return_url });
|
||||||
|
} else {
|
||||||
|
res.json({ error: 'Invalid PaymentIntent status' });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Payment error:', error);
|
||||||
|
res.json({ error: error.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
app.listen(PORT, () => {
|
app.listen(PORT, () => {
|
||||||
console.log(`Server is running at http://localhost:${PORT}`);
|
console.log(`Server is running at http://localhost:${PORT}`);
|
||||||
|
|||||||
80
views/checkout.ejs
Normal file
80
views/checkout.ejs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Checkout</title>
|
||||||
|
<link rel="stylesheet" href="/styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Checkout</h1>
|
||||||
|
<form id="payment-form">
|
||||||
|
<!-- Stripe Elements will inject the Card Element here -->
|
||||||
|
<div id="card-element"></div>
|
||||||
|
<button id="submit-button" type="submit">Pay $19.99</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Stripe.js -->
|
||||||
|
<script src="https://js.stripe.com/v3/"></script>
|
||||||
|
<script>
|
||||||
|
// Initialize Stripe
|
||||||
|
const stripe = Stripe("pk_test_51QZlMSCHHjDgpHosSrxdAEHgUCBmyhXCihiELaXjxcXzGtIY9Vw1YgOeiJfNpn7P9WkcMj5FWk13cDRavez3HhyN0001mNBtXW");
|
||||||
|
|
||||||
|
// Set up Stripe.js and Elements
|
||||||
|
const elements = stripe.elements();
|
||||||
|
const cardElement = elements.create("card");
|
||||||
|
cardElement.mount("#card-element");
|
||||||
|
|
||||||
|
const paymentForm = document.getElementById("payment-form");
|
||||||
|
paymentForm.addEventListener("submit", async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// 1. Create a PaymentMethod
|
||||||
|
const { paymentMethod, error } = await stripe.createPaymentMethod({
|
||||||
|
type: "card",
|
||||||
|
card: cardElement,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
alert(error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Send PaymentMethod ID to server
|
||||||
|
const response = await fetch("/charge", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ paymentMethodId: paymentMethod.id }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const responseData = await response.json();
|
||||||
|
|
||||||
|
if (responseData.error) {
|
||||||
|
console.error(responseData.error);
|
||||||
|
alert(responseData.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseData.requiresAction) {
|
||||||
|
// 3. Handle Additional Action if required (e.g., 3DS)
|
||||||
|
const { error: confirmError } = await stripe.confirmCardPayment(
|
||||||
|
responseData.paymentIntentClientSecret
|
||||||
|
);
|
||||||
|
|
||||||
|
if (confirmError) {
|
||||||
|
console.error(confirmError);
|
||||||
|
alert(confirmError.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("Payment succeeded!");
|
||||||
|
// redirect or show success message
|
||||||
|
window.location.href = "/";
|
||||||
|
} else if (responseData.success) {
|
||||||
|
// Payment succeeded without additional action
|
||||||
|
alert("Payment succeeded!");
|
||||||
|
window.location.href = "/";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
103
views/checkout2.ejs
Normal file
103
views/checkout2.ejs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Your Ticket</title>
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%- include('partials/nav') %>
|
||||||
|
<div class="content">
|
||||||
|
<form id="payment-form">
|
||||||
|
|
||||||
|
<!-- Stripe Elements will inject the Card Element here -->
|
||||||
|
|
||||||
|
<label for="card-number-element">Card Number</label>
|
||||||
|
<div id="card-number-element"></div>
|
||||||
|
|
||||||
|
<label for="card-expiry-element">Expiration Date</label>
|
||||||
|
<div id="card-expiry-element"></div>
|
||||||
|
|
||||||
|
<label for="card-cvc-element">CVC</label>
|
||||||
|
<div id="card-cvc-element"></div>
|
||||||
|
|
||||||
|
<label for="card-postal-element">ZIP Code</label>
|
||||||
|
<div id="card-postal-element"></div>
|
||||||
|
|
||||||
|
<button id="submit-button" type="submit">Pay $19.99</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<!-- Stripe.js -->
|
||||||
|
<script src="https://js.stripe.com/v3/"></script>
|
||||||
|
<script>
|
||||||
|
// Initialize Stripe
|
||||||
|
const stripe = Stripe("pk_test_51QZlMSCHHjDgpHosSrxdAEHgUCBmyhXCihiELaXjxcXzGtIY9Vw1YgOeiJfNpn7P9WkcMj5FWk13cDRavez3HhyN0001mNBtXW");
|
||||||
|
|
||||||
|
// Set up Stripe.js and Elements
|
||||||
|
const elements = stripe.elements();
|
||||||
|
const cardNumberElement = elements.create('cardNumber');
|
||||||
|
const cardExpiryElement = elements.create('cardExpiry');
|
||||||
|
const cardCvcElement = elements.create('cardCvc');
|
||||||
|
const cardPostalElement = elements.create('postalCode');
|
||||||
|
|
||||||
|
cardNumberElement.mount('#card-number-element');
|
||||||
|
cardExpiryElement.mount('#card-expiry-element');
|
||||||
|
cardCvcElement .mount('#card-cvc-element');
|
||||||
|
cardPostalElement.mount('#card-postal-element');
|
||||||
|
|
||||||
|
const paymentForm = document.getElementById("payment-form");
|
||||||
|
paymentForm.addEventListener("submit", async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// 1. Create a PaymentMethod
|
||||||
|
const { paymentMethod, error } = await stripe.createPaymentMethod({
|
||||||
|
type: "card",
|
||||||
|
card: cardElement,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
alert(error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Send PaymentMethod ID to server
|
||||||
|
const response = await fetch("/charge", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ paymentMethodId: paymentMethod.id }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const responseData = await response.json();
|
||||||
|
|
||||||
|
if (responseData.error) {
|
||||||
|
console.error(responseData.error);
|
||||||
|
alert(responseData.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseData.requiresAction) {
|
||||||
|
// 3. Handle Additional Action if required (e.g., 3DS)
|
||||||
|
const { error: confirmError } = await stripe.confirmCardPayment(
|
||||||
|
responseData.paymentIntentClientSecret
|
||||||
|
);
|
||||||
|
|
||||||
|
if (confirmError) {
|
||||||
|
console.error(confirmError);
|
||||||
|
alert(confirmError.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("Payment succeeded");
|
||||||
|
// redirect or show success message
|
||||||
|
window.location.href = responseData.redirect_url;
|
||||||
|
} else if (responseData.success) {
|
||||||
|
// Payment succeeded without additional action
|
||||||
|
alert("Payment succeeded.");
|
||||||
|
window.location.href = responseData.redirect_url;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user