Как и другие, работающие с платежами Stripe, я получаю сообщение об ошибке «Не может взимать плату с клиента, у которого нет активной карты». Форма не добавляла токен, потому что у javascript не было соответствующего идентификатора в форме, но теперь я получаю ошибку рельсов, и плата не взимается, клиент создается, ошибка указывает на наличие недопустимой строки элемент, когда код для создания клиента и плата за карту не выполняется, заказ создается без ошибок.рельсы 4 полоса платежа, вызывающая недействительную позицию позиции
Заказать Просмотр
<script type="text/javascript" src="https://js.stripe.com/v2/">
$(function(){
Stripe.setPublishableKey('<%= Rails.configuration.stripe[:PUBLISHABLE_KEY] %>');
});
</script>
<div class = "Power Me" >
<fieldset>
<legend> Please enter your details </legend>
<%= render 'form', object: @object %>
</fieldset>
</div>
Вынесено Форма заказа
<%= form_for(@order, :html => {:id => 'payment-form'}) do |f| %>
<% if @order.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@order.errors.count, "error") %> prohibited this order from being saved:</h2>
<ul>
<% @order.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= "Order Total: #{order_total.to_s}" %>
<%= "Order Currency: #{order_currency.to_s}" %>
</div>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :Address_line_1 %><br>
<%= f.text_area :address_line_1 %>
</div>
<div class="field">
<%= f.label :Address_Line_2 %><br>
<%= f.text_area :address_line_2 %>
</div>
<div class="field">
<%= f.label :City %><br>
<%= f.text_area :address_city %>
</div>
<div class="field">
<%= f.label :Region %><br>
<%= f.text_area :address_state %>
</div>
<div class="field">
<%= f.label :Postcode %><br>
<%= f.text_area :address_zip %>
</div>
<div class="field">
<%= f.label :Country %><br>
<%= f.select :address_country, Order::CC_COUNTRIES, prompt: 'Select the country' %>
</div>
<div class="field">
<%= f.label :email %><br>
<%= f.text_field :email, :placeholder => "[email protected]" %>
</div>
<div class="field">
<%= f.label :Payment_Type %><br>
<%= f.select :pay_type, Order::PAYMENT_TYPES, prompt: 'Select a payment method' %>
</div>
<div class="form-row">
<label>Card Number</label>
<input type="text" size="20" autocomplete="off" data-stripe="number" id="number" class="credit-number", placeholder = "**** **** **** ****" pattern="[\d ]*" />
</div>
<div class="form-row">
<label>Security Code/CVC</label>
<input type="text" size="4" autocomplete="off" data-stripe="cvc" id="cvc" class="credit-scurity" placeholder="***" pattern="\d*" />
</div>
<div class="form-row">
<label>Expiration (MM/YYYY)</label>
<input type="text" size="2" data-stripe="exp-month" id="exp-month" class="card-expiry-month" placeholder="MM" pattern="\d*" />
<span>/</span>
<input type="text" size="4" data-stripe="exp-year" id="exp-year" class="card-expiry-year" placeholder="YYYY" pattern="\d*" />
</div>
<div class="actions">
<%= f.submit 'Pay', :class =>"stripe-button" %>
</div>
<% end %>
заказы модели
class Order < ActiveRecord::Base
# attr_accessor :stripeToken
PAYMENT_TYPES = ["credit card"]
CC_COUNTRIES = ["United Kingdom", "France", "Italy"]
validates :name, :address_line_1, :address_zip, :email, presence: true
# validates :pay_type, inclusion: PAYMENT_TYPES
has_many :line_items, dependent: :destroy
def add_line_items_from_cart(cart)
cart.line_items.each do |item|
item.cart_id = nil
line_items << item
end
end
end
Приказы Контроллер
class OrdersController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:new, :create]
before_action :set_order, only: [:show, :edit, :update, :destroy]
# GET /orders
# GET /orders.json
def index
@orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
end
# GET /orders/new
def new
if @cart.line_items.empty?
redirect_to store_url, notice: "Your cart is empty"
return
end
@order = Order.new
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
@order = Order.new(order_params)
@order.add_line_items_from_cart(@cart)
respond_to do |format|
if @order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
format.html { redirect_to @order, notice: 'Order was successfully created.' }
format.json { render action: 'show', status: :created, location: @order }
else
format.html { render action: 'new' }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
Stripe.api_key = "sk_test_BsdqHq0SQuPqHIsm46lcpX4v"
@amount = order_total.to_i * 100
token = params[:stripeToken]
=begin
begin
customer = Stripe::Customer.create(
:email => order_params[:email]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => @amount, # amount in cents, again
:currency => order_currency,
:card => token,
:description => order_params[:email]
)
redirect_to root_path
rescue Stripe::CardError => e
@error = e
end
=end
end
# PATCH/PUT /orders/1
# PATCH/PUT /orders/1.json
def update
respond_to do |format|
if @order.update(order_params)
format.html { redirect_to @order, notice: 'Order was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
@order.destroy
respond_to do |format|
format.html { redirect_to orders_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
@order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:name, :email, :pay_type, :address_line_1, :address_line_2, :address_city, :address_state, :address_zip, :address_country)
end
end
Мой Application Helper
module ApplicationHelper
def order_total
total = LineItem.joins(:product).select("sum(line_items.quantity * products.price) as total").where("cart_id = ?", session[:cart_id]).first.total
end
def order_currency
currency = LineItem.joins(:product).joins(:currency).select("currencies.name as iso_name").where("cart_id = ?", session[:cart_id]).first.iso_name
end
# Returns the full title on a per-page basis.
def full_title(page_title)
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
end
def bootstrap_class_for flash_type
{ success: "alert-success", error: "alert-danger", alert: "alert-warning", notice: "alert-info" }[flash_type] || flash_type.to_s
end
def flash_messages(opts = {})
flash.each do |msg_type, message|
concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} fade in") do
concat message
end)
end
nil
end
# before filters
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
Orders.js
$('#payment-form').submit(function(event) {
var form = $(this);
form.find('button').prop('disabled', true);
Stripe.createToken(form, stripeResponseHandler);
return false;
});
Я бы удостоверился, что stripeToken на самом деле установлен и не равен нулю. Ваш текущий код должен вызывать ошибку «Клиент cus_XXXXXXX не имеет карты с идентификатором tok_YYYYYYYYYYY» –
спасибо, что было частью проблемы – Conor