beanstreamy 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -31,6 +31,7 @@ begin
31
31
  gemspec.email = "jeff@stage2.ca"
32
32
  gemspec.homepage = "http://github.com/jdsiegel/beanstreamy"
33
33
  gemspec.authors = ["Jeff Siegel"]
34
+ gemspec.add_dependency('activemerchant', '>= 1.5.1')
34
35
  end
35
36
  rescue LoadError
36
37
  puts "Jeweler not available. Install it with: gem install jeweler"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/beanstreamy.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{beanstreamy}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeff Siegel"]
12
- s.date = %q{2010-06-16}
12
+ s.date = %q{2010-07-09}
13
13
  s.description = %q{Currently provides a helper method for rendering forms that will submit to the beanstream hosted payment gateway}
14
14
  s.email = %q{jeff@stage2.ca}
15
15
  s.extra_rdoc_files = [
@@ -27,7 +27,9 @@ Gem::Specification.new do |s|
27
27
  "generators/beanstreamy/templates/beanstreamy.rb",
28
28
  "init.rb",
29
29
  "lib/beanstreamy.rb",
30
+ "lib/beanstreamy/gateway.rb",
30
31
  "lib/beanstreamy/hosted_payment_helper.rb",
32
+ "lib/beanstreamy/util.rb",
31
33
  "lib/tasks/beanstreamy.rake",
32
34
  "test/beanstreamy_test.rb",
33
35
  "test/test_helper.rb"
@@ -47,9 +49,12 @@ Gem::Specification.new do |s|
47
49
  s.specification_version = 3
48
50
 
49
51
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<activemerchant>, [">= 1.5.1"])
50
53
  else
54
+ s.add_dependency(%q<activemerchant>, [">= 1.5.1"])
51
55
  end
52
56
  else
57
+ s.add_dependency(%q<activemerchant>, [">= 1.5.1"])
53
58
  end
54
59
  end
55
60
 
@@ -17,3 +17,6 @@ Beanstreamy.config.hash_key = ""
17
17
 
18
18
  # If you use your own declined page, you can set that here:
19
19
  # Beanstreamy.config.declined_url = "/some/path"
20
+
21
+ # If you use your own error page, you can set that here:
22
+ # Beanstreamy.config.error_url = "/some/path"
data/lib/beanstreamy.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Beanstreamy
2
2
  class Config
3
- attr_accessor :payment_url, :merchant_id, :hash_key, :approved_url, :declined_url
3
+ attr_accessor :payment_url, :merchant_id, :hash_key, :approved_url, :declined_url, :error_url
4
4
 
5
5
  def initialize
6
6
  @payment_url = "https://www.beanstream.com/scripts/payment/payment.asp"
@@ -11,6 +11,13 @@ module Beanstreamy
11
11
  @@config = Config.new
12
12
  end
13
13
 
14
- require 'beanstreamy/hosted_payment_helper'
14
+ require 'active_merchant'
15
15
 
16
- ActionView::Base.send :include, Beanstreamy::HostedPaymentHelper
16
+ require 'beanstreamy/util'
17
+ require 'beanstreamy/gateway'
18
+
19
+ if defined?(ActionView)
20
+ require 'beanstreamy/hosted_payment_helper'
21
+
22
+ ActionView::Base.send :include, Beanstreamy::HostedPaymentHelper
23
+ end
@@ -0,0 +1,59 @@
1
+ require 'active_merchant/billing/gateways/beanstream'
2
+
3
+ module Beanstreamy
4
+ module QueryAction
5
+ EXTRA_TRANSACTIONS = { :query => 'Q' }
6
+
7
+ CVD_CODES = ActiveMerchant::Billing::BeanstreamCore::CVD_CODES
8
+ AVS_CODES = ActiveMerchant::Billing::BeanstreamCore::AVS_CODES
9
+
10
+ def response_from_query(query_string)
11
+ response = parse(query_string)
12
+ build_response(success?(response), message_from(response), response,
13
+ :test => test? || response[:authCode] == "TEST",
14
+ :authorization => authorization_from(response),
15
+ :cvv_result => CVD_CODES[response[:cvdId]],
16
+ :avs_result => { :code => (AVS_CODES.include? response[:avsId]) ? AVS_CODES[response[:avsId]] : response[:avsId] }
17
+ )
18
+ end
19
+
20
+ def query(amount, options={})
21
+ requires!(options, :order_id)
22
+
23
+ post = {}
24
+ add_order_number(post, options[:order_id])
25
+ add_amount(post, amount)
26
+ add_transaction_type(post, :query)
27
+ commit(post)
28
+ end
29
+
30
+ private
31
+
32
+ def add_transaction_type(post, action)
33
+ post[:trnType] = EXTRA_TRANSACTIONS[action] || super
34
+ end
35
+
36
+ def add_order_number(post, order_id)
37
+ post[:trnOrderNumber] = order_id
38
+ end
39
+ end
40
+
41
+ module HashValidation
42
+ private
43
+
44
+ def post_data(params)
45
+ params = super
46
+
47
+ hash_key = @options[:hash_key]
48
+ if hash_key
49
+ params += "&hashValue=#{CGI.escape(Util.hash_value(hash_key, params))}"
50
+ end
51
+ params
52
+ end
53
+ end
54
+
55
+ ActiveMerchant::Billing::BeanstreamGateway.class_eval do
56
+ include QueryAction
57
+ include HashValidation
58
+ end
59
+ end
@@ -12,34 +12,42 @@ module Beanstreamy
12
12
  hash_key = options.delete(:hash_key) || config.hash_key
