如何在Node.js中通过Stripe动态获取HTML金额实现自定义扣费
Let's break down how to grab that dynamic amount from your new_text element and pass it to your Node.js backend for Stripe charges. I'll walk you through each step with code fixes tailored to your setup.
Step 1: Update Frontend to Capture & Pass the Dynamic Amount
First, we need to:
- Grab the amount from the
new_textspan - Convert it to Stripe's required format (integer representing the smallest currency unit, e.g., $100 becomes 10000 cents)
- Send this amount along with the Stripe token to your backend
Modified HTML (Clean Up Hardcoded Input)
We'll remove the static hidden input and send the dynamic amount directly via AJAX:
<form action="/charge" method="post" id="payment-form"> <div class="form-row"> <label for="card-element"> Credit or debit card </label> <div id="card-element"> <!-- Stripe Element will be inserted here --> </div> <div id="card-errors"></div> </div> <!-- Remove hardcoded totalAmount input --> <button>Submit Payment</button> </form>
Modified Frontend Script
Update your form submission logic to capture the dynamic amount and send it with the token:
// Handle form submission var form = document.getElementById('payment-form'); form.addEventListener('submit', function(event) { event.preventDefault(); // 1. Grab the dynamic amount from new_text const rawAmount = document.getElementById('new_text').textContent; const totalAmount = parseFloat(rawAmount); // Basic validation to catch invalid values if (isNaN(totalAmount) || totalAmount <= 0) { document.getElementById('card-errors').textContent = "Invalid amount. Please check your service selection."; return; } // 2. Convert to Stripe's required format (cents) const stripeAmount = Math.round(totalAmount * 100); stripe.createToken(card).then(function(result) { if (result.error) { var errorElement = document.getElementById('card-errors'); errorElement.textContent = result.error.message; } else { // Pass both token and amount to our handler stripeTokenHandler(result.token, stripeAmount); } }); }); function stripeTokenHandler(token, amount) { // 3. Send token + dynamic amount via AJAX var formData = JSON.stringify({ mytoken: token.id, amount: amount // Include the calculated amount here }); $.ajax({ type: "POST", url: "/charge", data: formData, success: function(){alert("Payment successful!")}, error: function(){alert("Payment failed. Please try again.")}, dataType: "json", contentType: "application/json" }); // Remove form.submit() - this was causing duplicate requests! }
Step 2: Update Backend to Receive & Use the Dynamic Amount
Adjust your Node.js backend to accept the dynamic amount, validate it, and process the charge safely:
const express = require('express'); const stripe = require('stripe')('your_stripe_secret_key'); // Replace with your actual secret key const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); app.use(express.static('public')); // Remove the unnecessary GET /charge route - it's not needed for the payment flow // app.get('/charge', (req, res) => { res.send(); }); // Charge route with proper error handling and dynamic amount support app.post('/charge', async (req, res) => { try { const { mytoken, amount } = req.body; // Validate incoming data to avoid invalid charges if (!mytoken || typeof amount !== 'number' || amount <= 0) { return res.status(400).send('Invalid payment data'); } // Create customer and process charge const customer = await stripe.customers.create({ email: "random@gmail.com", // Consider adding an email input to your form instead of hardcoding! source: mytoken }); const charge = await stripe.charges.create({ amount: amount, description:'specified service description here', currency:'usd', customer: customer.id }); res.send('success'); } catch (error) { // Log errors for debugging console.error('Stripe charge error:', error); // Send meaningful error to frontend res.status(500).send('Payment failed: ' + error.message); } }); const port = process.env.PORT || 5000; app.listen(port, () => { console.log(`Server started on port ${port}`); });
Key Tips for Stripe/Node.js Beginners
- Stripe Amount Rules: Always use integers for the
amountfield (e.g., $10.50 becomes 1050 cents) to avoid floating-point errors. - Avoid Duplicate Requests: Your original code had both
$.ajax()andform.submit()- this would send two identical requests to/charge, so we removedform.submit(). - Validation: Validate input on both frontend and backend to catch invalid values before they reach Stripe.
- Error Handling: Using
try/catchin the backend helps you debug issues and send clear feedback to users.
Bonus: Add User Email Input (Optional)
To make your flow more robust, add an email input to your form and pass it to the backend instead of hardcoding:
<div class="form-row"> <label for="email">Email Address</label> <input type="email" id="email" name="email" required> </div>
Then update your frontend submit handler to include it:
// In form submit handler const userEmail = document.getElementById('email').value; // In formData var formData = JSON.stringify({ mytoken: token.id, amount: amount, email: userEmail });
And modify the backend to use the user's email:
const { mytoken, amount, email } = req.body; // ... const customer = await stripe.customers.create({ email: email, source: mytoken });
内容的提问来源于stack exchange,提问作者mur7ay

