簡體   English   中英

注冊用戶時,Stripe + Devise在模式對話框中顯示所有可能的條帶錯誤(和設計錯誤)

[英]Stripe + Devise show all possible stripe errors (and devise errors) in modal dialog when signing up user

問題是我無法在注冊模式對話框中顯示條帶錯誤。

Javascript:

$.externalScript('https://js.stripe.com/v1/').done(function(script, textStatus) {
  Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'));
  var subscription = {
    setupForm: function() {
      return $('form').submit(function() {
        $('input[type=submit]').prop('disabled', true);
        if ($('#card_number').length) {
          subscription.processCard();
          return false;
        } else {
          return true;
        }
      });
    },
    processCard: function() {
      var card;
      card = {
        name: $('#user_name').val(),
        number: $('#card_number').val(),
        cvc: $('#card_code').val(),
        expMonth: $('#card_month').val(),
        expYear: $('#card_year').val()
      };
      return Stripe.createToken(card, subscription.handleStripeResponse);
    },
    handleStripeResponse: function(status, response) {
      if (status === 200) {
        $('#stripe_token').val(response.id)
        $('form')[0].submit()
      } else {
        $('#stripe_error').text(response.error.message).show();
        return $('input[type=submit]').prop('disabled', false);
      }
    }
  };
  return subscription.setupForm();

});

在同一個js文件中,我使用了這個針對devise的create方法的ajax調用,但是我始終會得到null的錯誤值。 所以我想下面的那部分和上面的那部分不能一起使用。 我試圖合並它們,並在上面的handleStripeResponse函數中進行ajax調用,但是隨后出現了其他一些問題。

$('.signup').click(function(e){
e.preventDefault();
$.ajax ({
  url: '/users',
  method: 'POST',
  dataType: "JSON",
  success: function(data) {
    if (data.status == 'failed') {
      $('#stripe_error').show().text(data.error_message);
      return false;
    }
  }
});

});

設計注冊控制器:

def create
build_resource
user = User.new params[:user]

if user.save_with_payment 
  if user.active_for_authentication?
    set_flash_message :notice, :signed_up if is_navigational_format?
    sign_in(resource_name, user)
    # respond_with resource, :location => after_sign_up_path_for(user)
    render json: { status: 'success', resource: user }
  else
    set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
    expire_session_data_after_sign_in!
    respond_with user, :location => after_inactive_sign_up_path_for(user)
  end
else
  clean_up_passwords user
    render json: { status: 'failed', error_message: user.save_with_payment }
end

結束

用戶模型:

def save_with_payment
  if valid?
    stripe_customer = Stripe::Customer.create(
      :email => email,
      :source  => stripe_token
    )
    self.customer_id = stripe_customer.id
    update_stripe_user_details
    save!
  end

  rescue Stripe::InvalidRequestError => e
    logger.error "Stripe error while creating customer: #{e.message}"
    errors.add :base, "There was a problem with your credit card."
  rescue Stripe::CardError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue Stripe::InvalidRequestError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue Stripe::AuthenticationError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue Stripe::APIConnectionError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue Stripe::StripeError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue => e
    stripe_error e, e.message
    errors.add :base, e.message
end 

請指出正確的方向,我已經擺脫了想法。

您遇到的主要問題是,您正在嘗試通過單個控制器操作完成很多工作。

您的注冊控制者不僅負責與用戶表單輸入打交道,還負責與第三方打交道-如果您開始考慮這里可能存在的代碼路徑數量,您將意識到這是一個瘋狂的職責。

您可能想要做的就是將操作拆分:

POST /registrations # create a user profile
POST /registrations/:registration_id/payments # pay

這給您帶來了明確的職責,並且使用戶可以輕松重試失敗的付款,而不必從一個平方開始,也沒有設置來回傳遞參數的過於復雜的設置。

如果您要構建的是僅限會員類型的站點,您希望將訪問權限限制為付費用戶,則應在授權層(而不是身份驗證層)上進行處理。

實際上,這意味着您要讓具有的所有用戶完成注冊授權,然后在檢查用戶是否有權查看任何內容時檢查記錄上的標志或計算記錄上的付款次數。

class Ability
  include CanCan::Ability
  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.payed_in_full?
      can :read, :all
    end
  end
end

編輯

問題在於,在具有一個按鈕的同一表格中,我需要注冊>注冊用戶並輸入條紋卡詳細信息。

是的,這就是重點。 您需要更改方法。

如果可以接受ajax解決方案,則可以執行以下操作:

function sendForm($form){
  return $.ajax($form.attr('action'), {
    data: $form.serializeArray(),
    method: 'POST',
    dataType: "JSON",
  });
}

$(document).on('.signup', 'submit', function(){
  var $form = $(this);
  var promise = sendForm($form);
  promise.done(function(data, textStatus, jqXHR ){
    if (jqXHR.statusText === "OK") {
       console.log("User signup was successful");
       $form.toggleClass('signup payup');
       $form.attr('action', '/payments');
       $form.submit(); // this will cause the '.payup', 'submit' event
    else {
       console.log("User signup failed");
       // todo - display errors
    }
  });

  return false; // prevent default action
});

$(document).on('.payup', 'submit', function(){
  var $form = $(this);
  // should post to something like `/payments`
  var promise = sendForm($form);
  promise.done(function(data, textStatus, jqXHR ){
    if (jqXHR.statusText === "OK") {
       console.log("Payment was created successfully");
    else {
       console.log("Payment failed");
       // todo - display errors
    }
  });

  return false; // prevent default action
});

這給了您兩個不同的HTTP調用,並且從API的角度來看要簡單得多,而用戶體驗是他只提交一次表單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM