質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.92%

Stripe: stripeTokenが作成されない

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 1,343

score 7

 前提・実現したいこと

初めまして。Railsを独学で学んでおり、今回ECサイトのようなものの構築を試みています。
最終的に実現したいこととして、@product.priceをstripeのdata-amountとしてcharges controllerのcreateアクションに渡したいです。

一旦、data-amountをコントローラ側に渡す方法として、https://stripe.com/docs/recipes/variable-amount-checkoutを元に、まずはそれ通り実装を試みているのですが、stripeTokenが作成されず、先に進めません。

 発生している問題・エラーメッセージ

Donateボタンを押したあと、決済画面にならず、下記エラーが発生します。

Stripe::InvalidRequestError in ChargesController#create

Invalid source object: must be a dictionary or a non-empty string. See API docs at https://stripe.com/docs'

 app/views/products/show.html.erb

<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @product.name %>
</p>

<p>
  <strong>Price:</strong>
  <%= @product.price %>
</p>

<p>
  <strong>Stock:</strong>
  <%= @product.stock %>
</p>


<%= form_tag charges_path do %>
  <div id="error_explanation">
    <% if flash[:error].present? %>
      <p><%= flash[:error] %></p>
    <% end %>
  </div>
  <article>
    <%= label_tag(:amount, 'Donation Amount:') %>
    <%= text_field_tag(:amount) %>
  </article>
  <article>
    <%= hidden_field_tag(:stripeToken) %>
  </article>
  <button id='donateButton'>Donate</button>
<% end %>

<script src="https://checkout.stripe.com/checkout.js"></script>

<script>
var handler = StripeCheckout.configure({
  key: '<%= Rails.configuration.stripe[:publishable_key] %>',
  locale: 'auto',
  name: 'Sand Castles United',
  description: 'One-time donation',
  token: function(token) {
    $('input#stripeToken').val(token.id);
    $('form').submit();
  }
});

$('#donateButton').on('click', function(e) {
  e.preventDefault();

  $('#error_explanation').html('');

  var amount = $('input#amount').val();
  amount = amount.replace(/\$/g, '').replace(/\,/g, '')

  amount = parseFloat(amount);

  if (isNaN(amount)) {
    $('#error_explanation').html('<p>Please enter a valid amount in USD ($).</p>');
  }
  else if (amount < 5.00) {
    $('#error_explanation').html('<p>Donation amount must be at least $5.</p>');
  }
  else {
    amount = amount * 100; // Needs to be an integer!
    handler.open({
      amount: Math.round(amount)
    })
  }
});

// Close Checkout on page navigation
$(window).on('popstate', function() {
  handler.close();
});
</script>

<%= link_to 'Edit', edit_product_path(@product) %> |
<%= link_to 'Back', products_path %>

 app/controllers/charges_controller.rb

class ChargesController < ApplicationController
  def new
  end

  def create
    @amount = params[:amount]

    @amount = @amount.gsub('$', '').gsub(',', '')

    begin
      @amount = Float(@amount).round(2)
    rescue
      flash[:error] = 'Charge not completed. Please enter a valid amount in USD ($).'
      redirect_to new_charge_path
      return
    end

    @amount = (@amount * 100).to_i # Must be an integer!

    if @amount < 500
      flash[:error] = 'Charge not completed. Donation amount must be at least $5.'
      redirect_to new_charge_path
      return
    end

    Stripe::Charge.create(
      :amount => @amount,
      :currency => 'usd',
      :source => params[:stripeToken],
      :description => 'Custom donation'
    )

    rescue Stripe::CardError => e
      flash[:error] = e.message
      redirect_to new_charge_path
    end
  end

config/initializer/stripe.rb 

Rails.configuration.stripe = {
  publishable_key: Rails.application.secrets.stripe_publishable_key,
  secret_key: Rails.application.secrets.stripe_secret_key
}

Stripe.api_key = Rails.application.secrets.stripe_secret_key

 config/routes.rb

Rails.application.routes.draw do

  resources :products
  resources :charges
end

 試したこと

rails sしたログには、

Started POST "/charges" for 127.0.0.1 at 2018-11-01 18:02:41 +0900
Processing by ChargesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"JQv6bhiP+tO+gC9+s+hY1Av+No57+CW1u1e3dOtlfWNnfnaq8lrueqxkHE98aI2+D0JqZ4eOd/nG+MxNsGPwEg==", "amount"=>"1200", "stripeToken"=>""}
Completed 500 Internal Server Error in 1655ms (ActiveRecord: 0.0ms)

と表示されていることを確認しています。

Stripeのdocsを一応読みましたが、英語なのと今回の内容に対してどのあたりを見ればいいかの勘所がわからないため、ご質問させていただいています。

 補足情報

Rails 5.1.6
ruby 2.5.0
Stripeのkeyはconfig/secret.ymlに記載しています

今回初めて質問させていただくため、必要な情報が全然足りないかもしれないです。他に必要なソースコードがあれば教えていただきたいです。確認取れ次第追記します。
どなたかヒントでもいいのでいただければと思います。よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る