【问题标题】:Ruby on Rails Przelewy24 payment system implementation, undefined method `force_encoding' for nil:NilClassRuby on Rails Przelewy24 支付系统实现,nil:NilClass 的未定义方法“force_encoding”
【发布时间】:2017-08-10 16:31:11
【问题描述】:

我正在尝试通过此 gem 在我的应用中实现 Przelewy24 支付系统:https://github.com/jcieslar/przelewy24_payment

但是我的付款验证有问题,正是我收到了这个错误:

NoMethodError in PaymentsController#comeback
undefined method `force_encoding' for nil:NilClass

这可能是从 Przelewy24 接收数据的问题,因为当我没有收到任何方法错误时,请求参数和响应标头都没有。 这是我的配置文件:

Przelewy24Payment.setup do |config|
  config.merchant_id = 'XXXXX'
  config.pos_id = 'XXXXX'
  config.crc_key = 'XXXXXXXXXXXXXXXXXXXX'
  config.language = 'pl'
  config.currency = 'PLN'
  config.country = 'PL'
  config.mode = :development
  config.url_status = '/kam'
  config.url_return = '/kam'
  config.hostname = {
      :development => "http://127.0.0.1:3000",
      :production => "mydomain.pl",
      :staging => "staging.domain"
  }
end

还有我的 /kam 路线

get '/kam' => 'payments#comeback'

我不能直接将 url_status 和 url_return 设置为 '/payments/comeback' 这是我的控制器中显示操作的 url,因为那样我会收到错误

Couldn't find Payment with 'id'=comeback

我不知道如何解决这个问题,请帮助我。

【问题讨论】:

  • 您可以显示控制器中的代码吗?我对引发错误的行特别感兴趣。
  • 当然,我只是在下面发了这个
  • 嗯,我认为您的路线设置不正确。显然/payments/:id 是将您带到显示操作的路线(Rails 的默认设置也是如此)。然后,当您调用 /payments/comeback 时,rails 会将 comeback 解释为 id 参数,尝试查找以 comeback 为 id 的付款并失败。
  • 我知道这一点是因为我以这种方式设置了路线:get '/kam' => 'payments#comeback' 我正在调用 /kam,这会导致支付控制器中的恢复操作。也许问题在于将复出操作与提供付款按钮数据的显示操作分开调用,因此来自 Przelewy24 的响应不包含任何参数。但是,如果正如您所说,rails 尝试查找 ID 为复出的付款,我该如何在 /payments/comeback 中提供处理复出操作。

标签: ruby-on-rails ruby payment


【解决方案1】:

这是我的付款控制器

  class PaymentsController < ApplicationController
          include Przelewy24PaymentController


  def index
    @payments = Payment.all
  end



  def show

    @payment = Payment.find(params[:id])


        @data = { :session_id =>  @payment.session_id,
              :description => @payment.porada.title,
              :amount => @payment.porada.cena,
              :email => @payment.user.email,
              :country => 'PL',
              # adding this params, you overwrite your config settings so this param is optional
              :merchant_id => ‚XXXXX’,
              :pos_id => ‚XXXXX’,
              :api_version => '3.2',
              :crc_key => ‚XXXXXXXXXXX’,
              :currency => 'PLN',
              :country => 'PL',
              # :url_return => url_return,
              # :url_status => url_status,

              # other optional params
              # :language => pl/en/de/es/it
              # :method => method,
              # :client => 'Adam Nowak',
              # :address => 'Powstancow 22/2',
              # :zipcode => '53-456',
              # :city => 'Wroclaw',
              # :phone => '481321132123',
              # :time_limit => INT,
              # :wait_for_result => INT,
              # :channel => INT,
              # :shipping => INT,
              # :transfer_label => STRING(20)
              # :encoding => ISO-8859-2/UTF-8/Windows-1250

            }

  end



  def new
      @payment = Payment.new(:porada_id => params[:id])
  end

  def edit
  end

  def create
        @payment = Payment.new(payment_params)
    @payment.session_id = Przelewy24Payment.friendly_token[0,20] 
    @payment_porada = @payment.porada
        @user = current_user
        @payment.user_id = current_user.id
        @payment.user = current_user

    respond_to do |format|
      if @payment.save
        format.html { redirect_to @payment, notice: 'Payment was successfully created.' }
        format.json { render :show, status: :created, location: @payment }
      else
        format.html { render :new }
        format.json { render json: @payment.errors, status: :unprocessable_entity }
      end
    end
  end


  def update
    respond_to do |format|
      if @payment.update(payment_params)
        format.html { redirect_to @payment, notice: 'Payment was successfully updated.' }
        format.json { render :show, status: :ok, location: @payment }
      else
        format.html { render :edit }
        format.json { render json: @payment.errors, status: :unprocessable_entity }
      end
    end
  end


  def destroy
    @payment.destroy
    respond_to do |format|
      format.html { redirect_to payments_url, notice: 'Payment was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def payment_success(payment_params)
    # payment_params returns hash with:
    # p24_merchant_id
    # p24_pos_id
    # p24_session_id
    # p24_order_id
    # p24_amount
    # p24_currency
    # p24_method
    # p24_sign
    # p24_karta
    # payment_id
    # e.g
    # payment = Payment.find_by_session_id(payment_params[:p24_session_id])
  end

  # after error payment this method will be trigger
  # so you can do whatever you want
  def payment_error(payment_params, code, description)
    # payment_params returns hash with:
    # p24_merchant_id
    # p24_pos_id
    # p24_session_id
    # p24_order_id
    # p24_amount
    # p24_currency
    # p24_method
    # p24_sign
    # p24_karta
    # payment_id
    #
    # code return error code
    # description return error description
  end

  # method to setup params to verify it final verifyciation
  # so you can do whatever you want
  def payment_verify(response_params)
    # e.g:
    # you must return hash with amount which was save in your db and your crc_key
    payment = Payment::Payment.where(session_id: response_params['p24_session_id']).first
    if payment
      { amount: payment.amount, crc_key: Przelewy24Payment.crc_key }
    else
      {}
    end
  end







  private




    # Use callbacks to share common setup or constraints between actions.
    def set_payment
      @payment = Payment.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def payment_params
      params.require(:payment).permit(:amount, :porada_id, :user_id)
    end
end

这是 przelewy24_payment gem 中内置的 comeback 操作。

def comeback
      result = przelewy24_verify(params,request.remote_ip)
      if result.error == "0"
        payment_success(params)
      else
        payment_error(params, result.error, result.errorMessage)
      end
    end`

数据是从显示视图发送的

<%= payment_button(@data) %>

【讨论】:

    猜你喜欢
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多