Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
Fixing notification

Moar work
  • Loading branch information
Boris Slobodin committed Mar 27, 2014
1 parent 66ccb62 commit 4defb7b
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 0 deletions.
1 change: 1 addition & 0 deletions Gemfile
Expand Up @@ -4,4 +4,5 @@ gemspec
gem 'builder', '~> 3.0'
gem 'activesupport', '~> 3.2'
gem 'rails', '~> 3.2'

eval File.read(File.expand_path("../Gemfile_common", __FILE__))
30 changes: 30 additions & 0 deletions lib/active_merchant/billing/integrations/universal.rb
@@ -0,0 +1,30 @@
require File.dirname(__FILE__) + '/universal/helper.rb'
require File.dirname(__FILE__) + '/universal/notification.rb'
require File.dirname(__FILE__) + '/universal/return.rb'


module ActiveMerchant #:nodoc:
module Billing #:nodoc:
module Integrations #:nodoc:
module Universal

def self.credential_based_url(options)
options[:credential3]
end

def self.notification(post, options = {})
Notification.new(post, options)
end

def self.return(query_string, options = {})
Return.new(query_string, options)
end

def self.sign(fields, key)
Digest::HMAC.hexdigest(fields.sort.join, key, Digest::SHA1)
end

end
end
end
end
62 changes: 62 additions & 0 deletions lib/active_merchant/billing/integrations/universal/helper.rb
@@ -0,0 +1,62 @@
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
module Integrations #:nodoc:
module Universal
class Helper < ActiveMerchant::Billing::Integrations::Helper

def initialize(order, account, options = {})
super
@key = options[:credential2]
end

def generate_signature
Universal.sign(@fields, @key)
end

def form_fields
@fields.merge!(standard_fields)
@fields.merge('x-signature' => generate_signature)
end

def standard_fields
fields = {}
fields[mappings[:test]] = @test
fields
end

mapping :account, 'x-id'
mapping :currency, 'x-currency'
mapping :amount, 'x-amount'
mapping :shipping, 'x-amount-shipping'
mapping :tax, 'x-amount-tax'
mapping :order, 'x-reference'
mapping :country, 'x-shop-country'
mapping :account_name, 'x-shop-name'
mapping :transaction_type, 'x-transaction-type'
mapping :description, 'x-description'
mapping :invoice, 'x-invoice'
mapping :test, 'x-test'

mapping :customer, :first_name => 'x-customer-first-name',
:last_name => 'x-customer-last-name',
:email => 'x-customer-email',
:phone => 'x-customer-phone'

mapping :billing_address, :city => 'x-customer-city',
:company => 'x-customer-company',
:address1 => 'x-customer-address1',
:address2 => 'x-customer-address2',
:state => 'x-customer-state',
:zip => 'x-customer-zip',
:country => 'x-customer-country',
:phone => 'x-customer-phone'

mapping :notify_url, 'x-url-callback'
mapping :return_url, 'x-url-complete'
mapping :cancel_return_url, 'x-url-cancel'

end
end
end
end
end
56 changes: 56 additions & 0 deletions lib/active_merchant/billing/integrations/universal/notification.rb
@@ -0,0 +1,56 @@
require 'net/http'

module ActiveMerchant #:nodoc:
module Billing #:nodoc:
module Integrations #:nodoc:
module Universal
class Notification < ActiveMerchant::Billing::Integrations::Notification

def initialize(post, options = {})
super
@key = options[:credential2]
end

def acknowledge(authcode = nil)
signature = @params.delete('x-signature')
signature == generate_signature
end

def item_id
@params['x-reference']
end

def currency
@params['x-currency']
end

def gross
@params['x-amount']
end

def transaction_id
@params['x-gateway-reference']
end

def status
case @params['x-result']
when 'success'; 'Completed'
when 'failure'; 'Failed'
when 'pending'; 'Pending'
end
end

def test?
@params['x-test'] == 'true'
end

private
def generate_signature
Universal.sign(@params, @key)
end

end
end
end
end
end
26 changes: 26 additions & 0 deletions lib/active_merchant/billing/integrations/universal/return.rb
@@ -0,0 +1,26 @@
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
module Integrations #:nodoc:
module Universal
class Return < ActiveMerchant::Billing::Integrations::Return

def initialize(query_string, options = {})
super
@key = options[:credential2]
end

def success?
signature = @params.delete('x-signature')
signature == generate_signature
end

private
def generate_signature
Universal.sign(@params, @key)
end

end
end
end
end
end
54 changes: 54 additions & 0 deletions test/unit/integrations/helpers/universal_helper_test.rb
@@ -0,0 +1,54 @@
require 'test_helper'

class UniversalHelperTest < Test::Unit::TestCase
include ActiveMerchant::Billing::Integrations

def setup
@helper = Universal::Helper.new('order-500','cody@example.com', :amount => 500, :currency => 'USD')
end

def test_basic_helper_fields
assert_field '', 'cody@example.com'

assert_field '', '5.00'
assert_field '', 'order-500'
end

def test_customer_fields
@helper.customer :first_name => 'Cody', :last_name => 'Fauser', :email => 'cody@example.com'
assert_field '', 'Cody'
assert_field '', 'Fauser'
assert_field '', 'cody@example.com'
end

def test_address_mapping
@helper.billing_address :address1 => '1 My Street',
:address2 => '',
:city => 'Leeds',
:state => 'Yorkshire',
:zip => 'LS2 7EE',
:country => 'CA'

assert_field '', '1 My Street'
assert_field '', 'Leeds'
assert_field '', 'Yorkshire'
assert_field '', 'LS2 7EE'
end

def test_unknown_address_mapping
@helper.billing_address :farm => 'CA'
assert_equal 3, @helper.fields.size
end

def test_unknown_mapping
assert_nothing_raised do
@helper.company_address :address => '500 Dwemthy Fox Road'
end
end

def test_setting_invalid_address_field
fields = @helper.fields.dup
@helper.billing_address :street => 'My Street'
assert_equal fields, @helper.fields
end
end
@@ -0,0 +1,41 @@
require 'test_helper'

class UniversalNotificationTest < Test::Unit::TestCase
include ActiveMerchant::Billing::Integrations

def setup
@universal = Universal::Notification.new(http_raw_data)
end

def test_accessors
assert @universal.complete?
assert_equal "", @universal.status
assert_equal "", @universal.transaction_id
assert_equal "", @universal.item_id
assert_equal "", @universal.gross
assert_equal "", @universal.currency
assert_equal "", @universal.received_at
assert @universal.test?
end

def test_compositions
assert_equal Money.new(3166, 'USD'), @universal.amount
end

# Replace with real successful acknowledgement code
def test_acknowledgement

end

def test_send_acknowledgement
end

def test_respond_to_acknowledge
assert @universal.respond_to?(:acknowledge)
end

private
def http_raw_data
""
end
end
9 changes: 9 additions & 0 deletions test/unit/integrations/universal_module_test.rb
@@ -0,0 +1,9 @@
require 'test_helper'

class UniversalModuleTest < Test::Unit::TestCase
include ActiveMerchant::Billing::Integrations

def test_notification_method
assert_instance_of Universal::Notification, Universal.notification('name=cody')
end
end

0 comments on commit 4defb7b

Please sign in to comment.