Ruby on Rails Paypal REST API 来宾结账

Posted

技术标签:

【中文标题】Ruby on Rails Paypal REST API 来宾结账【英文标题】:Ruby on Rails Paypal REST API guest checkout 【发布时间】:2014-11-04 12:06:36 【问题描述】:

我正在尝试从其他开发人员那里调试 Rails 应用程序。请记住,我对 Ruby 和 Rails 的经验都很少。目标是让用户在进入 PayPal 支付页面时无需注册即可使用信用卡支付。

model/shopping-card.rb中的实际代码为:

include PayPal::SDK::REST

class ShoppingCart
  def initialize(session)
    @session = session
    @session["delivery"] ||= "shipping"
    @session[:coupon] ||= "token" => nil, "discount" => nil
    @session[:shopping_cart] ||= []
  end

  def delivery=(v)
    @session["delivery"] = v
  end

  def delivery
    @session["delivery"]
  end

  def should_add_shipping_costs?
    @session["delivery"] == "shipping"
  end

  def cart
    @session[:shopping_cart]
  end

  def discount
    val = @session["coupon"]["discount"]
    if val.nil?
      nil
    else
      val.to_f
    end
  end

  def token
    @session["coupon"]["token"]
  end

  def coupon=(c)
    @session["coupon"]["token"] = c.try("token")
    @session["coupon"]["discount"] = c.try("discount")
  end

  def subtotal_discount
    subtotal.to_f / 100 * discount.to_f
  end

  def subtotal_after_discount
    [(subtotal.to_f - subtotal_discount), 0].max
  end

  def subtotal_after_discount_with_vat
    subtotal_after_discount + subtotal_after_discount / 100 * 21
  end

  def add(product, quantity)
    quantity = quantity.to_i

    index = cart.find_index do |item|
      item["id"] == product.id
    end

    # Not in chart
    if index.nil?
     item = product.to_cart
     item[:quantity] = quantity
     cart << item
    else
      item = cart[index]
      item["quantity"] = item["quantity"].to_i + quantity
    end
  end

  def remove(id)
    cart.delete_if do |item|
      item["id"].to_s == id.to_s
    end
  end

  def clear
    cart.clear
  end

  def each(&block)
    cart.each(&block)
  end

  def each_with_index(&block)
    cart.each_with_index(&block)
  end

  def empty?
    cart.empty?
  end

  def to_paypal
    f = cart.map do |item|
      
        name: item["name"],
        price: "%.2f" % item["price_or_promo"],
        quantity: item["quantity"],
        currency: "EUR",
      
    end
    f
  end

  def subtotal
    amount = 0
    each do |item|
      amount += item["price_or_promo"].to_f * item["quantity"].to_i
    end
    "%.2f" % amount
  end

  def total_iva
    subtotal.to_f * 0.21
  end

  def total_for(user)
    t = subtotal_after_discount.to_f + total_iva + surcharge_for(user)
    if self.should_add_shipping_costs?
      t + shipping_cost
    else
      t
    end
  end


  def surcharge_for(user)
    user.surcharge ? subtotal.to_f * 0.052 : 0
  end

  def shipping_cost
    total = 0
    each do |item|
      total += (item['shipping'].to_f * item['quantity'].to_i)
    end
    total
  end

  def create_payment(description, user)
    payment = Payment.new(
      :intent => :sale,
      :payer => 
        :payment_method => :paypal
      ,

      :redirect_urls => 
        :return_url => ENV['PAYPAL_RETURN_URL'],
        :cancel_url => ENV['PAYPAL_CANCEL_URL']
      ,

      :transactions => [
        :item_list => 
          :items => 
            :name => description,
            :price => "%.2f" % total_for(user),
            :quantity => 1,
            :currency => "EUR"
          
        ,

        :amount => 
          :total => "%.2f" % total_for(user),
          :currency => "EUR"
        ,


        :description => description
      ],
    )

    if payment.create
      @session[:payment_id] = payment.id
    end

    payment
  end

  def build_order
    order = Order.new(user_id: @session[:user_id])
    each do |item|
      order.operations << Operation.new(
        product_id: item["id"],
        quantity: item["quantity"].to_i
      )
    end

    order
  end

  def complete_payment(params)
    payment = Payment.find(@session[:payment_id])
    if payment.execute(payer_id: params[:PayerID])
      build_order.save!
      @session[:payment] = nil
      @session[:coupon] = nil
      clear
    end

    if(coupon = Coupon.find_by(token: token))
      coupon.used = true
      coupon.save!
    end
    payment
  end

end

controllers/payment-controller.rb

include PayPal::SDK::REST

class PaymentsController < ApplicationController
  def checkout
    @payment = shopping_cart.create_payment("Cultius Purchase", current_user)
    if @payment.success?
      redirect_to @payment.links.find|v| v.method == "REDIRECT" .href
    else
      logger.error "Error while creating payment:"
      logger.error @payment.error.inspect
    end
  end

  def success
    shopping_cart.complete_payment(params)
  end
end

【问题讨论】:

【参考方案1】:

所以最后,与 PP 交谈,必须启用信用卡选项,检查您的 PP 帐户设置中的选项。甚至此选项仅适用于“合格买家”。

【讨论】:

以上是关于Ruby on Rails Paypal REST API 来宾结账的主要内容,如果未能解决你的问题,请参考以下文章

paypal gem 多个帐户 ruby​​ on rails

Paypal 经常性问题 ruby​​ on rails

如何在 Ruby on Rails 中集成 Paypal 集成

美国以外的 Ruby on Rails 和 Paypal

如何将 paypal 与 ruby​​ on rails 应用程序集成?

paypal 与 ruby​​ on rails 集成的“zoid 破坏了所有错误”