2015-01-31 2 views
1

Я обрабатываю платежи в электронной коммерции или на рынке. Пользователи заполняют форму заказа с адресом доставки, информацией о выставлении счетов и т. Д. И отправляют. Если форма заполнена без ошибок, форма работает по назначению, то есть заказ сохраняется и плата заряжается.Rails 4 - Обработка карточных платежей при возникновении ошибки формы

Проблема: когда форма имеет ошибку (пример: zip пуст), страница формы возвращает сообщение об ошибке. Но если информация о кредитной карте верна, пользователь получает плату. Мне нужно, чтобы карта была списана только при отсутствии ошибок формы.

Вот мой метод create в моем контроллере заказов. Я думал о перемещении блока блокировки полосы внутри блока response_to, но это не сработало, потому что заказ должен быть сохранен только после утверждения оплаты.

Поскольку это торговая площадка, у меня есть блок передачи платежей ниже, а также часть платежа передается продавцу. Этот код должен запускаться только после обработки платежа и сохранения заказа.

def create 
    @order = Order.new(order_params) 

    Stripe.api_key = ENV["STRIPE_API_KEY"] 
    token = params[:stripeToken] 


    begin 
     charge = Stripe::Charge.create(
     :amount => (@listing.price * 100).floor, 
     :currency => "usd", 
     :card => token, 
     :description => "Charge from ABC" 
     ) 

    respond_to do |format| 
     if @order.save 
     format.html { redirect_to thankyou_path(:id => @order.id) } 
     format.json { render action: 'show', status: :created, location: @order } 
     AutoNotifier.orderconf_email(current_user, @order).deliver 
     AutoNotifier.sellerconf_email(current_user, @seller, @order).deliver 
     else 
     format.html { render action: 'new' } 
     format.json { render json: @order.errors, status: :unprocessable_entity } 
     end 
    end #end respond_to 

    if [email protected]? 
     transfer = Stripe::Transfer.create(
      :amount => (((@listing.price * 97.1) - 30) * 0.8).floor, #converting to cents per stripe requirement. 80 percent in cents goes to seller. 
      :currency => "usd", 
      :recipient => @seller.recipient 
     ) 
    end #end transfer 

    rescue Stripe::CardError => e 
     flash[:danger] = e.message 
    end #end rescue 

    end #end begin 

end #end create 
+0

Вы нашли решение? – Tobias

+0

да, я использовал вариант решения, размещенный ниже Deep. Извините за задержанный ответ. меня здесь не много. – Moosa

ответ

0

Что вы можете сделать, это перевести платный заряд в метод в модели. А потом просто добавить условие, как это:

def save_with_payment 
    if self.valid? 
     charge = Stripe::Charge.create(
    :amount => (@listing.price * 100).floor, 
    :currency => "usd", 
    :card => token, 
    :description => "Charge from ABC" 
    ) 
     self.stripe_customer_token = charge.id 
     save! 
    else 
     logger.error "#{self.errors.inspect}" 
     false 
    end 
    rescue Stripe::InvalidRequestError => e 
    logger.error "Stripe error while creating charge: #{e.message}" 
    errors.add :base, "There was a problem with your credit card." 
    false 
    end 

И в контроллере вы можете сделать, это:

respond_to do |format| 
     if @order.save_with_payment 
     format.html { redirect_to thankyou_path(:id => @order.id) } 
     format.json { render action: 'show', status: :created, location: @order } 
     AutoNotifier.orderconf_email(current_user, @order).deliver 
     AutoNotifier.sellerconf_email(current_user, @seller, @order).deliver 
     else 
     format.html { render action: 'new' } 
     format.json { render json: @order.errors, status: :unprocessable_entity } 
     end 
    end #end respond_to 

Так что это будет проверять данные, введенные пользователем является действительным только тогда он будет заряжаться пользователю , Надеюсь это поможет.

0

Я предполагаю, что вы создаете обвинение перед созданием заказа, потому что хотите убедиться, что транзакция работает до создания заказа.

У вас здесь есть несколько вариантов.

  1. Вы можете подтвердить заказ с @order.valid?, прежде чем создать заряд, но это будет возвращать ложь, если у вас есть валидации на полосовом заряде.

  2. Вы также можете проверить подлинность заряда, не захватив ее, как на this page on the stripe support website, например, так:

    charge = Stripe::Charge.create(
        :amount => (@listing.price * 100).floor, 
        :currency => "usd", 
        :card => token, 
        :description => "Charge from ABC" 
        :capture => false 
        ) 
    

    Обратите внимание на :capture => false. Затем, как только вы создадите заказ, вы можете позвонить charge.capture. Но вы все равно захотите обработать (маловероятный) случай, когда charge.capture возвращает ошибку или вызывает исключение и удаляет заказ.

Вы можете также возвратить платеж, если @order.save возвращает ложь, но я рекомендовал бы по крайней мере, для проверки ошибок ввода, прежде чем захватить заряд.

0

Возможно, вам стоит взглянуть на сделки. Если что-то в транзакции вызывает исключение, все в нем будет отменено.

Смежные вопросы