Reputation: 984
I am new to ruby/rails/spree. I am implementing Indian payment gateway with spree-3.0.7
.
I am able to process the order but payment status is always at balance_due
.
Controller code
def confirm
payment_method = Spree::PaymentMethod.find(payment_method_id)
Spree::LogEntry.create({
source: payment_method,
details: params.to_yaml
})
order = current_order || raise(ActiveRecord::RecordNotFound)
if(address = order.bill_address || order.ship_address)
firstname = address.firstname
end
#confirm for correct hash and order amount requested before marking an payment as 'complete'
checksum_matched = payment_method.checksum_ok?([params[:status], '', '', '', '', '', '', params[:udf4], params[:udf3], params[:udf2], params[:udf1], order.email, firstname, @productinfo, params[:amount], params[:txnid]], params[:hash])
if !checksum_matched
flash.alert = 'Malicious transaction detected.'
redirect_to checkout_state_path(order.state)
return
end
#check for order amount
if !payment_method.amount_ok?(order.total, params[:amount])
flash.alert = 'Malicious transaction detected. Order amount not matched.'
redirect_to checkout_state_path(order.state)
return
end
payment = order.payments.create!({
source_type: 'Spree::Gateway::Payumoney',#could be something generated by system
amount: order.total,
payment_method: payment_method
})
payment.started_processing!
payment.pend!
order.next
order.update_attributes({:state => "complete", :completed_at => Time.now})
if order.complete?
order.update!
flash.notice = Spree.t(:order_processed_successfully)
redirect_to order_path(order)
return
else
redirect_to checkout_state_path(order.state)
return
end
end
Gateway/Model Code
require "offsite_payments"
module Spree
class Gateway::Payumoney < Gateway
preference :merchant_id, :string
preference :secret_key, :string
def provider_class
::OffsitePayments.integration('Payu_In')
end
def provider
#assign payment mode
OffsitePayments.mode = preferred_test_mode == true ? :test : :production
provider_class
end
def checksum(items)
provider_class.checksum(preferred_merchant_id, preferred_secret_key, items)
end
def auto_capture?
true
end
def method_type
"payumoney"
end
def support?(source)
true
end
def authorization
self
end
def purchase(amount, source, gateway_options={})
ActiveMerchant::Billing::Response.new(true, "payumoney success")
end
def success?
true
end
def txnid(order)
order.id.to_s + order.number.to_s
end
def service_provider
"payu_paisa"
end
def checksum_ok?(itms, pg_hash)
Digest::SHA512.hexdigest([preferred_secret_key, *itms, preferred_merchant_id].join("|")) == pg_hash
end
def amount_ok?(order_total, pg_amount)
BigDecimal.new(pg_amount) == order_total
end
end
in spree payment doc https://guides.spreecommerce.com/developer/payments.html they have mentioned if auto_capture?
return true
then purchase method will be called but purchase method is not getting called.
Can anyone point me to right direction?
Upvotes: 0
Views: 738
Reputation: 984
I fixed the issue by marking payment as complete.
remove
payment.started_processing!
payment.pend!
add
payment.complete
above
order.next
I have published my code at github as gem https://github.com/isantoshsingh/spree_payumoney
Upvotes: 0
Reputation: 779
You need not call the following commands
payment.started_processing!
payment.pend!
Just leave the payment in its initial state. i.e. checkout
state and complete your order.
Because when order is completed process_payments!
is called.
This method processes unprocessed payments whose criteria is like below
def unprocessed_payments
payments.select { |payment| payment.checkout? }
end
Hope this solves your case :)
Upvotes: 1