class Veritrans::Events
Rack based event notification callback processor
Usage:
Rails.application.routes.draw do # ... mount Veritrans::Events.new => '/vt_events' end Veritrans::Events.subscribe('payment.success') do |payment| payment.mark_paid!(payment.masked_card) end
All possible events:
-
payment.success == ['authorize', 'capture', 'settlement']
-
payment.failed == ['deny', 'cancel', 'expire']
-
payment.challenge # when payment.fraud_status == 'challenge'
-
payment.authorize
-
payment.capture
-
payment.settlement
-
payment.deny
-
payment.cancel
-
payment.expire
-
error
For sinatra you can use Rack::URLMap
run Rack::URLMap.new("/" => MyApp.new, "/payment_events" => Veritrans::Events.new)
Attributes
listeners[RW]
Public Class Methods
dispatch(new_event, event_data)
click to toggle source
Used internally to dispatch event
# File lib/veritrans/events.rb, line 122 def dispatch(new_event, event_data) @listeners.each do |pair| event_type, handler = *pair if event_type.is_a?(String) && event_type == new_event handler.call(event_data) elsif event_type.is_a?(Regexp) && event_type =~ new_event handler.call(event_data, new_event) end end end
subscribe(*event_types, &handler)
click to toggle source
Subscribe for events. The event object will be an instance of Midtrans::Result
Midtrans::Events.subscribe('payment.success') do |payment_status| Order.find_by(order_id: payment_status.order_id).mark_paid! end
# File lib/veritrans/events.rb, line 114 def subscribe(*event_types, &handler) @listeners ||= [] event_types.each do |event_type| @listeners << [event_type, handler] end end
Public Instance Methods
call(env)
click to toggle source
This is rack application Can be used as:
use Veritrans::Events.new
# File lib/veritrans/events.rb, line 43 def call(env) Veritrans.logger.info "Receive notification callback" post_body = env["rack.input"].read env["rack.input"].rewind request_data = Veritrans.decode_notification_json(post_body) Veritrans.file_logger.info("Callback for order: " + "#{request_data['order_id']} #{request_data['transaction_status']}\n" + post_body + "\n" ) verified_data = Veritrans.status(request_data['transaction_id']) if verified_data.status_code != 404 #puts "--- Transaction callback ---" #puts "Payment: #{verified_data.data[:order_id]}" #puts "Payment type: #{verified_data.data[:payment_type]}" #puts "Payment status: #{verified_data.data[:transaction_status]}" #puts "Fraud status: #{verified_data.data[:fraud_status]}" if verified_data.data[:fraud_status] #puts "Payment amount: #{verified_data.data[:gross_amount]}" #puts "--- Transaction callback ---" event_name = verified_data.data[:transaction_status] if verified_data.data[:fraud_status] == 'challenge' event_name = 'challenge' end Veritrans::Events.dispatch("payment.#{event_name}", verified_data) if %w{capture authorize settlement}.include?(event_name) Veritrans::Events.dispatch("payment.success", verified_data) elsif event_name != 'challenge' Veritrans::Events.dispatch("payment.failed", verified_data) end return send_text("ok", 200) else Veritrans::Events.dispatch("error", request_data) Veritrans.file_logger.info("Callback verification failed:" + "#{request_data['order_id']} #{request_data['transaction_status']}}\n" + verified_data.body + "\n" ) return send_text("Can not verify payment via Payment API: #{verified_data.status_message}", 404) end rescue Object => error Veritrans.file_logger.info("Callback proccesing failed. \n" + "RAW_POST_DATA: #{env["rack.input"].read}\n" + error.message + error.backtrace.join("\n") + "\n" ) Veritrans::Events.dispatch("error", verified_data || request_data || post_body) return send_text("Server error:\n#{error.message}", 500) end