unified_payment 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'UnifiedPayment'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ # APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ # load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,4 @@
1
+ module UnifiedPayment
2
+ class TransactionsController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,24 @@
1
+ module UnifiedPayment
2
+ class Transaction < ActiveRecord::Base
3
+ include Utility
4
+ self.table_name = "unified_payment_transactions"
5
+ attr_accessible :amount, :gateway_session_id, :gateway_order_id, :url, :merchant_id, :approval_code, :xml_response, :pan, :response_description, :response_status, :order_description, :currency, :gateway_order_status
6
+
7
+ def self.create_order_at_unified(amount, options)
8
+ 3.times do |attempt|
9
+ begin
10
+ @response = Client.create_order((amount.to_f)*100, options)
11
+ create(:url => @response['url'], :gateway_order_id => @response['orderId'], :gateway_session_id => @response['sessionId'], :xml_response => @response['xml_response'].to_s)
12
+ break
13
+ rescue
14
+ @response = false
15
+ end
16
+ end
17
+ @response
18
+ end
19
+
20
+ def self.extract_url_for_unified_payment(response)
21
+ response['url'] + '?' + 'ORDERID=' + response['orderId'] + '&' + 'SESSIONID=' + response['sessionId']
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ <table>
2
+ <thead>
3
+ <tr>
4
+ <th>Gateway Session Id</th>
5
+ <th>Gateway Order Id</th>
6
+ <th>Url</th>
7
+ <th>Merchant Id</th>
8
+ <th>Approval Code</th>
9
+ </tr>
10
+ </thead>
11
+ <% UnifiedPayment::Transaction.all.each do |transaction| %>
12
+ <tr>
13
+ <td><%= transaction.gateway_session_id %></td>
14
+ <td><%= transaction.gateway_order_id %></td>
15
+ <td><%= transaction.url %></td>
16
+ <td><%= transaction.merchant_id %></td>
17
+ <td><%= transaction.approval_code %></td>
18
+ </tr>
19
+ <% end %>
20
+ </table>
data/config/boot.rb ADDED
@@ -0,0 +1,5 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5
+ $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,5 @@
1
+ # Load the Rails application.
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the Rails application.
5
+ UnifiedPayment::Application.initialize!
@@ -0,0 +1,23 @@
1
+ # Files in the config/locales directory are used for internationalization
2
+ # and are automatically loaded by Rails. If you want to use locales other
3
+ # than English, add the necessary files in this directory.
4
+ #
5
+ # To use the locales, use `I18n.t`:
6
+ #
7
+ # I18n.t 'hello'
8
+ #
9
+ # In views, this is aliased to just `t`:
10
+ #
11
+ # <%= t('hello') %>
12
+ #
13
+ # To use a different locale, set it with `I18n.locale`:
14
+ #
15
+ # I18n.locale = :es
16
+ #
17
+ # This would use the information in config/locales/es.yml.
18
+ #
19
+ # To learn more, please read the Rails Internationalization guide
20
+ # available at http://guides.rubyonrails.org/i18n.html.
21
+
22
+ en:
23
+ hello: "Hello world"
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ Rails.application.routes.draw do
2
+ get '/unified_transactions', :to => 'transactions#index'
3
+ # mount UnifiedPayment::Engine => "/unified_payment"
4
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ rails generate unified_payment Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,26 @@
1
+ require 'rails/generators'
2
+ module UnifiedPayment
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc "Some description of my generator here"
5
+
6
+ # Commandline options can be defined here using Thor-like options:
7
+ class_option :my_opt, :type => :boolean, :default => false, :desc => "My Option"
8
+
9
+ # I can later access that option using:
10
+ # options[:my_opt]
11
+
12
+
13
+ def self.source_root
14
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
15
+ end
16
+
17
+ # Generator Code. Remember this is just suped-up Thor so methods are executed in order
18
+ def create_migrations
19
+ Dir["#{self.class.source_root}/migrations/*.rb"].sort.each do |filepath|
20
+ name = File.basename(filepath)
21
+ template "migrations/#{name}", "db/migrate/#{name}"
22
+ sleep 1
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ class AddUnifiedPaymentTransactions < ActiveRecord::Migration
2
+ def change
3
+ create_table :unified_payment_transactions do |t|
4
+ t.integer :gateway_order_id
5
+ t.string :gateway_order_status
6
+ t.string :amount
7
+ t.string :gateway_session_id
8
+ t.string :url
9
+ t.string :merchant_id
10
+ t.string :currency
11
+ t.string :order_description
12
+ t.string :response_status
13
+ t.string :response_description
14
+ t.string :pan
15
+ t.string :approval_code
16
+ t.text :xml_response
17
+ t.timestamps
18
+ end
19
+
20
+ add_index :unified_payment_transactions, [:gateway_order_id, :gateway_session_id], name: :order_session_index
21
+ add_index :unified_payment_transactions, :response_status
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :unified_payment do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,27 @@
1
+ module UnifiedPayment
2
+ @config = {
3
+ :merchant_name => "verbose",
4
+ :base_uri => 'http://127.0.0.1:5555'
5
+ }
6
+
7
+ @valid_config_keys = @config.keys
8
+
9
+ # Configure through hash
10
+ def self.configure(opts = {})
11
+ opts.each {|k,v| @config[k.to_sym] = v if @valid_config_keys.include? k.to_sym}
12
+ end
13
+
14
+ # Configure through yaml file
15
+ def self.configure_with(path_to_yaml_file)
16
+ config = YAML::load(IO.read(path_to_yaml_file))
17
+ global_config = config.select { |key, value| value.class != Hash } || {}
18
+ env_config = config[Rails.env] || {}
19
+ config = global_config.merge(env_config)
20
+ configure(config)
21
+ end
22
+
23
+ def self.config
24
+ @config
25
+ end
26
+ end
27
+ require "unified_payment/engine"
@@ -0,0 +1,148 @@
1
+ require 'httparty'
2
+ require 'builder'
3
+ module UnifiedPayment
4
+ # This is the usual error raised on any UnifiedPayment related Errors
5
+ class Error < RuntimeError
6
+
7
+ attr_accessor :http_response, :error, :user_error
8
+
9
+ def initialize(error, xml_response=nil, user_error=nil)
10
+ @error = error
11
+ @xml_response = xml_response
12
+ @user_error = user_error
13
+ end
14
+
15
+ def to_s
16
+ return "#{ user_error } (#{ error })" if user_error
17
+ "#{ error }"
18
+ end
19
+
20
+ end
21
+
22
+ class Client
23
+
24
+ MERCHANT_NAME = UnifiedPayment.config[:merchant_name]
25
+
26
+ include HTTParty
27
+ format :xml
28
+ base_uri UnifiedPayment.config[:base_uri]
29
+
30
+ # debug_output
31
+ follow_redirects(50)
32
+
33
+ def success?
34
+ self["orderId"]
35
+ end
36
+
37
+ def self.build_xml_for_create(amount, options)
38
+ xml_builder = ::Builder::XmlMarkup.new
39
+ xml_builder.instruct!
40
+ xml_builder.TKKPG { |tkkpg|
41
+ tkkpg.Request { |request|
42
+ request.Operation("CreateOrder")
43
+ request.Language(options[:language] || "EN")
44
+ request.Order { |order|
45
+ order.Merchant(MERCHANT_NAME)
46
+ order.Amount(amount)
47
+ order.Currency(options[:currency] || "566")
48
+ order.Description(options[:description] || "Test Order")
49
+ order.ApproveURL(options[:approve_url])
50
+ order.CancelURL(options[:cancel_url])
51
+ order.DeclineURL(options[:decline_url])
52
+ if params_to_add = options[:add_params]
53
+ order.AddParams do |add_param|
54
+ add_param.email(params_to_add[:email]) if params_to_add[:email]
55
+ add_param.phone(params_to_add[:phone]) if params_to_add[:phone]
56
+ end
57
+ end
58
+ }
59
+ }
60
+ }
61
+ xml_builder
62
+ end
63
+
64
+ def self.ping_gateway_for(operation, xml_request)
65
+ begin
66
+ response = post('/Exec', :body => xml_request.target! )
67
+ rescue => exception
68
+ raise Error.new("################### Unable to send " + operation + " request to Unified Payments Ltd " + exception.message)
69
+ end
70
+ response
71
+ end
72
+
73
+ def self.send_request_for_create(amount, options)
74
+ xml_builder = build_xml_for_create(amount, options)
75
+ ping_gateway_for('CreateOrder', xml_builder)
76
+ end
77
+
78
+ def self.create_order(amount, options={})
79
+ xml_response = send_request_for_create(amount, options)
80
+ response = xml_response["TKKPG"]["Response"]
81
+ if response["Status"] == "00"
82
+ response_order_details = response["Order"]
83
+
84
+ return { "url" => response_order_details["URL"],
85
+ "sessionId" => response_order_details["SessionID"],
86
+ "orderId" => response_order_details["OrderID"],
87
+ "Order" => response_order_details,
88
+ "Status" => response["Status"],
89
+ "xml_response" => xml_response
90
+ }
91
+ else
92
+ raise Error.new("CreateOrder Failed", response)
93
+ end
94
+ end
95
+
96
+ def self.build_xml_for(operation, order_id, session_id)
97
+ xml_builder = Builder::XmlMarkup.new
98
+ xml_builder.instruct!
99
+ xml_builder.TKKPG { |tkkpg|
100
+ tkkpg.Request { |request|
101
+ request.Operation(operation)
102
+ request.Language("EN")
103
+ request.Order { |order|
104
+ order.Merchant(MERCHANT_NAME)
105
+ order.OrderID(order_id) }
106
+ request.SessionID(session_id)
107
+ }
108
+ }
109
+ xml_builder
110
+ end
111
+
112
+ def self.send_request_for(operation, order_id, session_id)
113
+ xml_request = build_xml_for(operation, order_id, session_id)
114
+ ping_gateway_for(operation, xml_request)
115
+ end
116
+
117
+ def self.get_order_status(order_id, session_id)
118
+ xml_response = send_request_for("GetOrderStatus", order_id, session_id)
119
+ response = xml_response["TKKPG"]["Response"]
120
+
121
+ if response["Status"] == "00"
122
+ response_order_details = response["Order"]
123
+
124
+ return { "orderStatus" => response_order_details["OrderStatus"],
125
+ "orderId" => response_order_details["OrderID"],
126
+ "xml_response" => xml_response }
127
+ else
128
+ raise Error.new("GetOrderStatus Failed", xml_response)
129
+ end
130
+
131
+ end
132
+
133
+ def self.reverse(order_id, session_id)
134
+ xml_response = send_request_for("Reverse", order_id, session_id)
135
+ response = xml_response["TKKPG"]["Response"]
136
+ if response["Status"] == "00"
137
+ response_order_id, response_reversal_details = response["Order"]["OrderID"], response["Reversal"]
138
+
139
+ return { "orderId" => response_order_id,
140
+ "respCode" => response_reversal_details["RespCode"],
141
+ "respMessage" => response_reversal_details["RespMessage"],
142
+ "xml_response" => xml_response }
143
+ else
144
+ raise Error.new("Reverse Request Failed", xml_response)
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,7 @@
1
+ module UnifiedPayment
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace UnifiedPayment
4
+
5
+ config.autoload_paths += %W(#{config.root}/lib)
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ module UnifiedPayment
2
+ module Utility
3
+ def approved_at_gateway?
4
+ get_unified_order_status == 'APPROVED'
5
+ end
6
+
7
+ private
8
+ def get_unified_order_status
9
+ response = Client.get_order_status(gateway_order_id, gateway_session_id)
10
+ response['orderStatus']
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module UnifiedPayment
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+
3
+ describe UnifiedPayment::Client do
4
+ describe '#create_order' do
5
+ before do
6
+ @xml_builder = Builder::XmlMarkup.new
7
+ Builder::XmlMarkup.stub(:new).and_return(@xml_builder)
8
+ end
9
+
10
+ context 'not able to reach gateway' do
11
+ it { expect { UnifiedPayment::Client.create_order(200)}.to raise_error(UnifiedPayment::Error, "################### Unable to send CreateOrder request to Unified Payments Ltd Connection refused - connect(2)") }
12
+ end
13
+
14
+ context 'response status is not 00' do
15
+ before do
16
+ my_response = { "TKKPG" => { "Response" => { "Operation"=>"CreateOrder", "Status"=>"01", "Order"=>{"OrderID"=>"1086880", "SessionID"=>"740A7AB7EB527908EB9507154CFAD389", "URL"=> "https://mpi.valucardnigeria.com:443/index.jsp"}}}}
17
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
18
+ end
19
+
20
+ it { expect { UnifiedPayment::Client.create_order(200)}.to raise_error(UnifiedPayment::Error, "CreateOrder Failed") }
21
+ end
22
+
23
+ context 'response status is 00' do
24
+ before do
25
+ my_response = { "TKKPG" => { "Response" => { "Operation"=>"CreateOrder", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "SessionID"=>"740A7AB7EB527908EB9507154CFAD389", "URL"=> "https://mpi.valucardnigeria.com:443/index.jsp"}}}}
26
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
27
+ end
28
+
29
+ it { expect { UnifiedPayment::Client.create_order(200)}.not_to raise_error() }
30
+ it { UnifiedPayment::Client.create_order(200).should eq({"url"=>"https://mpi.valucardnigeria.com:443/index.jsp", "sessionId"=>"740A7AB7EB527908EB9507154CFAD389", "orderId"=>"1086880", "Order"=>{"OrderID"=>"1086880", "SessionID"=>"740A7AB7EB527908EB9507154CFAD389", "URL"=> "https://mpi.valucardnigeria.com:443/index.jsp"}, "Status"=>"00", "xml_response"=>{"TKKPG"=>{"Response"=>{"Operation"=>"CreateOrder", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "SessionID"=>"740A7AB7EB527908EB9507154CFAD389", "URL"=>"https://mpi.valucardnigeria.com:443/index.jsp"}}}}}) }
31
+ end
32
+
33
+ describe 'method calls' do
34
+ before do
35
+ my_response = { "TKKPG" => { "Response" => { "Operation"=>"CreateOrder", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "SessionID"=>"740A7AB7EB527908EB9507154CFAD389", "URL"=> "https://mpi.valucardnigeria.com:443/index.jsp"}}}}
36
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
37
+ end
38
+
39
+ it { Builder::XmlMarkup.should_receive(:new).and_return(@xml_builder) }
40
+ it { @xml_builder.should_receive(:instruct!).and_return(true) }
41
+
42
+ after { UnifiedPayment::Client.create_order(200) }
43
+ end
44
+
45
+ describe 'sends request along options' do
46
+ before do
47
+ my_response = { "TKKPG" => { "Response" => { "Operation"=>"CreateOrder", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "SessionID"=>"740A7AB7EB527908EB9507154CFAD389", "URL"=> "https://mpi.valucardnigeria.com:443/index.jsp"}}}}
48
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
49
+ end
50
+
51
+ context 'default options' do
52
+ before do
53
+ UnifiedPayment::Client.create_order(200, :approve_url => 'approve-url', :decline_url => 'decline-url', :cancel_url => 'cancel-url')
54
+ end
55
+
56
+ it { @xml_builder.inspect.should eq("<?xml version=\"1.0\" encoding=\"UTF-8\"?><TKKPG><Request><Operation>CreateOrder</Operation><Language>EN</Language><Order><Merchant>verbose</Merchant><Amount>200</Amount><Currency>566</Currency><Description>Test Order</Description><ApproveURL>approve-url</ApproveURL><CancelURL>cancel-url</CancelURL><DeclineURL>decline-url</DeclineURL></Order></Request></TKKPG><inspect/>")}
57
+ end
58
+
59
+ context 'Currency, Description and Language' do
60
+ before do
61
+ UnifiedPayment::Client.create_order(200,:currency => '444', :description => 'unified-payment-order', :language => 'HIN', :approve_url => 'approve-url', :decline_url => 'decline-url', :cancel_url => 'cancel-url')
62
+ end
63
+
64
+ it { @xml_builder.inspect.should eq("<?xml version=\"1.0\" encoding=\"UTF-8\"?><TKKPG><Request><Operation>CreateOrder</Operation><Language>HIN</Language><Order><Merchant>verbose</Merchant><Amount>200</Amount><Currency>444</Currency><Description>unified-payment-order</Description><ApproveURL>approve-url</ApproveURL><CancelURL>cancel-url</CancelURL><DeclineURL>decline-url</DeclineURL></Order></Request></TKKPG><inspect/>")}
65
+ end
66
+
67
+ context 'with email and phone' do
68
+ before do
69
+ UnifiedPayment::Client.create_order(200, :add_params => { :email => 'test-email@test.com', :phone => '07123456789' }, :currency => '444', :description => 'unified-payment-order', :language => 'HIN', :approve_url => 'approve-url', :decline_url => 'decline-url', :cancel_url => 'cancel-url')
70
+ end
71
+
72
+ it { @xml_builder.inspect.should eq("<?xml version=\"1.0\" encoding=\"UTF-8\"?><TKKPG><Request><Operation>CreateOrder</Operation><Language>HIN</Language><Order><Merchant>verbose</Merchant><Amount>200</Amount><Currency>444</Currency><Description>unified-payment-order</Description><ApproveURL>approve-url</ApproveURL><CancelURL>cancel-url</CancelURL><DeclineURL>decline-url</DeclineURL><AddParams><email>test-email@test.com</email><phone>07123456789</phone></AddParams></Order></Request></TKKPG><inspect/>")}
73
+ end
74
+ end
75
+ end
76
+
77
+ describe '.get_order_status' do
78
+ before do
79
+ @xml_builder = Builder::XmlMarkup.new
80
+ Builder::XmlMarkup.stub(:new).and_return(@xml_builder)
81
+ end
82
+
83
+ it { expect { UnifiedPayment::Client.get_order_status(1086880, '740A7AB7EB527908EB9507154CFAD389') }.to raise_error(UnifiedPayment::Error, '################### Unable to send GetOrderStatus request to Unified Payments Ltd Connection refused - connect(2)')}
84
+
85
+ context 'response status is not 00' do
86
+ before do
87
+ my_response = {"TKKPG"=>{"Response"=>{"Operation"=>"GetOrderStatus", "Status"=>"01", "Order"=>{"OrderID"=>"1086880", "OrderStatus"=>"CREATED"}}}}
88
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
89
+ end
90
+
91
+ it { expect { UnifiedPayment::Client.get_order_status(1086880, '740A7AB7EB527908EB9507154CFAD389') }.to raise_error(UnifiedPayment::Error, 'GetOrderStatus Failed') }
92
+ end
93
+
94
+ context 'response status is 00' do
95
+ before do
96
+ my_response = {"TKKPG"=>{"Response"=>{"Operation"=>"GetOrderStatus", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "OrderStatus"=>"CREATED"}}}}
97
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
98
+ end
99
+
100
+ it { expect { UnifiedPayment::Client.get_order_status(1086880, '740A7AB7EB527908EB9507154CFAD389') }.not_to raise_error() }
101
+ it { UnifiedPayment::Client.get_order_status(1086880, '740A7AB7EB527908EB9507154CFAD389').should eq({"orderStatus"=>"CREATED", "orderId"=>"1086880", "xml_response"=>{"TKKPG"=>{"Response"=>{"Operation"=>"GetOrderStatus", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "OrderStatus"=>"CREATED"}}}}}) }
102
+ end
103
+
104
+ describe 'sends request along options' do
105
+ before do
106
+ my_response = {"TKKPG"=>{"Response"=>{"Operation"=>"GetOrderStatus", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "OrderStatus"=>"CREATED"}}}}
107
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
108
+ UnifiedPayment::Client.get_order_status(1086880, '740A7AB7EB527908EB9507154CFAD389')
109
+ end
110
+
111
+ it { @xml_builder.inspect.should eq("<?xml version=\"1.0\" encoding=\"UTF-8\"?><TKKPG><Request><Operation>GetOrderStatus</Operation><Language>EN</Language><Order><Merchant>verbose</Merchant><OrderID>1086880</OrderID></Order><SessionID>740A7AB7EB527908EB9507154CFAD389</SessionID></Request></TKKPG><inspect/>") }
112
+ end
113
+ end
114
+
115
+ describe '.reverse' do
116
+ before do
117
+ @xml_builder = Builder::XmlMarkup.new
118
+ Builder::XmlMarkup.stub(:new).and_return(@xml_builder)
119
+ end
120
+
121
+ it { expect { UnifiedPayment::Client.reverse(1086880, '740A7AB7EB527908EB9507154CFAD389') }.to raise_error(UnifiedPayment::Error, '################### Unable to send Reverse request to Unified Payments Ltd Connection refused - connect(2)')}
122
+
123
+ context 'response status is not 00' do
124
+ before do
125
+ my_response = {"TKKPG"=>{"Response"=>{"Operation"=>"GetOrderStatus", "Status"=>"01", "Order"=>{"OrderID"=>"1086880", "OrderStatus"=>"CREATED"}, "Reversal" => {'RespCode' => '876', 'RespMessage' => 'resp-message' }}}}
126
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
127
+ end
128
+
129
+ it { expect { UnifiedPayment::Client.reverse(1086880, '740A7AB7EB527908EB9507154CFAD389') }.to raise_error(UnifiedPayment::Error, 'Reverse Request Failed') }
130
+ end
131
+
132
+ context 'response status is 00' do
133
+ before do
134
+ my_response = {"TKKPG"=>{"Response"=>{"Operation"=>"GetOrderStatus", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "OrderStatus"=>"CREATED"}, "Reversal" => {'RespCode' => '876', 'RespMessage' => 'resp-message' }}}}
135
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
136
+ end
137
+
138
+ it { expect { UnifiedPayment::Client.reverse(1086880, '740A7AB7EB527908EB9507154CFAD389') }.not_to raise_error() }
139
+ it { UnifiedPayment::Client.reverse(1086880, '740A7AB7EB527908EB9507154CFAD389').should eq({"orderId"=>"1086880", "respCode"=>"876", "respMessage"=>"resp-message", "xml_response"=>{"TKKPG"=>{"Response"=>{"Operation"=>"GetOrderStatus", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "OrderStatus"=>"CREATED"}, "Reversal"=>{"RespCode"=>"876", "RespMessage"=>"resp-message"}}}}}) }
140
+ end
141
+
142
+ describe 'sends request along options' do
143
+ before do
144
+ my_response = {"TKKPG"=>{"Response"=>{"Operation"=>"GetOrderStatus", "Status"=>"00", "Order"=>{"OrderID"=>"1086880", "OrderStatus"=>"CREATED"}, "Reversal" => {'RespCode' => '876', 'RespMessage' => 'resp-message' }}}}
145
+ UnifiedPayment::Client.stub(:post).with('/Exec', :body => @xml_builder.target!).and_return(my_response)
146
+ UnifiedPayment::Client.reverse(1086880, '740A7AB7EB527908EB9507154CFAD389')
147
+ end
148
+
149
+ it { @xml_builder.inspect.should eq("<?xml version=\"1.0\" encoding=\"UTF-8\"?><TKKPG><Request><Operation>Reverse</Operation><Language>EN</Language><Order><Merchant>verbose</Merchant><OrderID>1086880</OrderID></Order><SessionID>740A7AB7EB527908EB9507154CFAD389</SessionID></Request></TKKPG><inspect/>") }
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+
3
+ describe UnifiedPayment::Transaction do
4
+ it { UnifiedPayment::Transaction.table_name.should eq('unified_payment_transactions') }
5
+ [:gateway_session_id, :gateway_order_id, :url, :merchant_id, :approval_code].each do |attribute|
6
+ it { should allow_mass_assignment_of attribute }
7
+ end
8
+
9
+ let(:unified_payment) { UnifiedPayment::Transaction.new }
10
+ context 'utility methods' do
11
+ describe '#create_order_at_unified' do
12
+ context 'attempt fails' do
13
+ context 'never' do
14
+ before do
15
+ UnifiedPayment::Client.stub(:create_order).and_return({ 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'})
16
+ end
17
+
18
+ it 'calls to client only once with no error raised' do
19
+ UnifiedPayment::Client.should_receive(:create_order).and_return({ 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'})
20
+ UnifiedPayment::Transaction.create_order_at_unified(200, {})
21
+ end
22
+
23
+ it 'creates a unified transaction entry' do
24
+ UnifiedPayment::Transaction.should_receive(:create).with({ :url => 'https://mpi.valucardnigeria.com:443/index.jsp', :gateway_order_id => '12345', :gateway_session_id => '040C78AA2FACF4B1164EDAA27BB281A7', :xml_response => ""})
25
+ UnifiedPayment::Transaction.create_order_at_unified(200, {})
26
+ end
27
+
28
+ it 'sets response' do
29
+ UnifiedPayment::Transaction.create_order_at_unified(200, {}).should eq({ 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'})
30
+ end
31
+ end
32
+
33
+ context 'once' do
34
+ before do
35
+ UnifiedPayment::Client.stub(:create_order).once.and_raise(UnifiedPayment::Error.new("Unable to send create order request to Unified Payments Ltd. ERROR: Connection refused - connect(2)") )
36
+ UnifiedPayment::Client.stub(:create_order).once.and_return({ 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'})
37
+ end
38
+
39
+ it 'calls to client twice with error raise once' do
40
+ UnifiedPayment::Client.should_receive(:create_order).once.and_raise(UnifiedPayment::Error.new("Unable to send create order request to Unified Payments Ltd. ERROR: Connection refused - connect(2)") )
41
+ UnifiedPayment::Client.should_receive(:create_order).once.and_return({ 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'})
42
+ UnifiedPayment::Transaction.create_order_at_unified(200, {})
43
+ end
44
+
45
+ it 'sets response' do
46
+ UnifiedPayment::Transaction.create_order_at_unified(200, {}).should eq({ 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'})
47
+ end
48
+ end
49
+
50
+ context 'twice' do
51
+ before do
52
+ UnifiedPayment::Client.stub(:create_order).twice.and_raise(UnifiedPayment::Error.new("Unable to send create order request to Unified Payments Ltd. ERROR: Connection refused - connect(2)") )
53
+ UnifiedPayment::Client.stub(:create_order).once.and_return({ 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'})
54
+ end
55
+
56
+ it 'calls to client thrice with error raise twice' do
57
+ UnifiedPayment::Client.should_receive(:create_order).twice.and_raise(UnifiedPayment::Error.new("Unable to send create order request to Unified Payments Ltd. ERROR: Connection refused - connect(2)") )
58
+ UnifiedPayment::Client.should_receive(:create_order).once.and_return({ 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'})
59
+ UnifiedPayment::Transaction.create_order_at_unified(200, {})
60
+ end
61
+
62
+ it 'sets response' do
63
+ UnifiedPayment::Transaction.create_order_at_unified(200, {}).should eq({ 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'})
64
+ end
65
+ end
66
+
67
+ context 'thrice' do
68
+ before do
69
+ UnifiedPayment::Client.stub(:create_order).and_raise(UnifiedPayment::Error.new("Unable to send create order request to Unified Payments Ltd. ERROR: Connection refused - connect(2)"))
70
+ end
71
+
72
+ it 'calls to client thrice with error raised thrice' do
73
+ UnifiedPayment::Client.should_receive(:create_order).exactly(3).times.and_raise(UnifiedPayment::Error.new("Unable to send create order request to Unified Payments Ltd. ERROR: Connection refused - connect(2)"))
74
+ UnifiedPayment::Transaction.create_order_at_unified(200, {})
75
+ end
76
+
77
+ it 'sets response false' do
78
+ UnifiedPayment::Transaction.create_order_at_unified(200, {}).should be_false
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ describe '#extract_url_for_unified_payment' do
85
+ before do
86
+ @response = { 'url' => 'https://mpi.valucardnigeria.com:443/index.jsp', 'orderId' => '12345', 'sessionId' => '040C78AA2FACF4B1164EDAA27BB281A7'}
87
+ end
88
+
89
+ it { UnifiedPayment::Transaction.extract_url_for_unified_payment(@response).should eq('https://mpi.valucardnigeria.com:443/index.jsp?ORDERID=12345&SESSIONID=040C78AA2FACF4B1164EDAA27BB281A7') }
90
+ end
91
+
92
+ describe '#approved_at_gateway?' do
93
+ context 'when approved' do
94
+ before { unified_payment.stub(:get_unified_order_status).and_return('APPROVED') }
95
+
96
+ it { unified_payment.should be_approved_at_gateway }
97
+ end
98
+
99
+ context 'when not approved' do
100
+ before { unified_payment.stub(:get_unified_order_status).and_return('NOT-APPROVED') }
101
+
102
+ it { unified_payment.should_not be_approved_at_gateway }
103
+ end
104
+ end
105
+
106
+ describe '#get_unified_order_status' do
107
+ before do
108
+ unified_payment.stub(:gateway_order_id).and_return('12345')
109
+ unified_payment.stub(:gateway_session_id).and_return('040C78AA2FACF4B1164EDAA27BB281A7')
110
+ UnifiedPayment::Client.stub(:get_order_status).with(unified_payment.gateway_order_id, unified_payment.gateway_session_id).and_return('orderStatus' => 'APPROVED')
111
+ end
112
+
113
+ it 'calls client' do
114
+ UnifiedPayment::Client.should_receive(:get_order_status).with(unified_payment.gateway_order_id, unified_payment.gateway_session_id).and_return('orderStatus' => 'APPROVED')
115
+ unified_payment.send(:get_unified_order_status)
116
+ end
117
+
118
+ it { unified_payment.send(:get_unified_order_status).should eq('APPROVED')}
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,45 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ require File.expand_path("../../config/environment", __FILE__)
4
+ # require 'rspec/rails'
5
+ # require 'rspec/autorun'
6
+
7
+ require 'rubygems'
8
+ require 'bundler/setup'
9
+ require 'unified_payment'
10
+ # Requires supporting ruby files with custom matchers and macros, etc,
11
+ # in spec/support/ and its subdirectories.
12
+ # Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
13
+
14
+ # Checks for pending migrations before tests are run.
15
+ # If you are not using ActiveRecord, you can remove this line.
16
+ # ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
17
+
18
+ RSpec.configure do |config|
19
+ # ## Mock Framework
20
+ #
21
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
22
+ #
23
+ # config.mock_with :mocha
24
+ # config.mock_with :flexmock
25
+ # config.mock_with :rr
26
+
27
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
28
+ # config.fixture_path = "#{::Rails.root}/spec/fixtures"
29
+
30
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
31
+ # examples within a transaction, remove the following line or assign false
32
+ # instead of true.
33
+ # config.use_transactional_fixtures = true
34
+
35
+ # If true, the base class of anonymous controllers will be inferred
36
+ # automatically. This will be the default behavior in future versions of
37
+ # rspec-rails.
38
+ # config.infer_base_class_for_anonymous_controllers = false
39
+
40
+ # Run specs in random order to surface order dependencies. If you find an
41
+ # order dependency and want to debug it, you can fix the order by providing
42
+ # the seed, which is printed after each run.
43
+ # --seed 1234
44
+ config.order = "random"
45
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: unified_payment
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Manish Kangia
14
+ - Sushant Mittal
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2014-02-27 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rails
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">"
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 3
32
+ - 0
33
+ version: "3.0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ description: Interface to handle payments via UnifiedPayment for rails app.
37
+ email:
38
+ - info@vinsol.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - app/controllers/unified_payment/transactions_controller.rb
47
+ - app/models/unified_payment/transaction.rb
48
+ - app/views/unified_payment/transactions/index.html.erb
49
+ - config/boot.rb
50
+ - config/environment.rb
51
+ - config/locales/en.yml
52
+ - config/routes.rb
53
+ - lib/generators/unified_payment/install_generator.rb
54
+ - lib/generators/unified_payment/templates/migrations/20131101092408_add_unified_payment_transactions.rb
55
+ - lib/generators/unified_payment/USAGE
56
+ - lib/tasks/unified_payment_tasks.rake
57
+ - lib/unified_payment/client.rb
58
+ - lib/unified_payment/engine.rb
59
+ - lib/unified_payment/utility.rb
60
+ - lib/unified_payment/version.rb
61
+ - lib/unified_payment.rb
62
+ - Rakefile
63
+ - spec/Libraries/client_spec.rb
64
+ - spec/models/unified_payment/transaction_spec.rb
65
+ - spec/spec_helper.rb
66
+ homepage: http://vinsol.com
67
+ licenses:
68
+ - MIT
69
+ post_install_message:
70
+ rdoc_options: []
71
+
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project:
95
+ rubygems_version: 1.8.24
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Interface to handle payments via UnifiedPayment for rails app.
99
+ test_files:
100
+ - spec/Libraries/client_spec.rb
101
+ - spec/models/unified_payment/transaction_spec.rb
102
+ - spec/spec_helper.rb