bancomer-active_merchant 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jorge Calás
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = bancomer-active_merchant
2
+
3
+ Active Merchant Integration for Bancomer (Mexico)
4
+
5
+ = WARNING: This is still pre-alfa don't use in production.
6
+
7
+ == Note on Patches/Pull Requests
8
+
9
+ * Fork the project.
10
+ * Make your feature addition or bug fix.
11
+ * Add tests for it. This is important so I don't break it in a
12
+ future version unintentionally.
13
+ * Commit, do not mess with rakefile, version, or history.
14
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
15
+ * Send me a pull request. Bonus points for topic branches.
16
+
17
+ == Copyright
18
+
19
+ Copyright (c) 2009 Jorge Calás. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "bancomer-active_merchant"
8
+ gem.summary = %Q{Bancomer Integration for ActiveMerchant}
9
+ gem.description = %Q{A plugin for ActiveMerchant to provide Bancomer Integration}
10
+ gem.email = "calas@railsdog.com"
11
+ gem.homepage = "http://github.com/calas/bancomer-active_merchant"
12
+ gem.authors = ["Jorge Calás"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/test_*.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+ task :test => :check_dependencies
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "bancomer-active_merchant #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,50 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Bancomer
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper
6
+
7
+ def initialize(order, account, options = {})
8
+ super
9
+ add_field('Ds_Merchant_Currency', 484)
10
+ add_field('Ds_Merchant_TransactionType', 0)
11
+ add_field('Ds_Merchant_Order', format_order_number(order))
12
+ add_field('Ds_Merchant_MerchantCode', account)
13
+ add_field('Ds_Merchant_Terminal', 1)
14
+ end
15
+
16
+ # Limited to 12 digits max
17
+ def format_order_number(number)
18
+ number.to_s.gsub(/[A-Z]/, '').rjust(12, "0")
19
+ end
20
+
21
+ def sha1secret(value)
22
+ @sha1secret = value
23
+ end
24
+
25
+ def form_fields
26
+ @fields.merge('Ds_Merchant_MerchantSignature' => generate_sha1check)
27
+ end
28
+
29
+ def generate_sha1string
30
+ SHA1_CHECK_FIELDS.map {|key| @fields[key.to_s]} * "" + @sha1secret
31
+ end
32
+
33
+ def generate_sha1check
34
+ Digest::SHA1.hexdigest(generate_sha1string)
35
+ end
36
+
37
+ SHA1_CHECK_FIELDS = [ 'Ds_Merchant_Amount', 'Ds_Merchant_Order',
38
+ 'Ds_Merchant_MerchantCode', 'Ds_Merchant_Currency',
39
+ 'Ds_Merchant_TransactionType' ]
40
+
41
+ mapping :amount, 'Ds_Merchant_Amount'
42
+ mapping :notify_url, 'Ds_Merchant_MerchantURL'
43
+ mapping :return_url, 'Ds_Merchant_UrlOk'
44
+ mapping :cancel_return_url, 'Ds_Merchant_UrlKo'
45
+ mapping :description, 'Ds_Merchant_ProductDescription'
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,78 @@
1
+ require 'net/http'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ module Integrations #:nodoc:
6
+ module Bancomer
7
+ class Notification < ActiveMerchant::Billing::Integrations::Notification
8
+ ['Ds_Date', 'Ds_Hour', 'Ds_Amount', 'Ds_Currency',
9
+ 'Ds_Order', 'Ds_MerchantCode', 'Ds_Terminal',
10
+ 'Ds_Signature', 'Ds_Response', 'Ds_MerchantData',
11
+ 'Ds_SecurePayment', 'Ds_TransactionType',
12
+ 'Ds_ConsumerLanguage', 'Ds_ErrorCode' ].each do |attr|
13
+ define_method(attr.downcase) do
14
+ params[attr]
15
+ end
16
+ end
17
+
18
+ def complete?
19
+ status == '000'
20
+ end
21
+
22
+ def item_id
23
+ ds_order
24
+ end
25
+
26
+ def transaction_id
27
+ ds_order
28
+ end
29
+
30
+ def received_at
31
+ DateTime.strptime("#{ds_date} #{ds_hour}", "%d/%m/%Y %H:%M")
32
+ end
33
+
34
+ def security_key
35
+ ds_signature
36
+ end
37
+
38
+ def currency
39
+ ds_currency
40
+ end
41
+
42
+ def gross
43
+ "%.2f" % (gross_cents / 100.0)
44
+ end
45
+
46
+ def gross_cents
47
+ ds_amount.to_i
48
+ end
49
+
50
+ # Was this a test transaction?
51
+ def test?
52
+ false
53
+ end
54
+
55
+ def status
56
+ ds_response
57
+ end
58
+
59
+ SHA1_CHECK_FIELDS = [ 'Ds_Amount', 'Ds_Order', 'Ds_MerchantCode', 'Ds_Currency', 'Ds_Response' ]
60
+
61
+ def generate_sha1string
62
+ SHA1_CHECK_FIELDS.map { |key| params[key.to_s] } * "" + @options[:sha1secret]
63
+ end
64
+
65
+ def generate_sha1check
66
+ Digest::SHA1.hexdigest(generate_sha1string)
67
+ end
68
+
69
+ # Quickpay doesn't do acknowledgements of callback notifications
70
+ # Instead it uses and SHA1 hash of all parameters
71
+ def acknowledge
72
+ generate_sha1check == ds_signature
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/bancomer/helper.rb'
2
+ require File.dirname(__FILE__) + '/bancomer/notification.rb'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ module Integrations #:nodoc:
7
+ module Bancomer
8
+ mattr_accessor :service_url
9
+
10
+ self.service_url = 'https://www.bancomer.eglobal.com.mx/sis/entradaPagos'
11
+
12
+ def self.notification(post)
13
+ Notification.new(post)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,98 @@
1
+ require 'active_merchant'
2
+ require 'test/unit'
3
+ require 'mocha'
4
+ require 'yaml'
5
+
6
+ begin
7
+ gem 'actionpack'
8
+ rescue LoadError
9
+ raise StandardError, "The view tests need ActionPack"
10
+ end
11
+
12
+ require 'action_controller'
13
+ require 'action_controller/test_process'
14
+ require 'active_merchant/billing/integrations/action_view_helper'
15
+
16
+ ActiveMerchant::Billing::Base.mode = :test
17
+
18
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
19
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
20
+ require 'active_merchant/bancomer'
21
+
22
+ module ActiveMerchant
23
+ module Assertions
24
+ def assert_field(field, value)
25
+ clean_backtrace do
26
+ assert_equal value, @helper.fields[field]
27
+ end
28
+ end
29
+
30
+ # Allows the testing of you to check for negative assertions:
31
+ #
32
+ # # Instead of
33
+ # assert !something_that_is_false
34
+ #
35
+ # # Do this
36
+ # assert_false something_that_should_be_false
37
+ #
38
+ # An optional +msg+ parameter is available to help you debug.
39
+ def assert_false(boolean, message = nil)
40
+ message = build_message message, '<?> is not false or nil.', boolean
41
+
42
+ clean_backtrace do
43
+ assert_block message do
44
+ not boolean
45
+ end
46
+ end
47
+ end
48
+
49
+ # A handy little assertion to check for a successful response:
50
+ #
51
+ # # Instead of
52
+ # assert_success response
53
+ #
54
+ # # DRY that up with
55
+ # assert_success response
56
+ #
57
+ # A message will automatically show the inspection of the response
58
+ # object if things go afoul.
59
+ def assert_success(response)
60
+ clean_backtrace do
61
+ assert response.success?, "Response failed: #{response.inspect}"
62
+ end
63
+ end
64
+
65
+ # The negative of +assert_success+
66
+ def assert_failure(response)
67
+ clean_backtrace do
68
+ assert_false response.success?, "Response expected to fail: #{response.inspect}"
69
+ end
70
+ end
71
+
72
+ def assert_valid(validateable)
73
+ clean_backtrace do
74
+ assert validateable.valid?, "Expected to be valid"
75
+ end
76
+ end
77
+
78
+ def assert_not_valid(validateable)
79
+ clean_backtrace do
80
+ assert_false validateable.valid?, "Expected to not be valid"
81
+ end
82
+ end
83
+
84
+ private
85
+ def clean_backtrace(&block)
86
+ yield
87
+ rescue Test::Unit::AssertionFailedError => e
88
+ path = File.expand_path(__FILE__)
89
+ raise Test::Unit::AssertionFailedError, e.message, e.backtrace.reject { |line| File.expand_path(line) =~ /#{path}/ }
90
+ end
91
+ end
92
+ end
93
+
94
+ class Test::Unit::TestCase
95
+ include ActiveMerchant::Billing
96
+ include ActiveMerchant::Assertions
97
+ include ActiveMerchant::Utils
98
+ end
@@ -0,0 +1,91 @@
1
+ require "helper"
2
+
3
+ class BancomerModuleTest < Test::Unit::TestCase
4
+ include ActiveMerchant::Billing::Integrations
5
+
6
+ def test_notification_method
7
+ assert_instance_of Bancomer::Notification, Bancomer.notification('name=cody')
8
+ end
9
+ end
10
+
11
+ class BancomerHelperTest < Test::Unit::TestCase
12
+ include ActiveMerchant::Billing::Integrations
13
+
14
+ def setup
15
+ @helper = Bancomer::Helper.new('R987654321','1234567', :amount => 500)
16
+ @helper.sha1secret "mysecretsha1string"
17
+ @helper.return_url 'http://example.com/ok'
18
+ @helper.cancel_return_url 'http://example.com/cancel'
19
+ @helper.notify_url 'http://example.com/notify'
20
+ @helper.description 'Product Description'
21
+ end
22
+
23
+ def test_basic_helper_fields
24
+ assert_field 'Ds_Merchant_MerchantCode', '1234567'
25
+ assert_field 'Ds_Merchant_Amount', '500'
26
+ assert_field 'Ds_Merchant_Order', '000987654321'
27
+ assert_field 'Ds_Merchant_UrlOk', 'http://example.com/ok'
28
+ assert_field 'Ds_Merchant_UrlKo', 'http://example.com/cancel'
29
+ assert_field 'Ds_Merchant_MerchantURL', 'http://example.com/notify'
30
+ assert_field 'Ds_Merchant_ProductDescription', 'Product Description'
31
+ end
32
+
33
+ def test_minimum_fields
34
+ assert @helper.form_fields.size >= 9
35
+ end
36
+
37
+ def test_secret_generation
38
+ assert_not_nil @helper.form_fields['Ds_Merchant_MerchantSignature']
39
+ end
40
+
41
+ def test_unknown_mapping
42
+ assert_nothing_raised do
43
+ @helper.company_address :address => '500 Dwemthy Fox Road'
44
+ end
45
+ end
46
+
47
+ def test_setting_invalid_address_field
48
+ fields = @helper.fields.dup
49
+ @helper.billing_address :street => 'My Street'
50
+ assert_equal fields, @helper.fields
51
+ end
52
+ end
53
+
54
+ class BancomerNotificationTest < Test::Unit::TestCase
55
+ include ActiveMerchant::Billing::Integrations
56
+
57
+ def setup
58
+ @bancomer = Bancomer::Notification.new(http_raw_data, :sha1secret => "mysecretsha1string")
59
+ end
60
+
61
+ def test_accessors
62
+ assert @bancomer.complete?
63
+ assert_equal "000", @bancomer.status
64
+ assert_equal "000987654321", @bancomer.transaction_id
65
+ assert_equal "000987654321", @bancomer.item_id
66
+ assert_equal "5.00", @bancomer.gross
67
+ assert_equal "484", @bancomer.currency
68
+ assert_equal DateTime.parse('2009 Feb 2, 10:25'), @bancomer.received_at
69
+ end
70
+
71
+ # Replace with real successful acknowledgement code
72
+ def test_acknowledgement
73
+ assert @bancomer.acknowledge
74
+ end
75
+
76
+ def test_respond_to_acknowledge
77
+ assert @bancomer.respond_to?(:acknowledge)
78
+ end
79
+
80
+ private
81
+
82
+ # Digest::SHA1.hexdigest("5000009876543211234567484000mysecretsha1string")
83
+ def http_raw_data
84
+ "Ds_Date=02%2F02%2F2009&Ds_Hour=10:25&Ds_Amount=500" +
85
+ "&Ds_Currency=484&Ds_Order=000987654321&Ds_MerchantCode=1234567" +
86
+ "&Ds_Terminal=1&Ds_Signature=4ab324115ec93c45a969656dda0f1d6aa79e807a" +
87
+ "&Ds_Response=000&Ds_MerchantData=&Ds_SecurePayment=1" +
88
+ "&Ds_TransactionType=0&Ds_ConsumerLanguage=0"
89
+ end
90
+
91
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bancomer-active_merchant
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - "Jorge Cal\xC3\xA1s"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-26 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A plugin for ActiveMerchant to provide Bancomer Integration
17
+ email: calas@railsdog.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.rdoc
30
+ - Rakefile
31
+ - VERSION
32
+ - lib/active_merchant/bancomer.rb
33
+ - lib/active_merchant/bancomer/helper.rb
34
+ - lib/active_merchant/bancomer/notification.rb
35
+ - test/helper.rb
36
+ - test/test_bancomer-active_merchant.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/calas/bancomer-active_merchant
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Bancomer Integration for ActiveMerchant
65
+ test_files:
66
+ - test/helper.rb
67
+ - test/test_bancomer-active_merchant.rb