beanstreamy 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/beanstreamy.gemspec +2 -2
- data/lib/beanstreamy/gateway.rb +12 -0
- data/lib/beanstreamy/hosted_payment_helper.rb +73 -7
- data/lib/beanstreamy/util.rb +54 -0
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.2
|
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.2.
|
8
|
+
s.version = "0.2.2"
|
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-07-
|
12
|
+
s.date = %q{2010-07-12}
|
13
13
|
s.description = %q{Adds activemerchant gateway support for hash validation, querying transactions, and submitting payment via hosted forms}
|
14
14
|
s.email = %q{jeff@stage2.ca}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/beanstreamy/gateway.rb
CHANGED
@@ -29,6 +29,18 @@ module Beanstreamy
|
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
+
def parse(body)
|
33
|
+
results = super
|
34
|
+
|
35
|
+
if results[:errorMessage]
|
36
|
+
results[:errorMessage].gsub!(/<LI>/, "")
|
37
|
+
results[:errorMessage].gsub!(/(\.)?<br>/, ". ")
|
38
|
+
results[:errorMessage].strip!
|
39
|
+
end
|
40
|
+
|
41
|
+
results
|
42
|
+
end
|
43
|
+
|
32
44
|
def add_transaction_type(post, action)
|
33
45
|
post[:trnType] = EXTRA_TRANSACTIONS[action] || super
|
34
46
|
end
|
@@ -4,21 +4,86 @@ module Beanstreamy
|
|
4
4
|
mattr_accessor :config
|
5
5
|
@@config = Beanstreamy.config
|
6
6
|
|
7
|
-
|
7
|
+
# Generate a form that will submit payment information to Beanstream's payment gateway
|
8
|
+
# using the http POST method.
|
9
|
+
#
|
10
|
+
# === Hash Validation
|
11
|
+
#
|
12
|
+
# It's highly recommended you enable hash validation. Otherwise end-users will be able
|
13
|
+
# to modify any information submitted to Beanstream, including the amount to be charged.
|
14
|
+
# You can specify the hash key with the +:hash_key+ option.
|
15
|
+
#
|
16
|
+
# (*Note*: Currently only SHA1 hashing is supported.)
|
17
|
+
#
|
18
|
+
# The +amount+ argument is expected to be an +Integer+ in cents, just like in ActiveMerchant.
|
19
|
+
#
|
20
|
+
# === Options
|
21
|
+
#
|
22
|
+
# [:merchant_id]
|
23
|
+
# The merchant id of your Beanstream account. This is required. You can specify this in
|
24
|
+
# the beanstreamy initializer file
|
25
|
+
# [:hash_key]
|
26
|
+
# The key used for SHA1 hash validation. You can specify this in the beanstreamy initializer file
|
27
|
+
# [:skip_hash]
|
28
|
+
# If +true+, turn off hash validation. Default is +false+.
|
29
|
+
# [:approved_url]
|
30
|
+
# The url that beanstream will redirect to for approved transactions
|
31
|
+
# [:declined_url]
|
32
|
+
# The url that beanstream will redirect to for declined transactions
|
33
|
+
# [:error_url]
|
34
|
+
# The url that beanstream will redirect to when there's validation errors with any of the submitted fields
|
35
|
+
# [:options]
|
36
|
+
# A hash of extra gateway parameters such as billing address and subtotals. Uses the same
|
37
|
+
# format as gateway options in ActiveMerchant. You'll most likely want to specify the +:order_id+ option
|
38
|
+
# at a minimum.
|
39
|
+
#
|
40
|
+
# === Example
|
41
|
+
#
|
42
|
+
# <%= beanstream_hosted_payment_form 3456, :merchant_id => 454353534, :hash_key => "FK49Clk34Jd",
|
43
|
+
# :options => {
|
44
|
+
# :order_id => "R5564396848",
|
45
|
+
# :email => "customer@example.com",
|
46
|
+
# :billing_address => {
|
47
|
+
# :name => "Reginald DeBillings",
|
48
|
+
# :address1 => "15 Over There Rd",
|
49
|
+
# :city => "Somecity",
|
50
|
+
# :province => "AB",
|
51
|
+
# :country => "CA",
|
52
|
+
# :postal_code => "T6G1K7"
|
53
|
+
# }
|
54
|
+
# } %>
|
55
|
+
# # Render fields needed for CC info
|
56
|
+
# <% end -%>
|
57
|
+
#
|
58
|
+
# In this example, it is assumed the billing information has been captured in a previous step. If you wanted to
|
59
|
+
# capture both billing information along with the CC info in one step, you would exclude it from the +:options+
|
60
|
+
# and render the appropriate fields.
|
61
|
+
#
|
62
|
+
# === TODO
|
63
|
+
#
|
64
|
+
# For rendered inputs, you need to specify the exact parameter names that Beanstream
|
65
|
+
# expects (e.g. +trnCardNumber+). There should be some extra helper methods that abstracts these to be
|
66
|
+
# similar to the +options+ hash.
|
67
|
+
def beanstream_hosted_payment_form(amount, options = {}, &block)
|
68
|
+
amount = Util.amount(amount) # convert from cents to dollars
|
8
69
|
|
9
|
-
order_id = options.delete(:order_id) or raise("Missing order id")
|
10
|
-
amount = options.delete(:amount) or raise("Missing amount")
|
11
70
|
merchant_id = options.delete(:merchant_id) || config.merchant_id
|
12
71
|
hash_key = options.delete(:hash_key) || config.hash_key
|
72
|
+
skip_hash = options.delete(:skip_hash)
|
73
|
+
|
13
74
|
approved_url = options.delete(:approved_url) || config.approved_url
|
14
75
|
declined_url = options.delete(:declined_url) || config.declined_url
|
15
76
|
error_url = options.delete(:error_url)
|
16
77
|
|
17
|
-
|
78
|
+
gateway_options = options.delete(:options) || {}
|
79
|
+
gateway_params = {}
|
80
|
+
Util.add_address(gateway_params, gateway_options)
|
81
|
+
Util.add_invoice(gateway_params, gateway_options)
|
82
|
+
|
18
83
|
extra_params = options.delete(:params)
|
19
84
|
|
85
|
+
# construct the parameter list
|
20
86
|
hashed_params = [["merchant_id", merchant_id],
|
21
|
-
["trnOrderNumber", order_id],
|
22
87
|
["trnAmount", amount]]
|
23
88
|
hashed_params << ["approvedPage", approved_url] if approved_url.present?
|
24
89
|
hashed_params << ["declinedPage", declined_url] if declined_url.present?
|
@@ -28,18 +93,19 @@ module Beanstreamy
|
|
28
93
|
hashed_params << ["hashExpiry", Util.hash_expiry(expire_at)]
|
29
94
|
end
|
30
95
|
|
96
|
+
hashed_params += Array(gateway_params)
|
31
97
|
hashed_params += Array(extra_params)
|
32
98
|
|
33
99
|
form = content_tag(:form, options.merge(:action => config.payment_url, :method => "post")) do
|
34
100
|
hashed_params.each do |key, value|
|
35
|
-
concat hidden_field_tag(key, value)
|
101
|
+
concat hidden_field_tag(key, value) if value
|
36
102
|
end
|
37
103
|
|
38
104
|
hash_value = nil
|
39
105
|
if hash_key.present? && !skip_hash
|
40
106
|
# Beansream's hosted page uses hash validation to prevent price modification. This hash is computed from
|
41
107
|
# the url encoded string of the above inputs
|
42
|
-
query_string = hashed_params.reject { |k,v| v
|
108
|
+
query_string = hashed_params.reject { |k,v| !v }.map { |k,v| v.to_query(k) }.join('&')
|
43
109
|
hash_value = Util.hash_value(hash_key, query_string)
|
44
110
|
|
45
111
|
concat hidden_field_tag("hashValue", hash_value)
|
data/lib/beanstreamy/util.rb
CHANGED
@@ -1,13 +1,67 @@
|
|
1
1
|
module Beanstreamy
|
2
2
|
module Util
|
3
|
+
|
3
4
|
def self.hash_value(key, message)
|
4
5
|
Digest::SHA1.hexdigest(message + key)
|
5
6
|
end
|
6
7
|
|
8
|
+
def self.amount(cents)
|
9
|
+
sprintf("%.2f", cents.to_f / 100)
|
10
|
+
end
|
11
|
+
|
7
12
|
def self.hash_expiry(expire_at)
|
8
13
|
# Beanstream uses PST/PDT for all their timestamps. Time stamps only have minute resolution,
|
9
14
|
# so the seconds need chopping off.
|
10
15
|
expire_at.in_time_zone("Pacific Time (US & Canada)").to_s(:number)[0..-3]
|
11
16
|
end
|
17
|
+
|
18
|
+
def self.add_address(params, options)
|
19
|
+
prepare_address_for_non_american_countries(options)
|
20
|
+
|
21
|
+
if billing_address = options[:billing_address] || options[:address]
|
22
|
+
params[:ordName] = billing_address[:name]
|
23
|
+
params[:ordEmailAddress] = options[:email]
|
24
|
+
params[:ordPhoneNumber] = billing_address[:phone]
|
25
|
+
params[:ordAddress1] = billing_address[:address1]
|
26
|
+
params[:ordAddress2] = billing_address[:address2]
|
27
|
+
params[:ordCity] = billing_address[:city]
|
28
|
+
params[:ordProvince] = billing_address[:province] || billing_address[:state]
|
29
|
+
params[:ordPostalCode] = billing_address[:postal_code] || billing_address[:zip]
|
30
|
+
params[:ordCountry] = billing_address[:country]
|
31
|
+
end
|
32
|
+
|
33
|
+
if shipping_address = options[:shipping_address]
|
34
|
+
params[:shipName] = shipping_address[:name]
|
35
|
+
params[:shipEmailAddress] = options[:email]
|
36
|
+
params[:shipPhoneNumber] = shipping_address[:phone]
|
37
|
+
params[:shipAddress1] = shipping_address[:address1]
|
38
|
+
params[:shipAddress2] = shipping_address[:address2]
|
39
|
+
params[:shipCity] = shipping_address[:city]
|
40
|
+
params[:shipProvince] = shipping_address[:province] || shipping_address[:state]
|
41
|
+
params[:shipPostalCode] = shipping_address[:postal_code] || shipping_address[:zip]
|
42
|
+
params[:shipCountry] = shipping_address[:country]
|
43
|
+
params[:shippingMethod] = shipping_address[:shipping_method]
|
44
|
+
params[:deliveryEstimate] = shipping_address[:delivery_estimate]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.prepare_address_for_non_american_countries(options)
|
49
|
+
[ options[:billing_address], options[:shipping_address] ].compact.each do |address|
|
50
|
+
unless ['US', 'CA'].include?(address[:country])
|
51
|
+
address[:province] = '--'
|
52
|
+
address[:postal_code] = '000000' unless address[:postal_code] || address[:zip]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.add_invoice(params, options)
|
58
|
+
params[:trnOrderNumber] = options[:order_id]
|
59
|
+
params[:trnComments] = options[:description]
|
60
|
+
params[:ordItemPrice] = amount(options[:subtotal])
|
61
|
+
params[:ordShippingPrice] = amount(options[:shipping])
|
62
|
+
params[:ordTax1Price] = amount(options[:tax1] || options[:tax])
|
63
|
+
params[:ordTax2Price] = amount(options[:tax2])
|
64
|
+
params[:ref1] = options[:custom]
|
65
|
+
end
|
12
66
|
end
|
13
67
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 2
|
9
|
+
version: 0.2.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jeff Siegel
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-07-
|
17
|
+
date: 2010-07-12 00:00:00 -06:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|