mywork1868
@mywork1868

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

payjpのcheckoutでtokenが認識されません

解決したいこと

クレジットカード情報入力画面を作っています。
payjpのcheckoutを使用していますが、トークンが認識されないようです。
トークンを取得するために直すべきところを教えていただきたいです。

発生している問題・エラー

検証のコンソールで出力されるエラー

Uncaught SyntaxError: Cannot use import statement outside a module

該当するソースコード

↓ index.html,erb

<%# カード情報の入力 %>
<div class='credit-card-form'>
  <h1 class='info-input-haedline'>
    クレジットカード情報入力
  </h1>
  <script
    type="text/javascript"
    src="https://checkout.pay.jp/"
    class="payjp-button"
        data-key="pk_***********"
    data-submit-text="トークンを作成する"
    data-partial="true">
  </script>

<%# /カード情報の入力 %>

↓ order_controller.rb

class OrdersController < ApplicationController
  before_action :authenticate_user!
  before_action :non_matched_coach, only: [:index, :create]

  def index
    @order_form = OrderForm.new
  end

  def create
    @order_form = OrderForm.new(order_params)
    #binding.pry
    if @order_form.valid?
      match
      @order_form.save
      redirect_to root_path
    else
      render :index
    end
  end

  private

  def order_params
    params.require(:order_form).permit(:rank_id, {:character => []}, :play_style, :play_time, {:play_device => []}, {:communication_tool => []}, :goal).merge(user_id: current_user.id, coach_id: params[:coach_id], token: params[:token])
  end

  def match
    Payjp.api_key = ENV["sk_************"]
    Payjp::Charge.create(
      amount: @coach.price,
      card: order_params['payjp-token'],
      currency: 'jpy'
    )
  end

  def non_matched_coach
    @coach = Coach.find(params[:coach_id])
    if current_user.id == @coach.user_id
      redirect_to root_path
    end
  end

end

↓ order_form.rb

class OrderForm
  include ActiveModel::Model
  attr_accessor :user_id, :coach_id, :rank_id, :character, :play_style, :play_time, :play_device, :communication_tool, :goal, :token

  with_options presence: true do
    validates :user_id
    validates :coach_id

    validates :rank_id
    validates :character
    validates :play_time
    validates :play_device
    validates :communication_tool
    validates :goal

    validates :token
  end

  def save
    order = Order.create(user_id: user_id, coach_id: coach_id)
    Payment.create(coach_id: coach_id, order_id: order.id, rank_id: rank_id, character: character, play_style: play_style, play_time: play_time, play_device: play_device, communication_tool: communication_tool, goal: goal)
  end
end

自分で試したこと

order_paramsに['payjp-token']を入れてみた

足りない情報等あればお教えください。

0

1Answer

お疲れ様です。由利です。
Rubyは触ったことはないので、エラーコードを見た感想をお伝えします。

Uncaught SyntaxError: Cannot use import statement outside a module

このエラーはモジュール外でimport文を使っているので起きています。
原因としてはECMAScriptのモジュールをサポートしないブラウザでimport文を使っていることが考えられます。

htmlのtype="module"を指定して外部モジュールとして読み込ませてみてください。

1Like

