better_offsite_payments 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +76 -0
  4. data/lib/offsite_payments.rb +39 -0
  5. data/lib/offsite_payments/action_view_helper.rb +72 -0
  6. data/lib/offsite_payments/helper.rb +120 -0
  7. data/lib/offsite_payments/integrations.rb +14 -0
  8. data/lib/offsite_payments/integrations/a1agregator.rb +245 -0
  9. data/lib/offsite_payments/integrations/authorize_net_sim.rb +580 -0
  10. data/lib/offsite_payments/integrations/bit_pay.rb +150 -0
  11. data/lib/offsite_payments/integrations/bogus.rb +32 -0
  12. data/lib/offsite_payments/integrations/chronopay.rb +283 -0
  13. data/lib/offsite_payments/integrations/citrus.rb +227 -0
  14. data/lib/offsite_payments/integrations/coinbase.rb +172 -0
  15. data/lib/offsite_payments/integrations/direc_pay.rb +332 -0
  16. data/lib/offsite_payments/integrations/directebanking.rb +237 -0
  17. data/lib/offsite_payments/integrations/doku.rb +171 -0
  18. data/lib/offsite_payments/integrations/dotpay.rb +166 -0
  19. data/lib/offsite_payments/integrations/dwolla.rb +160 -0
  20. data/lib/offsite_payments/integrations/e_payment_plans.rb +146 -0
  21. data/lib/offsite_payments/integrations/easy_pay.rb +137 -0
  22. data/lib/offsite_payments/integrations/epay.rb +161 -0
  23. data/lib/offsite_payments/integrations/first_data.rb +133 -0
  24. data/lib/offsite_payments/integrations/gestpay.rb +205 -0
  25. data/lib/offsite_payments/integrations/hi_trust.rb +179 -0
  26. data/lib/offsite_payments/integrations/ipay88.rb +251 -0
  27. data/lib/offsite_payments/integrations/klarna.rb +275 -0
  28. data/lib/offsite_payments/integrations/liqpay.rb +216 -0
  29. data/lib/offsite_payments/integrations/maksuturva.rb +231 -0
  30. data/lib/offsite_payments/integrations/megakassa.rb +184 -0
  31. data/lib/offsite_payments/integrations/mollie.rb +32 -0
  32. data/lib/offsite_payments/integrations/mollie_ideal.rb +194 -0
  33. data/lib/offsite_payments/integrations/mollie_mistercash.rb +143 -0
  34. data/lib/offsite_payments/integrations/molpay.rb +193 -0
  35. data/lib/offsite_payments/integrations/moneybookers.rb +199 -0
  36. data/lib/offsite_payments/integrations/nochex.rb +228 -0
  37. data/lib/offsite_payments/integrations/pag_seguro.rb +268 -0
  38. data/lib/offsite_payments/integrations/paxum.rb +114 -0
  39. data/lib/offsite_payments/integrations/pay_fast.rb +269 -0
  40. data/lib/offsite_payments/integrations/paydollar.rb +142 -0
  41. data/lib/offsite_payments/integrations/payflow_link.rb +194 -0
  42. data/lib/offsite_payments/integrations/paypal.rb +362 -0
  43. data/lib/offsite_payments/integrations/paypal_payments_advanced.rb +23 -0
  44. data/lib/offsite_payments/integrations/paysbuy.rb +71 -0
  45. data/lib/offsite_payments/integrations/payu_in.rb +276 -0
  46. data/lib/offsite_payments/integrations/payu_in_paisa.rb +46 -0
  47. data/lib/offsite_payments/integrations/platron.rb +153 -0
  48. data/lib/offsite_payments/integrations/pxpay.rb +273 -0
  49. data/lib/offsite_payments/integrations/quickpay.rb +232 -0
  50. data/lib/offsite_payments/integrations/rbkmoney.rb +110 -0
  51. data/lib/offsite_payments/integrations/realex_offsite.rb +317 -0
  52. data/lib/offsite_payments/integrations/robokassa.rb +154 -0
  53. data/lib/offsite_payments/integrations/sage_pay_form.rb +431 -0
  54. data/lib/offsite_payments/integrations/two_checkout.rb +329 -0
  55. data/lib/offsite_payments/integrations/universal.rb +190 -0
  56. data/lib/offsite_payments/integrations/valitor.rb +200 -0
  57. data/lib/offsite_payments/integrations/verkkomaksut.rb +143 -0
  58. data/lib/offsite_payments/integrations/web_pay.rb +186 -0
  59. data/lib/offsite_payments/integrations/webmoney.rb +119 -0
  60. data/lib/offsite_payments/integrations/wirecard_checkout_page.rb +359 -0
  61. data/lib/offsite_payments/integrations/world_pay.rb +280 -0
  62. data/lib/offsite_payments/integrations/yandex_money.rb +175 -0
  63. data/lib/offsite_payments/notification.rb +71 -0
  64. data/lib/offsite_payments/return.rb +37 -0
  65. data/lib/offsite_payments/version.rb +3 -0
  66. metadata +297 -0
