Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Heroku web地址时条带webhook错误400错误请求_Heroku_Stripe Payments - Fatal编程技术网

使用Heroku web地址时条带webhook错误400错误请求

使用Heroku web地址时条带webhook错误400错误请求,heroku,stripe-payments,Heroku,Stripe Payments,我已经在我的Ruby on Rails网站中集成了Stripe。如果我用ngrok测试它,一切正常,但是当我使用heroku网址作为stripe webhook时,它抛出了一个400错误请求错误。如果我查阅文档,就会发现缺少必需的参数。这可能是因为我没有ssl证书吗?我在Heroku上是免费的,但是Heroku的网址以https开头。。。那不安全吗?我已经在heroku网站上输入了可发布、保密和签名密钥 Routes.rb Rails.application.routes.draw do

我已经在我的Ruby on Rails网站中集成了Stripe。如果我用ngrok测试它,一切正常,但是当我使用heroku网址作为stripe webhook时,它抛出了一个400错误请求错误。如果我查阅文档,就会发现缺少必需的参数。这可能是因为我没有ssl证书吗?我在Heroku上是免费的,但是Heroku的网址以https开头。。。那不安全吗?我已经在heroku网站上输入了可发布、保密和签名密钥

Routes.rb

Rails.application.routes.draw do

  mount StripeEvent::Engine, at: '/stripe-webhooks'

  devise_for :users, controllers: {
    sessions: 'users/sessions',
    passwords: 'users/passwords',
    registrations: 'users/registrations'
  }

  scope '(:locale)', locale: /en|de/ do
    root to: 'pages#home'
    get '/about', to: 'pages#about', as: 'about'
    get '/shipping', to: 'pages#shipping', as: 'shipping'
    get '/privacypolicy', to: 'pages#privacypolicy', as: 'privacypolicy'
    get '/termsandconditions', to: 'pages#termsandconditions', as: 'termsandconditions'
    get '/success', to: 'pages#success'

    get 'contact', to: 'contacts#new', as: 'contact'


    resources :contacts, only: [:new, :create]


    get 'cart', to: 'carts#show', as: 'cart'
    delete 'carts', to: 'carts#destroy'
    delete 'cart_items/:id', to: 'cart_items#destroy', as: 'cart_items'

    resources :cart_items, only: [:create, :destroy] do
      member do
        get :add_quantity
        get :reduce_quantity
      end
    end

    post 'without-login', to: 'orders#without_login'

    resources :users
    resources :products do
      resources :cart_items, only: [:create]
    end
    resources :categories
    resources :orders, only: [:new, :show, :create] do
      resources :payments, only: :new
    end
  end
end
模式:

create_table "orders", force: :cascade do |t|
    t.string "product_sku"
    t.integer "amount_cents", default: 0, null: false
    t.string "checkout_session_id"
    t.bigint "user_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "first_name"
    t.string "last_name"
    t.string "street_name"
    t.string "house_number"
    t.string "postal_code"
    t.string "city"
    t.string "country"
    t.string "email"
    t.text "comment"
    t.integer "price_cents", default: 0, null: false
    t.boolean "termsandconditions"
    t.string "status", default: "pending"
    t.index ["user_id"], name: "index_orders_on_user_id"
  end
payments new.html.erb:

<script src="https://js.stripe.com/v3/"></script>
<script>
  const paymentButton = document.getElementById('pay-stripe');
  paymentButton.addEventListener('click', () => {
    const stripe = Stripe('<%= ENV['STRIPE_PUBLISHABLE_KEY'] %>');
    stripe.redirectToCheckout({
      sessionId: '<%= @order.checkout_session_id %>'
    });
  });
  </script>

如果从Stripe返回签名验证错误,StripeEvent将以400错误响应(请参阅)


您应该仔细检查您的签名密码,确保它与heroku webhook的密码匹配,而不是与ngrok webhook的密码匹配。

如果从Stripe返回签名验证错误,StripeEvent似乎会响应400错误(请参阅)


你应该仔细检查你的签名密码,确保它与你的heroku webhook的密码匹配,而不是与你的ngrok webhook的密码匹配。