13
13
  approved_url = options.delete(:approved_url) || config.approved_url
14
14
  declined_url = options.delete(:declined_url) || config.declined_url
15
+ error_url = options.delete(:error_url)
16
+
17
+ skip_hash = options.delete(:skip_hash)
18
+ extra_params = options.delete(:params)
19
+
20
+ hashed_params = [["merchant_id", merchant_id],
21
+ ["trnOrderNumber", order_id],
22
+ ["trnAmount", amount]]
23
+ hashed_params << ["approvedPage", approved_url] if approved_url.present?
24
+ hashed_params << ["declinedPage", declined_url] if declined_url.present?
25
+ hashed_params << ["errorPage", error_url] if error_url.present?
26
+
27
+ if expire_at = options.delete(:expire_at)
28
+ hashed_params << ["hashExpiry", Util.hash_expiry(expire_at)]
29
+ end
30
+
31
+ hashed_params += Array(extra_params)
15
32
 
16
33
  form = content_tag(:form, options.merge(:action => config.payment_url, :method => "post")) do
17
- concat hidden_field_tag("merchant_id", merchant_id)
18
- concat hidden_field_tag("trnOrderNumber", order_id)
19
- concat hidden_field_tag("trnAmount", amount)
20
- if approved_url.present?
21
- concat hidden_field_tag("approvedPage", approved_url)
22
- end
23
- if declined_url.present?
24
- concat hidden_field_tag("declinedPage", declined_url)
34
+ hashed_params.each do |key, value|
35
+ concat hidden_field_tag(key, value)
25
36
  end
26
37
 
27
- # Beansream's hosted page uses hash validation to prevent price modification. This hash is computed from
28
- # the url encoded string of the above inputs
29
- query_params = [
30
- ["merchant_id", merchant_id],
31
- ["trnOrderNumber", order_id],
32
- ["trnAmount", amount],
33
- ["approvedPage", approved_url],
34
- ["declinedPage", declined_url]
35
- ]
36
- query_string = query_params.reject { |k,v| v.blank? }.map { |k,v| v.to_query(k) }.join('&')
37
- hash_value = Digest::SHA1.hexdigest(query_string + hash_key)
38
+ hash_value = nil
39
+ if hash_key.present? && !skip_hash
40
+ # Beansream's hosted page uses hash validation to prevent price modification. This hash is computed from
41
+ # the url encoded string of the above inputs
42
+ query_string = hashed_params.reject { |k,v| v.blank? }.map { |k,v| v.to_query(k) }.join('&')
43
+ hash_value = Util.hash_value(hash_key, query_string)
38
44
 
39
- concat hidden_field_tag("hashValue", hash_value)
45
+ concat hidden_field_tag("hashValue", hash_value)
46
+ end
40
47
 
41
48
  block.call(:hash_value => hash_value, :query_string => query_string)
42
49
  end
50
+
43
51
  concat form
44
52
  end
45
53
  end
@@ -0,0 +1,13 @@
1
+ module Beanstreamy
2
+ module Util
3
+ def self.hash_value(key, message)
4
+ Digest::SHA1.hexdigest(message + key)
5
+ end
6
+
7
+ def self.hash_expiry(expire_at)
8
+ # Beanstream uses PST/PDT for all their timestamps. Time stamps only have minute resolution,
9
+ # so the seconds need chopping off.
10
+ expire_at.in_time_zone("Pacific Time (US & Canada)").to_s(:number)[0..-3]
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jeff Siegel
@@ -14,10 +14,23 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-16 00:00:00 -06:00
17
+ date: 2010-07-09 00:00:00 -06:00
18
18
  default_executable:
19
- dependencies: []
20
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activemerchant
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 5
30
+ - 1
31
+ version: 1.5.1
32
+ type: :runtime
33
+ version_requirements: *id001
21
34
  description: Currently provides a helper method for rendering forms that will submit to the beanstream hosted payment gateway
22
35
  email: jeff@stage2.ca
23
36
  executables: []
@@ -38,7 +51,9 @@ files:
38
51
  - generators/beanstreamy/templates/beanstreamy.rb
39
52
  - init.rb
40
53
  - lib/beanstreamy.rb
54
+ - lib/beanstreamy/gateway.rb
41
55
  - lib/beanstreamy/hosted_payment_helper.rb
56
+ - lib/beanstreamy/util.rb
42
57
  - lib/tasks/beanstreamy.rake
43
58
  - test/beanstreamy_test.rb
44
59
  - test/test_helper.rb