@@ -0,0 +1,190 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module Universal
4
+ def self.notification(post, options = {})
5
+ Notification.new(post, options)
6
+ end
7
+
8
+ def self.return(query_string, options = {})
9
+ Return.new(query_string, options)
10
+ end
11
+
12
+ def self.sign(fields, key)
13
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, key, fields.sort.join)
14
+ end
15
+
16
+ class Helper < OffsitePayments::Helper
17
+ CURRENCY_SPECIAL_MINOR_UNITS = {
18
+ 'BIF' => 0,
19
+ 'BYR' => 0,
20
+ 'CLF' => 0,
21
+ 'CLP' => 0,
22
+ 'CVE' => 0,
23
+ 'DJF' => 0,
24
+ 'GNF' => 0,
25
+ 'HUF' => 0,
26
+ 'ISK' => 0,
27
+ 'JPY' => 0,
28
+ 'KMF' => 0,
29
+ 'KRW' => 0,
30
+ 'PYG' => 0,
31
+ 'RWF' => 0,
32
+ 'UGX' => 0,
33
+ 'UYI' => 0,
34
+ 'VND' => 0,
35
+ 'VUV' => 0,
36
+ 'XAF' => 0,
37
+ 'XOF' => 0,
38
+ 'XPF' => 0,
39
+ 'BHD' => 3,
40
+ 'IQD' => 3,
41
+ 'JOD' => 3,
42
+ 'KWD' => 3,
43
+ 'LYD' => 3,
44
+ 'OMR' => 3,
45
+ 'TND' => 3,
46
+ 'COU' => 4
47
+ }
48
+
49
+ def initialize(order, account, options = {})
50
+ @forward_url = options[:forward_url]
51
+ @key = options[:credential2]
52
+ @currency = options[:currency]
53
+
54
+ # x_credential3 should not be included in the request when using the universal offsite dev kit.
55
+ options[:credential3] = nil if options[:credential3] == @forward_url
56
+
57
+ super
58
+ self.country = options[:country]
59
+ self.account_name = options[:account_name]
60
+ self.transaction_type = options[:transaction_type]
61
+ add_field 'x_test', @test.to_s
62
+ end
63
+
64
+ def credential_based_url
65
+ @forward_url
66
+ end
67
+
68
+ def form_fields
69
+ sign_fields
70
+ end
71
+
72
+ def amount=(amount)
73
+ add_field 'x_amount', format_amount(amount, @currency)
74
+ end
75
+
76
+ def sign_fields
77
+ @fields.merge!('x_signature' => generate_signature)
78
+ end
79
+
80
+ def generate_signature
81
+ Universal.sign(@fields, @key)
82
+ end
83
+
84
+ mapping :account, 'x_account_id'
85
+ mapping :currency, 'x_currency'
86
+ mapping :order, 'x_reference'
87
+ mapping :country, 'x_shop_country'
88
+ mapping :account_name, 'x_shop_name'
89
+ mapping :transaction_type, 'x_transaction_type'
90
+ mapping :description, 'x_description'
91
+ mapping :invoice, 'x_invoice'
92
+ mapping :credential3, 'x_credential3'
93
+ mapping :credential4, 'x_credential4'
94
+
95
+ mapping :customer, :first_name => 'x_customer_first_name',
96
+ :last_name => 'x_customer_last_name',
97
+ :email => 'x_customer_email',
98
+ :phone => 'x_customer_phone'
99
+
100
+ mapping :billing_address, :first_name => 'x_customer_billing_first_name',
101
+ :last_name => 'x_customer_billing_last_name',
102
+ :city => 'x_customer_billing_city',
103
+ :company => 'x_customer_billing_company',
104
+ :address1 => 'x_customer_billing_address1',
105
+ :address2 => 'x_customer_billing_address2',
106
+ :state => 'x_customer_billing_state',
107
+ :zip => 'x_customer_billing_zip',
108
+ :country => 'x_customer_billing_country',
109
+ :phone => 'x_customer_billing_phone'
110
+
111
+ mapping :shipping_address, :first_name => 'x_customer_shipping_first_name',
112
+ :last_name => 'x_customer_shipping_last_name',
113
+ :city => 'x_customer_shipping_city',
114
+ :company => 'x_customer_shipping_company',
115
+ :address1 => 'x_customer_shipping_address1',
116
+ :address2 => 'x_customer_shipping_address2',
117
+ :state => 'x_customer_shipping_state',
118
+ :zip => 'x_customer_shipping_zip',
119
+ :country => 'x_customer_shipping_country',
120
+ :phone => 'x_customer_shipping_phone'
121
+
122
+ mapping :notify_url, 'x_url_callback'
123
+ mapping :return_url, 'x_url_complete'
124
+ mapping :cancel_return_url, 'x_url_cancel'
125
+
126
+ private
127
+
128
+ def format_amount(amount, currency)
129
+ units = CURRENCY_SPECIAL_MINOR_UNITS[currency] || 2
130
+ sprintf("%.#{units}f", amount)
131
+ end
132
+ end
133
+
134
+ class Notification < OffsitePayments::Notification
135
+ def initialize(post, options = {})
136
+ super
137
+ @key = options[:credential2]
138
+ end
139
+
140
+ def acknowledge(authcode = nil)
141
+ signature = @params['x_signature']
142
+ signature && signature.casecmp(generate_signature) == 0
143
+ end
144
+
145
+ def item_id
146
+ @params['x_reference']
147
+ end
148
+
149
+ def currency
150
+ @params['x_currency']
151
+ end
152
+
153
+ def gross
154
+ @params['x_amount']
155
+ end
156
+
157
+ def transaction_id
158
+ @params['x_gateway_reference']
159
+ end
160
+
161
+ def status
162
+ result = @params['x_result']
163
+ result && result.capitalize
164
+ end
165
+
166
+ def test?
167
+ @params['x_test'] == 'true'
168
+ end
169
+
170
+ private
171
+
172
+ def generate_signature
173
+ signature_params = @params.select { |k| k.start_with? 'x_' }.reject { |k| k == 'x_signature' }
174
+ Universal.sign(signature_params, @key)
175
+ end
176
+ end
177
+
178
+ class Return < OffsitePayments::Return
179
+ def initialize(query_string, options = {})
180
+ super
181
+ @notification = Notification.new(query_string, options)
182
+ end
183
+
184
+ def success?
185
+ @notification.acknowledge
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,200 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module Valitor
4
+ mattr_accessor :test_url
5
+ self.test_url = 'https://testvefverslun.valitor.is/1_1/'
6
+
7
+ mattr_accessor :production_url
8
+ self.production_url = 'https://vefverslun.valitor.is/1_1/'
9
+
10
+ def self.test?
11
+ (OffsitePayments.mode == :test)
12
+ end
13
+
14
+ def self.service_url
15
+ (test? ? test_url : production_url)
16
+ end
17
+
18
+ def self.notification(params, options={})
19
+ Notification.new(params, options.merge(:test => test?))
20
+ end
21
+
22
+ def self.return(query_string, options={})
23
+ Return.new(query_string, options.merge(:test => test?))
24
+ end
25
+
26
+ class Helper < OffsitePayments::Helper
27
+ include ActiveUtils::RequiresParameters
28
+
29
+ DEFAULT_SUCCESS_TEXT = "The transaction has been completed."
30
+
31
+ def initialize(order, account, options={})
32
+ options[:currency] ||= 'ISK'
33
+ super
34
+ add_field 'Adeinsheimild', '0'
35
+ add_field 'KaupandaUpplysingar', '0'
36
+ add_field 'SlokkvaHaus', '0'
37
+ @security_number = options[:credential2]
38
+ @amount = options[:amount]
39
+ @order = order
40
+ end
41
+
42
+ mapping :account, 'VefverslunID'
43
+ mapping :currency, 'Gjaldmidill'
44
+
45
+ mapping :order, 'Tilvisunarnumer'
46
+
47
+ mapping :notify_url, 'SlodTokstAdGjaldfaeraServerSide'
48
+ mapping :return_url, 'SlodTokstAdGjaldfaera'
49
+ mapping :cancel_return_url, 'SlodNotandiHaettirVid'
50
+
51
+ mapping :success_text, 'SlodTokstAdGjaldfaeraTexti'
52
+
53
+ mapping :language, 'Lang'
54
+
55
+ def authorize_only
56
+ add_field 'Adeinsheimild', '1'
57
+ end
58
+
59
+ def collect_customer_info
60
+ add_field 'KaupandaUpplysingar', '1'
61
+ end
62
+
63
+ def hide_header
64
+ add_field 'SlokkvaHaus', '1'
65
+ end
66
+
67
+ def product(id, options={})
68
+ raise ArgumentError, "Product id #{id} is not an integer between 1 and 500" unless id.to_i > 0 && id.to_i <= 500
69
+ requires!(options, :amount, :description)
70
+ options.assert_valid_keys([:description, :quantity, :amount, :discount])
71
+
72
+ add_field("Vara_#{id}_Verd", format_amount(options[:amount], @fields[mappings[:currency]]))
73
+ add_field("Vara_#{id}_Fjoldi", options[:quantity] || "1")
74
+
75
+ add_field("Vara_#{id}_Lysing", options[:description]) if options[:description]
76
+ add_field("Vara_#{id}_Afslattur", options[:discount] || '0')
77
+
78
+ @products ||= []
79
+ @products << id.to_i
80
+ end
81
+
82
+ def signature
83
+ raise ArgumentError, "Security number not set" unless @security_number
84
+ parts = [@security_number, @fields['Adeinsheimild']]
85
+ @products.sort.uniq.each do |id|
86
+ parts.concat(["Vara_#{id}_Fjoldi", "Vara_#{id}_Verd", "Vara_#{id}_Afslattur"].collect{|e| @fields[e]})
87
+ end if @products
88
+ parts.concat(%w(VefverslunID Tilvisunarnumer SlodTokstAdGjaldfaera SlodTokstAdGjaldfaeraServerSide Gjaldmidill).collect{|e| @fields[e]})
89
+ Digest::MD5.hexdigest(parts.compact.join(''))
90
+ end
91
+
92
+ def form_fields
93
+ product(1, :amount => @amount, :description => @order) if Array(@products).empty?
94
+ @fields[mappings[:success_text]] ||= DEFAULT_SUCCESS_TEXT
95
+ @fields.merge('RafraenUndirskrift' => signature)
96
+ end
97
+
98
+ def format_amount(amount, currency)
99
+ OffsitePayments::CURRENCIES_WITHOUT_FRACTIONS.include?(currency) ? amount.to_f.round : sprintf("%.2f", amount)
100
+ end
101
+ end
102
+
103
+ module ResponseFields
104
+ def success?
105
+ status == 'Completed'
106
+ end
107
+ alias :complete? :success?
108
+
109
+ def test?
110
+ @options[:test]
111
+ end
112
+
113
+ def item_id
114
+ params['Tilvisunarnumer']
115
+ end
116
+ alias :order :item_id
117
+
118
+ def transaction_id
119
+ params['VefverslunSalaID']
120
+ end
121
+
122
+ def currency
123
+ nil
124
+ end
125
+
126
+ def status
127
+ "Completed" if acknowledge
128
+ end
129
+
130
+ def received_at
131
+ Time.parse(params['Dagsetning'].to_s)
132
+ end
133
+
134
+ def gross
135
+ "%0.2f" % params['Upphaed'].to_s.sub(',', '.')
136
+ end
137
+
138
+ def card_type
139
+ params['Kortategund']
140
+ end
141
+
142
+ def card_last_four
143
+ params['KortnumerSidustu']
144
+ end
145
+
146
+ def authorization_number
147
+ params['Heimildarnumer']
148
+ end
149
+
150
+ def transaction_number
151
+ params['Faerslunumer']
152
+ end
153
+
154
+ def customer_name
155
+ params['Nafn']
156
+ end
157
+
158
+ def customer_address
159
+ params['Heimilisfang']
160
+ end
161
+
162
+ def customer_zip
163
+ params['Postnumer']
164
+ end
165
+
166
+ def customer_city
167
+ params['Stadur']
168
+ end
169
+
170
+ def customer_country
171
+ params['Land']
172
+ end
173
+
174
+ def customer_email
175
+ params['Tolvupostfang']
176
+ end
177
+
178
+ def customer_comment
179
+ params['Athugasemdir']
180
+ end
181
+
182
+ def password
183
+ @options[:credential2]
184
+ end
185
+
186
+ def acknowledge(authcode = nil)
187
+ password ? Digest::MD5.hexdigest("#{password}#{order}") == params['RafraenUndirskriftSvar'] : true
188
+ end
189
+ end
190
+
191
+ class Notification < OffsitePayments::Notification
192
+ include ResponseFields
193
+ end
194
+
195
+ class Return < OffsitePayments::Return
196
+ include ResponseFields
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,143 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ # Usage, see the blog post here: http://blog.kiskolabs.com/post/22374612968/understanding-active-merchant-integrations and E1 API documentation here: http://docs.verkkomaksut.fi/
4
+ module Verkkomaksut
5
+ mattr_accessor :service_url
6
+ self.service_url = 'https://payment.verkkomaksut.fi/'
7
+
8
+ def self.notification(post)
9
+ Notification.new(post)
10
+ end
11
+
12
+ class Helper < OffsitePayments::Helper
13
+ # Fetches the md5secret and adds MERCHANT_ID and API TYPE to the form
14
+ def initialize(order, account, options = {})
15
+ md5secret options.delete(:credential2)
16
+ super
17
+ add_field("MERCHANT_ID", account)
18
+ add_field("TYPE", "E1")
19
+ end
20
+
21
+ def md5secret(value)
22
+ @md5secret = value
23
+ end
24
+
25
+ # Adds the AUTHCODE to the form
26
+ def form_fields
27
+ @fields.merge("AUTHCODE" => generate_md5string)
28
+ end
29
+
30
+ # Calculates the AUTHCODE
31
+ def generate_md5string
32
+ fields = [@md5secret, @fields["MERCHANT_ID"], @fields["ORDER_NUMBER"], @fields["REFERENCE_NUMBER"], @fields["ORDER_DESCRIPTION"], @fields["CURRENCY"], @fields["RETURN_ADDRESS"], @fields["CANCEL_ADDRESS"], @fields["PENDING_ADDRESS"],
33
+ @fields["NOTIFY_ADDRESS"], @fields["TYPE"], @fields["CULTURE"], @fields["PRESELECTED_METHOD"], @fields["MODE"], @fields["VISIBLE_METHODS"], @fields["GROUP"], @fields["CONTACT_TELNO"], @fields["CONTACT_CELLNO"],
34
+ @fields["CONTACT_EMAIL"], @fields["CONTACT_FIRSTNAME"], @fields["CONTACT_LASTNAME"], @fields["CONTACT_COMPANY"], @fields["CONTACT_ADDR_STREET"], @fields["CONTACT_ADDR_ZIP"], @fields["CONTACT_ADDR_CITY"], @fields["CONTACT_ADDR_COUNTRY"], @fields["INCLUDE_VAT"],
35
+ @fields["ITEMS"]]
36
+
37
+ (0..@fields["ITEMS"].to_i-1).each do |i|
38
+ fields += [@fields["ITEM_TITLE[#{i}]"], @fields["ITEM_NO[#{i}]"], @fields["ITEM_AMOUNT[#{i}]"], @fields["ITEM_PRICE[#{i}]"], @fields["ITEM_TAX[#{i}]"], @fields["ITEM_DISCOUNT[#{i}]"], @fields["ITEM_TYPE[#{i}]"]]
39
+ end
40
+
41
+ fields = fields.join("|")
42
+
43
+ return Digest::MD5.hexdigest(fields).upcase
44
+ end
45
+
46
+ # Mappings
47
+ mapping :merchant_id, "MERCHANT_ID"
48
+ mapping :order, "ORDER_NUMBER"
49
+ mapping :reference_number, "REFERENCE_NUMBER"
50
+ mapping :customer, :first_name => "CONTACT_FIRSTNAME",
51
+ :last_name => "CONTACT_LASTNAME",
52
+ :email => "CONTACT_EMAIL",
53
+ :phone => "CONTACT_CELLNO",
54
+ :tellno => "CONTACT_TELLNO",
55
+ :company => "CONTACT_COMPANY"
56
+
57
+
58
+ mapping :billing_address, :city => "CONTACT_ADDR_CITY",
59
+ :address1 => "CONTACT_ADDR_STREET",
60
+ :address2 => "",
61
+ :state => "",
62
+ :zip => "CONTACT_ADDR_ZIP",
63
+ :country => "CONTACT_ADDR_COUNTRY"
64
+
65
+ mapping :notify_url, "NOTIFY_ADDRESS"
66
+ mapping :currency, "CURRENCY"
67
+ mapping :return_url, "RETURN_ADDRESS"
68
+ mapping :cancel_return_url, "CANCEL_ADDRESS"
69
+ mapping :description, "ORDER_DESCRIPTION"
70
+ mapping :tax, ""
71
+ mapping :shipping, ""
72
+ mapping :include_vat, "INCLUDE_VAT"
73
+ mapping :pending_address, "PENDING_ADDRESS"
74
+ mapping :culture, "CULTURE"
75
+ mapping :items, "ITEMS"
76
+ mapping :preselected_method, "PRESELECTED_METHOD"
77
+ mapping :mode, "MODE"
78
+ mapping :visible_methods, "VISIBLE_METHODS"
79
+ mapping :group, "GROUP"
80
+
81
+ (0..499.to_i).each do |i|
82
+ mapping "item_title_#{i}".to_sym, "ITEM_TITLE[#{i}]"
83
+ mapping "item_no_#{i}".to_sym, "ITEM_NO[#{i}]"
84
+ mapping "item_amount_#{i}".to_sym, "ITEM_AMOUNT[#{i}]"
85
+ mapping "item_price_#{i}".to_sym, "ITEM_PRICE[#{i}]"
86
+ mapping "item_tax_#{i}".to_sym, "ITEM_TAX[#{i}]"
87
+ mapping "item_discount_#{i}".to_sym, "ITEM_DISCOUNT[#{i}]"
88
+ mapping "item_type_#{i}".to_sym, "ITEM_TYPE[#{i}]"
89
+ end
90
+ end
91
+
92
+ class Notification < OffsitePayments::Notification
93
+ # Is the payment complete or not. Verkkomaksut only has two statuses: random string or 0000000000 which means pending
94
+ def complete?
95
+ params['PAID'] != "0000000000"
96
+ end
97
+
98
+ # Order id
99
+ def order_id
100
+ params['ORDER_NUMBER']
101
+ end
102
+
103
+ # Payment method used
104
+ def method
105
+ params['METHOD']
106
+ end
107
+
108
+ # When was this payment received by the client.
109
+ def received_at
110
+ params['TIMESTAMP']
111
+ end
112
+
113
+ # Security key got from Verkkomaksut
114
+ def security_key
115
+ params['RETURN_AUTHCODE']
116
+ end
117
+
118
+ # Another way of asking the payment status
119
+ def status
120
+ if complete?
121
+ "PAID"
122
+ else
123
+ "PENDING"
124
+ end
125
+ end
126
+
127
+ # Acknowledges the payment. If the authcodes match, returns true.
128
+ def acknowledge(authcode = nil)
129
+ return_authcode = [params["ORDER_NUMBER"], params["TIMESTAMP"], params["PAID"], params["METHOD"], authcode].join("|")
130
+ Digest::MD5.hexdigest(return_authcode).upcase == params["RETURN_AUTHCODE"]
131
+ end
132
+
133
+ private
134
+
135
+ def parse(post)
136
+ post.each do |key, value|
137
+ params[key] = value
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end