Моя проблема в том, что у меня есть форма, которая отправляется с пустым полем кредитной карты.
У меня есть поле кредитной карты в сочетании с другой формой, в которой заключается проблема.
Итак, мой вопрос: как мне потребовать поле кредитной карты с помощью JS или Ruby?
Вот форма и javascript:
<%= form_for([@listing, @order], html: {id: "Orders"}) do |form| %>
<div class = "form-group">
<%= form.label :name, "Who's the Order for?" %>
<%= form.text_field :name, class: "form-control", required: true %>
</div>
<script
src = "https://js.stripe.com/v3/">
</script>
<div class = "form-row">
<label for = "card-element">
Credit or debit card
</label>
<div id = "card-element" class = "form-control">
</div>
<div id = "card-errors" role = "alert"></div>
</div>
<br>
<div class = "form-group">
<%= form.submit "asdf", class:"ripple-effect", id:"button-element" %>
<!-- <button id = "button-element" class = "ripple-effect">Submit Payment for </button> EITHER OF THESE BUTTONS WORK WITH THE FORM-->
</div>
<span class = "token"></span>
</form>
<% end %>
<script>
var stripe = Stripe('pk_test_413253....f0B8');
var elements = stripe.elements();
var style = {
base: {
color: '#32325d',
lineHeight: '24px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
var card = elements.create('card', {style: style});
card.mount('#card-element');
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
var form = document.getElementById('payment_form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server
stripeTokenHandler(result.token);
}
});
});
function stripeTokenHandler(token) {
var form = document.getElementById('payment_form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
["brand", "exp_month", "exp_year", "last4"].forEach(function(field) {
addFieldToForm(form, token, field);
});
// Submit the form
form.submit();
}
</script>
Вот метод создания контроллера заказов, который теперь немного запутан:
def create
@order = Order.new(order_params)
@listing = Listing.find(params[:listing_id])
@seller = @listing.user
@order.listing_id = @listing.id
@order.buyer_id = current_user.id
@order.seller_id = @seller.id
if @order.valid?
begin
@amount = 500
token = params[:stripeToken]
payment_form = params[:payment_form]
charge = Stripe::Charge.create({
:source => 'tok_visa',
:amount => @amount,
:description => 'Rails Stripe customer',
:currency => 'usd'
})
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
end
respond_to do |format|
if @order.save
if user_signed_in?
@user = current_user
OrderMailer.order_email(@user, @order).deliver
format.html { redirect_to @order, notice: 'Order was successfully created.' }
format.json { render :show, status: :created, location: @order }
else
format.html { render :new }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
if buyer_signed_in?
@user = current_buyer
OrderMailer.order_email(@user, @order).deliver
format.html { redirect_to @listing, notice: 'Order was successfully created.' }
format.json { render :show, status: :created, location: @order }
else
format.html { render :new }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
end
def update
respond_to do |format|
if @order.update(order_params)
if user_signed_in?
format.html { redirect_to @order, notice: 'Order was successfully uploaded.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
if buyer_signed_in?
format.html { redirect_to @order, notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
end
def destroy
@order.destroy
respond_to do |format|
format.html { redirect_to orders_url, notice: 'Order was successfully destroyed.' }
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
def order_params
params.require(:order).permit(:name, :address, :city, :state, :image, :video, :description, :order_status)
end
def deny_to_visitors
redirect_to root_path unless user_signed_in? or buyer_signed_in?
end
def user_orders
@order.buyer_id = current_buyer.id or current_user
end
end
Когда я нажимаю кнопку «Отправить», создается и заказ, и запрос API выполняется успешно. Как я могу потребовать, чтобы поле кредитной карты было проверено с помощью ruby или javascript?
Я вижу, что вы используете шаблон https://stripe.com/docs/stripe-js
Попробуйте добавить window.onload = function () {
var stripe = Stripe('pk_test_413253....f0B8');
.............................................. // UR CODE
}
В примере с документами вы можете видеть, что он должен предупреждать, если пользователь отправляет пустую карточку. Вы не можете проверить это в бэкэнде, поскольку stripe.js в интерфейсе создает токен кредитной карты, который вы можете использовать в качестве безопасности.
все это работает как-то правильно .. токен отправляется на полосу и создается заказ. в идеале я бы хотел, чтобы заказ создавался только в том случае, если полоса платежа прошла успешно, но, прежде всего, мне нужно выяснить, почему я даже отправляю токен платежа в полосу, если поле кредитной карты не заполнено
Как отметил @Auriga, проверка кредитной карты выполняется по полосе в процессе токенизации.
Тем не менее, Stripe Element предоставляет вам возможность проверить поля и дать более значимую обратную связь вашему внешнему пользователю.
https://stripe.com/docs/stripe-js/reference#input-validation
Проблема, я думаю, в основном в контроллере или подобном. потому что на стороне полос он работает ... но мне не нужно заполнять или заполнять данные кредитной карты для ввода заказа ... даже когда я использую "<button id = " button-element "...>" как вход
window.onload = function () {....} этого не делал ... он работает отдельно, если у меня его нет в @orders form_for ... это (когда я добавил код полосы в заказ контроллер), когда проблемы начнут возникать.