【问题标题】:Rails & Stripe - Stripe card token not saving to the new customer for payment later (subscription w free trial)Rails & Stripe - Stripe 卡令牌不保存给新客户以供以后付款(订阅免费试用)
【发布时间】:2018-05-26 15:42:54
【问题描述】:

我将 Rails、Devise 和 Stripe 用于 SaaS 应用程序,但在注册时无法保存客户卡信息。

我想保存信息而不收费的原因是因为它是免费试用的订阅计划。

到目前为止,我可以创建要创建的卡令牌和要创建的客户,它们都出现在 Stripe 仪表板日志中(POST /v1/tokens 和 POST /v1/customer)。

问题是卡没有显示为客户已保存,即它们都已提交但未连接。

我认为这与我在用户模型中创建客户的方式有关:

Stripe::Customer.create(description: plan_id, email: email, plan: plan_id, card: stripeToken)

但我似乎找不到解决方案。

这是我的表格:

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), :html => {:id => "payment-form"}) do |f| %>
  <%= devise_error_messages! %>

  <%= hidden_field_tag 'plan', params[:plan] %>

  <div class="field form-group">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, class: 'form-control' %>
  </div>
  <div class="field form-group">
    <%= f.label :password %>
    <% if @validatable %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "off", class: 'form-control' %>
  </div>
  <div class="field form-group">
    <%= f.label :password_confirmation, "Password Confirmation" %><br />
    <%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control' %>
  </div>
  <!-- CC -->
    <div class="form-row">
      <label for="card-element">
        Credit or Debit Card
      </label>
      <div id="card-element" class="form-control"></div>

      <!-- Used to display form errors -->
      <div id="card-errors" role="alert"></div>
    </div>
  <!-- / CC -->
  <div class="actions form-group text-center" style="margin-top: 40px;">
    <input type="submit" class="btn btn-success btn-block" value="Create Account">
  </div>
<% end %>

这里是 JS:

#In <head> <script src="https://js.stripe.com/v3/"></script>

var stripe = Stripe('pk_test_sadnasd2n3krekl3k434kla');
  var elements = stripe.elements();
  var card = elements.create('card', { style:
    {
      base: {
        lineHeight: '2'
      }
    }
  });

  // Add an instance of the card UI component into the `card-element` <div>
  card.mount('#card-element');

  function stripeTokenHandler(token) {
    // Insert the token ID into the form so it gets submitted to the server
    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);

    // Submit the form
    form.submit();
  }

  function createToken() {
    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);
      }
    });
  };

  // Create a token when the form is submitted.
  var form = document.getElementById('payment-form');
  form.addEventListener('submit', function(e) {
    e.preventDefault();
    createToken();
  });

  card.addEventListener('change', function(event) {
    var displayError = document.getElementById('card-errors');
    if (event.error) {
      displayError.textContent = event.error.message;
    } else {
      displayError.textContent = '';
    }
  });

这里是控制器:

class Users::RegistrationsController < Devise::RegistrationsController
  def create
    super do |resource|
      if params[:plan]
        resource.plan_id = params[:plan]
        if resource.plan_id == "1"
          resource.save_with_payment
        else
          resource.save
        end
      end
    end
  end
end

这是模型:

class User < ApplicationRecord

  attr_accessor :stripeToken

  def save_with_payment
    if valid?
      customer = Stripe::Customer.create(description: plan_id, email: email, plan: plan_id, card: stripeToken)
      self.stripe_customer_token = customer.id
      save!
    end
  end
end

任何人都可以帮助解释为什么卡片在创建时没有与客户链接?

【问题讨论】:

  • UserstripeToken 的值是多少?您是否已打印并确认已设置好?如果不是,它是从哪里来的?您是否在代码的那一侧确认该值已设置?

标签: ruby-on-rails ruby-on-rails-5 stripe-payments stripe.js


【解决方案1】:

条带令牌应该在源属性中传递,而不是在卡片中。

我们使用这种方式可以工作,你也可以参考它不接受卡片属性的API文档。

它接受 stripeToken 作为客户端点中的源 Refer

【讨论】:

    【解决方案2】:

    创建客户时,您可以将卡令牌添加为sources 对象的一部分。

    如果您检查related docs,您会发现您所需要的只是为客户传递已经保存的令牌。

    这是一个 step by step 指南以及如何使用 Ruby gem 将源附加到客户对象

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-04
      • 2015-08-21
      • 1970-01-01
      • 2018-12-01
      • 1970-01-01
      • 2015-03-01
      • 1970-01-01
      • 2017-07-01
      相关资源
      最近更新 更多