控制器方法/ Javascript验证优惠券代码并更新价格

时间:2015-05-09 18:52:20

标签: javascript ruby-on-rails ruby ruby-on-rails-4

我有一个结帐页面,访问者可以输入优惠券,从而获得折扣。此外,我还有一个动作代码模型,其中包含由管理员生成的所有可能的有效动作代码。可以提交优惠券,然后按下按钮,它应该验证优惠券,如果有效则自动更新价格。我已尝试按照答案here中的步骤操作,但我不完全确定如何执行此操作。

当然,这应该以安全的方式完成。我最初的计划是通过Javascript,但这里的答案让我确信这应该在控制器中完成(并且可能使用Javascript来更新结账视图上显示的金额?)。

我应该如何调整以下代码以包含优惠券以及我应该包含哪些Javascript?就像现在一样,按下优惠券按钮时没有任何反应。

路线,提交新用户时执行def checkout

post 'signup/register' => 'organizations#checkout', as: 'signup_checkout'

保存新用户并为结帐(付款)生成视图的控制器方法。它为结帐设置了各种变量:

  def checkout
    @organization = Organization.new(organizationnew_params)
    if @organization.save
      @organization.members.each do |single_member|
        single_member.send_activation_email
      end
      @actioncode = Actioncode.new
      @amount = 100.00
      @currency = "EUR"
      @description = @organization.id
      @transaction_description = "My description"
      @transaction_type = "S"
      @hash = hash(@description, @amount, @currency, @transaction_type)
      render 'checkout'   # This renders the checkout view.
    else                            
      render 'new_premium'
    end
  end

表单视图,前四行生成动作代码/优惠券的表单:

<%= form_for @actioncode, method: :post, url: {action: "check_actioncode", :controller => 'actioncodes'}, remote: true do |f| %>
  <%= f.text_field :actioncode, :placeholder => "Enter your coupon" %>
  <%= f.submit "Submit Coupon Code" %>
<% end %>

<form action="https://secure.paylane.com/order/cart.html" method="post" >
  <%= "If you have a coupon, please enter that first. The amount due is #{@currency} #{number_with_precision(@amount, precision: 2)}. The button below will bring you to the secure environment of PayLane where you can select your payment method." %>
  <!-- form adapted from http://devzone.paylane.com/secure-form-guide/implementation/ -->
  <input type="hidden" name="amount" value=@amount />
  <input type="hidden" name="currency" value=@currency />
  <input type="hidden" name="merchant_id" value=PAYLANE_ID />
  <input type="hidden" name="description" value=@description />
  <input type="hidden" name="transaction_description" value=@transaction_description />
  <input type="hidden" name="transaction_type" value=@transaction_type />
  <input type="hidden" name="back_url" value="https://mysite/signup/confirmation" />
  <input type="hidden" name="language" value="en" />
  <input type="hidden" name="hash" value=@hash />
  <input type="hidden" name="customer_email" value=@member.email />
  <button type="submit">Pay with PayLane</button>
</form>

路线,在提交优惠券按钮时执行:

post 'check_actioncode' => 'actioncodes#check_actioncode'

按下动作代码/优惠券按钮后执行的控制器方法

def check_actioncode
  @actioncode = Actioncode.where(:actioncode => params[:actioncode][:actioncode]).first
  respond_to do |format|
    unless @actioncode.empty?
      unless @actioncode.price.empty?
        @amount = @actioncode.price     # It it safe this way, or should (part of) the method be private?
        format.js {}             # What should the js file look like to update the values in the checkout view?
        render 'checkout'        # To reload page with the updated price/amount?
      else
        unless @actioncode.discount.empty?
          @amount = @amount * (100 - @actioncode.discount)  # Not sure how to do this. The first @amount should be yhr new amount, while the second @amount should be the initial amount.
          format.js {}
          render 'checkout'
        else
          flash.now[:danger] = "Action code offers no discount"
        end
      end
    else
      flash.now[:danger] = "Action code not found or expired"
    end
  end
end

删除了初始的Javascript代码,因为答案表明这不是一种安全的方法,例如更新金额。

2 个答案:

答案 0 :(得分:2)

很少有事情要注意,你永远不会把动作代码带到UI。人们肯定会破解这个!

function validate(actioncode) {

    //Here make a call to your backend to validate. I RECOMMEND NOT TO DO IT IN UI.
    //Return somevalue
    //if you have the data in UI, you can use if(validActionCodes.indexOf(actioncode))
    if (isActionValid)
        window.alert("Action Code Accepted! Click the Buy Now button to finalize the payment");
    } else {
        window.alert("Sorry, The Action Code you entered is invalid. Please check and try again!");
    }
}

答案 1 :(得分:1)

您永远不应该只验证关键用户输入客户端(换句话说,这里:使用javascript)。这将是一个安全漏洞和可能的代码注入攻击的目标。 为什么不通过post将表单输入发送到您的控制器并使用ruby在那里进行验证?我认为这更符合保持MVC(视图不应该与模型对话)。