你能包括你的webhook的代码以及你看到的错误消息吗?你能包括你的webhook的代码以及你看到的错误消息吗?是的,我检查了签名密码。它在heroku配置和.env文件中都是正确的。我实际上删除了ngrok webhook,以防它会引起任何问题。所以现在我只有一个heroku webhook,3个密钥是正确的。你有可能有任何后端日志表明发生了什么吗?是的,我检查了签名秘密。它在heroku配置和.env文件中都是正确的。我实际上删除了ngrok webhook,以防它会引起任何问题。所以现在我只有一个heroku webhook,而且3个键都是正确的。你有没有可能有任何后端日志表明发生了什么?
class OrdersController < ApplicationController
  skip_before_action :authenticate_user!

  def new
    @order = Order.new
    @cart = current_cart
    # Storing the two constants in a gon variable to send data to the JS file
    gon.ceilings = Product::ORDER_CEILINGS
    gon.prices = Product::SHIPPING_PRICES
  end

  def create
    @order = Order.new(order_params)
    @cart = current_cart
    @cart.cart_items.each { |item| @order.cart_items << item }
    @order.amount = @cart.total_price

    shipping_costs = calculate_shipping_costs(params[:order][:country], @order.amount)
    @order.amount += Monetize.parse(shipping_costs)

    @order.user = current_user if current_user
    @order.email = current_user.email if current_user

    if @order.save
      save_user_address if params[:save_address].to_i == 1
      trigger_stripe(shipping_costs)
      cleanup_cart
      redirect_to new_order_payment_path(@order)
    else
      @cart = @current_cart
      render :new
    end
  end

  def show
    if current_user
      @order = current_user.orders.find(params[:id])
    else
      @order = Order.find(params[:id])
    end

    mail = OrderMailer.with(order: @order).confirmation
    mail.deliver_now
    # may need to change this for guest users- must check that their email address is saved to the database
  end

  def index
    @orders = current_user.orders
  end

  def without_login
    session[:without_login] = true
    redirect_to new_order_path
  end

  def submit
  end


  private

  def order_params
    params.require(:order).permit(:first_name, :last_name, :email, :street_name, :house_number, :postal_code, :city, :country, :comment)
  end

  def trigger_stripe(shipping_costs)
    stripe_session = Stripe::Checkout::Session.create(
      payment_method_types: ['card'],
      customer_email: customer_email,
      locale: I18n.locale.to_s,
      line_items: stripe_line_items(@order.cart_items, shipping_costs),
      success_url: order_url(@order),
      cancel_url: order_url(@order)
    )
    @order.update(checkout_session_id: stripe_session.id)
  end

  def cleanup_cart
    @cart.cart_items.each { |item| item.update(cart_id: nil) }
    Cart.destroy(session[:cart_id])
    session[:cart_id] = nil
  end

  def stripe_line_items(order_items, shipping_costs)
    all_items = []

    order_items.each do |item|
      item_hash = {
        name: item.product.title,
        amount: (item.total_price.amount * 100).to_i / item.quantity,
        quantity: item.quantity,
        currency: 'eur'
       }
       all_items.push(item_hash)
    end

    shipping_item_hash = {
      name: "Delivery",
      amount: (shipping_costs * 100).to_i,
      quantity: 1,
      currency: 'eur'
    }
    all_items.push(shipping_item_hash)

    return all_items
  end

  def customer_email
    current_user ? current_user.email : nil
  end

  def save_user_address
    if @order.user != nil
      current_user.attributes = @order.attributes.except("id", "email", "status", "comment", "amount_cents", "amount_currency", "checkout_session_id", "user_id", "updated_at", "created_at")
      current_user.save
    end
  end
class StripeCheckoutSessionService
  def call(event)
    order = Order.find_by(checkout_session_id: event.data.object.id)
    order.update(status: 'paid')
  end
end
<script src="https://js.stripe.com/v3/"></script>
<script>
  const paymentButton = document.getElementById('pay-stripe');
  paymentButton.addEventListener('click', () => {
    const stripe = Stripe('<%= ENV['STRIPE_PUBLISHABLE_KEY'] %>');
    stripe.redirectToCheckout({
      sessionId: '<%= @order.checkout_session_id %>'
    });
  });
  </script>
Rails.configuration.stripe = {
  publishable_key: ENV['STRIPE_PUBLISHABLE_KEY'],
  secret_key:      ENV['STRIPE_SECRET_KEY'],
  signing_secret:  ENV['STRIPE_WEBHOOK_SECRET_KEY']
}

Stripe.api_key = Rails.configuration.stripe[:secret_key]

StripeEvent.signing_secret = Rails.configuration.stripe[:signing_secret]

StripeEvent.configure do |events|
  events.subscribe 'checkout.session.completed', StripeCheckoutSessionService.new
end