Trouble with Stripe Integration using Javascript and Ruby

34 Views Asked by At

I have a form in a Webflow website that dynamically calculates a price depending on selectors the user has chosen.

`<script>
document.addEventListener('DOMContentLoaded', function() {
    const selections = document.querySelectorAll('#language, input[name="turnaround"], #timecoding, input[name="textFormat"], input[name="speakers"]');
    const estimatedPriceElement = document.getElementById('estimatedPrice');
    const form = document.querySelector('form'); // Adjust selector as needed
    let fileSizeInMB = 0; // Initialize file size in MB, will be set by Uploadcare

    // Default multipliers for selections
    let defaultMultipliers = {
        language: 1, // Default multiplier for language
        turnaround: 1, // Default multiplier for turnaround time
        timecoding: 1, // Default multiplier for timecoding
        textFormat: 1, // Default multiplier for text format
        speakers: 1, // Default multiplier for speakers
    };

    function calculatePrice() {
        let priceMultiplier = 1; // Start with a multiplier of 1

        selections.forEach(selection => {
            if ((selection.type === 'radio' && selection.checked) || selection.type === 'select-one') {
                let selectionValue = parseFloat(selection.value);
                if (!isNaN(selectionValue)) {
                    priceMultiplier *= selectionValue;
                } else {
                    priceMultiplier *= defaultMultipliers[selection.name] || 1;
                }
            }
        });

        let finalPrice = fileSizeInMB * priceMultiplier;
        estimatedPriceElement.textContent = `$${isNaN(finalPrice) ? "N/A" : finalPrice.toFixed(2)}`;
    }

    selections.forEach(selection => {
        selection.addEventListener('change', calculatePrice);
    });

    const widget = uploadcare.Widget('#uploadcareWidget');
    widget.onUploadComplete(info => {
        fileSizeInMB = info.size / (1024 * 1024);
        calculatePrice();
    });

    form.addEventListener('submit', function(event) {
        event.preventDefault(); // Prevent default submission
        console.log("Form submit event triggered");
        // Capture the project name from the form
        const projectName = document.getElementById('project-name-2').value;
        const priceText = estimatedPriceElement.textContent;
        const price = parseInt(priceText.replace(/^\$/, '').replace(/,/g, '')) * 100; // Convert to cents
      
       console.log("Calculated price (in cents):", price);

    console.log("About to send fetch request", { price: price });
        fetch('https://test-app-123456-efc60cbf5fa3.herokuapp.com/create-checkout-session', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ price: price, name: projectName }) // Include the project name here
        })
        .then(response => response.json())
        .then(data => {
            // Ensure we're accessing the 'url' property correctly
            if(data.url) {
                window.location.href = data.url; // Redirect to the Stripe checkout page
            } else {
                console.error('Session URL is undefined:', data);
            }
        })
        .catch((error) => {
            console.error('Error:', error);
        });
            });
        });
</script>`

Which is supposed to send a POST request to the server to create "create-checkout-session":

require 'stripe'
require 'sinatra'
require 'sinatra/cors'

set :allow_origin, "****"
set :allow_methods, "GET,POST"
set :allow_headers, "content-type,if-modified-since"
set :expose_headers, "location,link"
set :cors_allow_credentials, true  # If your requests are made with credentials

# This is your test secret API key.
Stripe.api_key = '****'
set :static, true
set :port, ENV['PORT'] || ****

YOUR_DOMAIN = '****'
YOUR_SUCCESS_URL = YOUR_DOMAIN + '/success.html'
YOUR_CANCEL_URL = YOUR_DOMAIN + '/cancel.html'

get '/' do
  'Hello, world!'
end

post '/create-checkout-session' do
  content_type :json
  request_body = JSON.parse(request.body.read)

  puts "Endpoint /create-checkout-session hit"
  
  # Extract the project name from the request
  project_name = request_body['name']

  # Log received price for debugging

  final_price = request_body['price'].to_i

  if final_price <= 0
    status 400 # Bad Request
    return { error: 'Invalid price calculated.' }.to_json
  end
  
  # Create Stripe Checkout session with the final price
  begin
    session = Stripe::Checkout::Session.create({
      payment_method_types: ['card'],
      line_items: [{
        price_data: {
          currency: 'usd',
          product_data: {
            name: project_name || 'Custom Product', # Use the project name or a default
          },
          unit_amount: final_price,
        },
        quantity: 1,
      }],
      mode: 'payment',
      success_url: YOUR_SUCCESS_URL,
      cancel_url: YOUR_CANCEL_URL,
    })

    { url: session.url }.to_json
  rescue Stripe::StripeError => e
    status 500
    { error: e.message }.to_json
  end
end

The problem is the dynamically generated price doesn't show up in the Stripe Checkout page. The page is successfully created, but without the dynamic price.

I've tried adding a "puts" statement to show up in the console logs to check that it's successfully gone through, but it never appears. I also tried to simple change the product name rather than the price dynamically but that didn't work either.

0

There are 0 best solutions below