Comments

  1. @mywork1868

    Questioner

    <!DOCTYPE html>
    <html>
      <head>
        <title>MatchingGame</title>
        <%= csrf_meta_tags %>
        <%= csp_meta_tag %>
        <script src="https://js.pay.jp/v2/pay.js"></script>
    
        <%= stylesheet_link_tag 'application', media: 'all'  %>
        <%= javascript_importmap_tags 'application' %>
        
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link href="https://fonts.googleapis.com/css2?family=Yomogi&display=swap" rel="stylesheet">
      </head>
    
      <body>
        <main>
          <%= yield %>
        </main>
      </body>
    </html>
    
  2. @mywork1868

    Questioner

    class OrdersController < ApplicationController
      before_action :authenticate_user!
      before_action :non_matched_coach, only: [:index, :create]
    
      def index
        @order_form = OrderForm.new
      end
    
      def create
        @order_form = OrderForm.new(order_params)
        #binding.pry
        if @order_form.valid?
          match
          @order_form.save
          redirect_to root_path
        else
          render :index
        end
      end
    
      private
    
      def order_params
        params.require(:order_form).permit(:rank_id, {:character => []}, :play_style, :play_time, {:play_device => []}, {:communication_tool => []}, :goal).merge(user_id: current_user.id, coach_id: params[:coach_id], token: params[:token])
      end
    
      def match
        Payjp.api_key = "sk_test_d0d0e718d7b91dfeb4a1ffd4"
        Payjp::Charge.create(
          amount: @coach.price,
          card: order_params[:token],
          currency: 'jpy'
        )
      end
    
      def non_matched_coach
        @coach = Coach.find(params[:coach_id])
        if current_user.id == @coach.user_id
          redirect_to root_path
        end
      end
    end
    
  3. @mywork1868

    Questioner

    class OrderForm
      include ActiveModel::Model
      attr_accessor :user_id, :coach_id, :rank_id, :character, :play_style, :play_time, :play_device, :communication_tool, :goal, :token
    
      with_options presence: true do
        validates :user_id
        validates :coach_id
    
        validates :rank_id
        validates :character
        validates :play_time
        validates :play_device
        validates :communication_tool
        validates :goal
    
        validates :token
      end
    
      def save
        order = Order.create(user_id: user_id, coach_id: coach_id)
        Payment.create(coach_id: coach_id, order_id: order.id, rank_id: rank_id, character: character, play_style: play_style, play_time: play_time, play_device: play_device, communication_tool: communication_tool, goal: goal)
      end
    end
    
  4. @mywork1868

    Questioner

    Started POST "/coaches/1/orders" for ::1 at 2024-02-03 11:56:26 +0900
    Processing by OrdersController#create as HTML
      Parameters: {"authenticity_token"=>"[FILTERED]", "payjp-token"=>"[FILTERED]", "order_form"=>{"rank_id"=>"20", "character"=>["アッシュ"], "play_style"=>"w", "play_time"=>"w", "play_device"=>["PC"], "communication_tool"=>["Discord"], "goal"=>"w"}, "commit"=>"購入", "coach_id"=>"1"}
      User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 2], ["LIMIT", 1]]
      Coach Load (0.4ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
      ↳ app/controllers/orders_controller.rb:37:in `non_matched_coach'
      Rendering layout layouts/application.html.erb
      Rendering orders/index.html.erb within layouts/application
      Rendered shared/_header.html.erb (Duration: 7.0ms | Allocations: 1139)
      Rendered shared/_side_bar.html.erb (Duration: 0.2ms | Allocations: 160)
      User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
      ↳ app/views/orders/index.html.erb:14
      Rendered shared/_error_messages.html.erb (Duration: 0.6ms | Allocations: 413)
      Rendered shared/_footer.html.erb (Duration: 0.0ms | Allocations: 9)
      Rendered orders/index.html.erb within layouts/application (Duration: 29.2ms | Allocations: 11538)
      Rendered layout layouts/application.html.erb (Duration: 100.8ms | Allocations: 37221)
    Completed 200 OK in 169ms (Views: 103.5ms | ActiveRecord: 5.5ms | Allocations: 60822)
    
    
    
    ActionController::RoutingError (No route matches [GET] "/assets/comment_channel"):
    
  5. ※あくまでもエラーコードなどの内容からよるものでの推測です
    コメント欄に追記されているエラーについて、
    ActionController::RoutingError (No route matches [GET] "/assets/comment_channel"):
    とありました
    以下サイトが参考になるかと思います
    https://ichigick.com/no-route-matches/

    [概要]
    原因:リクエスト(HTTPメソッド+パス)に対するルーティングが定義されてない

    • HTTPメソッド+パスのミス
      • エラーとなったリクエスト(HTTPメソッド+パス)を受け入れるルーティングを足す
    • リクエストを発行するリンク/フォーム/リダイレクト
      • 存在するルーティングとなるようにリクエストの発行元(リンク、フォーム、リダイレクト)を修正する

    のどちらかになるかと思います
    「rails routes」コマンドを使用してルーティングの定義、
    config/routes.rbを一度確認してみてはいかがでしょうか

Your answer might help someone💌