首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义支付网关payment_state和shipment_state不能持续狂欢

自定义支付网关payment_state和shipment_state不能持续狂欢
EN

Stack Overflow用户
提问于 2015-02-19 21:46:01
回答 2查看 636关注 0票数 0

我在Spare2.2中实现了一个自定义支付网关。这是一个网关,在那里你可以重定向到网关自己的网站来接受付款,然后银行会用一堆get params重定向回给你。

我遇到了一个问题,如果我在代码中放入一个debugger,那么order的payment_state和shipment_state在数据库中会以null结束,尽管它们在order对象本身中不是null。调用order.save似乎没有什么帮助。

我已经实现了一个肮脏的黑客来解决这个问题:

代码语言:javascript
复制
  # This is a hack - for some reason the payment_state and shipment_state weren't being persisted
  # and where being stored in the database as null. Really the spree checkout process
  # should take care of this and we shouldn't have to set them manually.
  # We must be doing something wrong...
  order.update_attribute :payment_state, 'paid'
  order.update_attribute :shipment_state, 'ready'

但我真的很想知道真正的问题是什么--为什么这些状态没有被坚持下来?(在调用上面的代码之前,我应该补充一点,order.payment_stateorder.shipment_state的值分别是balance_duepending -但这是另一个问题。如果我能让他们以任何方式保存,这是主要的问题。

你知道我做错了什么吗?

下面是我的控制器和网关的完整代码。

代码语言:javascript
复制
class Spree::CommBankController < Spree::StoreController

  def secure_payment
    order = current_order
    @order_info = 'Espionage Online order ' + order.number

    payment_params = {
      "Title" => 'Espionage Online',
      "vpc_AccessCode" => payment_method.preferred_access_code,
      "vpc_Amount" => (order.total * 100).to_i, # convert to cents
      "vpc_Desc" => @order_info,
      "vpc_MerchTxnRef" => order.number,
      "vpc_Merchant" => payment_method.preferred_merchant_id_no,
      "vpc_OrderInfo" => @order_info,
      "vpc_ReturnURL" => secure_payment_callback_url(payment_method_id: payment_method.id),
    }

    payment_request = ::CommWeb::PaymentRequest.new(payment_params, payment_method.preferred_secure_secret)
    redirect_to payment_request.url
  end

  def secure_payment_callback
    # Next line - see http://stackoverflow.com/questions/4116545/how-do-i-get-only-the-query-string-in-a-rails-route
    order = current_order
    query_params = params.except(*request.path_parameters.keys)
    payment_response = ::CommWeb::PaymentResponse.new(query_params, payment_method.preferred_secure_secret)
    if !secure_hash_matches?(payment_response)
      flash.notice = 'Error with payment - secure hash did not match. Please try again.'
      redirect_to checkout_state_path(order.state)
      return
    end

    payment = order.payments.create!({
      :source => Spree::CommbankCheckout.create({
        :params_hash => payment_response.params.to_s,
        :success => payment_response.success?,
        :desc => payment_response.description,
        :trx_response_code => payment_response.trx_response_code,
        :message => payment_response.message,
      }),
      :amount => order.total,
      :payment_method => payment_method,
      :response_code => payment_response.trx_response_code,
    })

    payment.pend
    if payment_response.success?
      # Set payment to completed after order.next because
      # spree expects at least one incomplete payment to process an order to complete
      order.next!
      payment.complete
      debugger
      # This is a hack - for some reason the payment_state and shipment_state weren't being persisted
      # and where being stored in the database as null. Really the spree checkout process
      # should take care of this and we shouldn't have to set them manually.
      # We must be doing something wrong...
      order.update_attribute :payment_state, 'paid'
      order.update_attribute :shipment_state, 'ready'
    else
      payment.failure
    end

    if order.complete?
      flash.notice = Spree.t(:order_processed_successfully)
      session[:order_id] = nil
      redirect_to completion_route(order)
    else
      flash.notice = 'Error: ' + payment_response.message + '. Please try again.'
      redirect_to checkout_state_path(order.state)
    end
  end

  def secure_hash_matches? payment_response
    payment_response.secure_hash_matches?
  end

  def payment_method
    @payment_method ||= Spree::PaymentMethod.find(params[:payment_method_id])
  end

  def completion_route(order)
    order_path(order)
  end

end

入口..。

代码语言:javascript
复制
# Partly inspired from https://github.com/spree-contrib/spree-adyen (the hosted payment page class)
module Spree
  class Gateway::CommBank < Gateway
    preference :merchant_id_no, :string
    preference :access_code, :string
    preference :secure_secret, :string

    def auto_capture?
      true
    end

    # Spree usually grabs these from a Credit Card object but when using
    # Commbank's 3 Party where we wouldn't keep the credit card object
    # as that's entered outside of the store forms
    def actions
      %w{capture}
    end

    # Indicates whether its possible to void the payment.
    def can_void?(payment)
      !payment.void?
    end

    # Indicates whether its possible to capture the payment
    def can_capture?(payment)
      payment.pending? || payment.checkout?
    end

    def method_type
      'commbank'
    end

    def capture(*args)
      ActiveMerchant::Billing::Response.new(true, "", {}, {})
    end

    def source_required?
      false
    end

    def provider_class
      self.class
    end

    def provider
      self
    end

    def purchase
        # This is normally delegated to the payment, but don't do that. Handle it here.
        # This is a hack copied from the Spree Better Paypal Express gem.
        Class.new do
          def success?; true; end
          def authorization; nil; end
        end.new
    end

  end
end
EN

回答 2

Stack Overflow用户

发布于 2015-03-11 11:57:39

检查order.state_changes。它们是否显示了两个状态的更改?

我在使用"spree-adyen“的时候遇到了同样的问题。order.state_changes显示payment_stateshipment_state已更改为ready。然而,它并不保持顺序。这是随机发生的,订单的10%。我目前正在对这样的订单手动调用order.update!,但我真的很想知道问题是什么。

此外,我不太确定order.update!是否是一个好的解决方案,因为它执行很多查询,而且可能非常昂贵。

票数 1
EN

Stack Overflow用户

发布于 2015-02-19 22:04:32

嗯。所以很明显order.update!会解决我的问题。哇哦。

尽管如此,调用order.update!并不是我在其他Spree Payment Gateway gem (https://github.com/spree-contrib/better_spree_paypal_expresshttps://github.com/spree-contrib/spree-adyen)中看到的,所以我有兴趣知道我是不是在做一些非常愚蠢的事情。(我最终在https://github.com/coinbase/coinbase-spree/blob/master/app%2Fcontrollers%2Fspree%2Fcoinbase_controller.rb的代码中注意到了它)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28608001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档