在ruby中尝试将动态总计传递给amount时,出现创建付款意图的500错误

o7jaxewo  于 2023-05-22  发布在  Ruby
关注(0)|答案(1)|浏览(86)

因此,我试图使传递的动态总额传递到ruby脚本中的创建支付意图中的金额,并且我在创建支付意图中得到500错误,并且它说payment.js中的fetch创建支付意图存在错误(总额正确传递)

document.addEventListener('DOMContentLoaded', async () => {
  // Fetch publishable key from the server
  const { publishableKey } = await fetch('/config').then(r => r.json());
  const stripe = Stripe(publishableKey);

  // Fetch the total amount from the DOM
  const totalSpan = document.getElementById("total");
  const total = parseFloat(totalSpan.textContent.replace("$", ""));
  console.log(total)
  
  // Create payment intent on the server
  const { clientSecret } = await fetch("/create-payment-intent", {
    method: "POST",
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ total: total })
  }).then(r => r.json());  

  // Render payment element
  const elements = stripe.elements({ clientSecret });
  const paymentElement = elements.create('payment', {
    fields: {
      billingDetails: {
        name: 'auto',
        email: 'auto',
      }
    }
  });
  paymentElement.mount('#payment-element');

  const nameInput = document.getElementById('name');
  const emailInput = document.getElementById('email');

  const form = document.getElementById('payment-form');
  form.addEventListener('submit', async (e) => {
    e.preventDefault();

    // Get the values from the input fields
    const name = nameInput.value;
    const email = emailInput.value;

    // Confirm the payment and redirect to the return URL
    const { error } = await stripe.confirmPayment({
      elements,
      confirmParams: {
        return_url: window.location.origin + '/complete',
        payment_method_data: {
          billing_details: {
            name: name,
            email: email,
          }
        },
      },
    });

    if (error) {
      const messages = document.getElementById('error-messages');
      messages.innerText = error.message;
    }
  });
});

这是我的html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Stripe Sample</title>
    <meta name="description" content="A demo of Stripe" />

    <link rel="icon" href="favicon.ico" type="image/x-icon" />
    <link rel="stylesheet" href="css/normalize.css" />
    <link rel="stylesheet" href="css/global.css" />
    <script src="https://js.stripe.com/v3/"></script>
    <script src="./payment.js"></script>
  </head>

  <body>   
    <div class="sr-root">
      <div class="sr-main">
        <h1>Pay with a bunch of payment option</h1>

        <form id="payment-form" method="POST">
          <input type="text" name="email" id="email" placeholder="E-Mail" required>
          <input type="text" name="name" id="name" placeholder="Full Name" required>
    
          <div id="payment-element"></div>

          <span name="total" id="total" class="total"></span>   
          <button>Pay</button><!--Make functional-->

          <!--Make total price hidden and that total of this is same as in checkout and that its connected to ruby-->
          <div id="error-messages"></div>
        </form>        
      </div>
    </div>
    <script>
      // Get the value of the "total" parameter from the URL
      const urlParams = new URLSearchParams(window.location.search);
      const total = urlParams.get("total");
    
      // Set the total value in the DOM
      const totalSpan = document.getElementById("total");
      totalSpan.textContent = total;
    
      // Update the form action URL to include the total as a query parameter
      const form = document.getElementById('payment-form');
      form.action = `/create-payment-intent?total=${total}`;
    </script>    
</body>
</html>

这是我的ruby:

# frozen_string_literal: true
require 'stripe'
require 'sinatra'
require 'dotenv'
require 'mail'
require 'nokogiri'
require 'open-uri'
require 'logger'
require 'json'
enable :sessions  

# Replace if using a different env file or config
Dotenv.load

# For sample support and debugging, not required for production:
Stripe.set_app_info(
  'stripe-samples/<name-of-sample>/[<name-of-integration-type>]',
  version: '0.0.1',
  url: 'https://github.com/stripe-samples'
)
Stripe.api_version = '2020-08-27'
Stripe.api_key = ENV['STRIPE_SECRET_KEY']

set :static, true
set :public_folder, File.join(File.dirname(__FILE__), ENV['STATIC_DIR'])
set :port, 4242

# Define a global array to store the products added to cart
$cart_items = []

# Define a route to add products to the cart
post '/cart' do
  request.body.rewind
  product = JSON.parse(request.body.read)
  $cart_items.push(product)
  content_type :json
  { cart_size: $cart_items.size }.to_json
end

# Define a route to get the cart items
get '/cart' do
  content_type :json
  $cart_items.to_json
end

# Create a new logger instance that logs to a file named 'development.log'
logger = Logger.new('C:\s\starter-ruby\server\logs/development.log')

# Set the logger to be used by Sinatra
set :logger, logger

get '/' do
  logger.info 'Hello World!'
  content_type 'text/html'
  send_file File.join(settings.public_folder, 'index.html')
end

get '/config' do
  content_type 'application/json'
  {
    publishableKey: ENV['STRIPE_PUBLISHABLE_KEY'],
  }.to_json
end    

post '/create-payment-intent' do
  total = data['total'].to_i

  payment_intent = Stripe::PaymentIntent.create({
    amount: total,
    currency: 'usd',
    automatic_payment_methods: { enabled: true }
  })

  { clientSecret: payment_intent.client_secret }.to_json
end      

post '/webhook' do
  # You can use webhooks to receive information about asynchronous payment events.
  # For more about our webhook events check out https://stripe.com/docs/webhooks.
  webhook_secret = ENV['STRIPE_WEBHOOK_SECRET']
  payload = request.body.read
  if !webhook_secret.empty?
    # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(
        payload, sig_header, webhook_secret
      )
    rescue JSON::ParserError => e
      # Invalid payload
      status 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      puts '⚠️  Webhook signature verification failed.'
      status 400
      return
    end
  else
    data = JSON.parse(payload, symbolize_names: true)
    event = Stripe::Event.construct_from(data)
  end

  case event.type
  when 'payment_intent.succeeded'
    puts '💰  Payment received!'
  end

  content_type 'application/json'
  {
    status: 'success'
  }.to_json
end

我用这个教程构建了它:https://youtu.be/OGmEZbLMjOs,我发现这一点,但这是与结帐会话,而不是付款意图https://youtu.be/1-olKBnmC84和有人建议我检查这个https://stripe.com/docs/products-prices/pricing-models#variable-pricing链接,但我不能用我的代码弄清楚!

o2g1uqev

o2g1uqev1#

通过查看Ruby代码和HTML,我可以确定可能导致创建付款意图的500错误的几个问题。
1./create-payment-intent路由中缺少数据变量:在/create-payment-intent路由中,您引用了data ['total']来检索总金额,但没有定义data变量。要解决这个问题,您需要将请求主体解析为JSON以访问total值。修改代码如下:
post '/create-payment-intent' do request_payload = JSON.parse(request.body.read)total = request_payload['total'].to_i
payment_intent = Stripe::PaymentIntent.create({ amount:货币共计:'usd',automatic_payment_methods:{ enabled:true } })
{ clientSecret:payment_intent.client_secret }.to_json end

  1. JavaScript中的端点路径不正确:在你的JavaScript代码中,你向/create-payment-intent发出一个POST请求:
    const { clientSecret } = await fetch(“/create-payment-intent”,{ // ...});
    然而,在Ruby代码中,实际的路由被定义为post '/create-payment-intent' do。确保JavaScript和Ruby代码中的端点路径匹配。
    应用这些更改后,请再次尝试运行代码,以查看500错误是否已解决。如果您遇到任何其他问题或错误消息,请提供更多详细信息,我很乐意为您提供进一步帮助。

相关问题