offsite_payments 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +70 -0
  4. data/lib/offsite_payments.rb +46 -0
  5. data/lib/offsite_payments/action_view_helper.rb +72 -0
  6. data/lib/offsite_payments/helper.rb +119 -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/direc_pay.rb +339 -0
  15. data/lib/offsite_payments/integrations/directebanking.rb +237 -0
  16. data/lib/offsite_payments/integrations/doku.rb +171 -0
  17. data/lib/offsite_payments/integrations/dotpay.rb +166 -0
  18. data/lib/offsite_payments/integrations/dwolla.rb +160 -0
  19. data/lib/offsite_payments/integrations/e_payment_plans.rb +146 -0
  20. data/lib/offsite_payments/integrations/easy_pay.rb +137 -0
  21. data/lib/offsite_payments/integrations/epay.rb +161 -0
  22. data/lib/offsite_payments/integrations/first_data.rb +133 -0
  23. data/lib/offsite_payments/integrations/gestpay.rb +201 -0
  24. data/lib/offsite_payments/integrations/hi_trust.rb +179 -0
  25. data/lib/offsite_payments/integrations/ipay88.rb +240 -0
  26. data/lib/offsite_payments/integrations/klarna.rb +291 -0
  27. data/lib/offsite_payments/integrations/liqpay.rb +216 -0
  28. data/lib/offsite_payments/integrations/maksuturva.rb +231 -0
  29. data/lib/offsite_payments/integrations/mollie_ideal.rb +213 -0
  30. data/lib/offsite_payments/integrations/moneybookers.rb +199 -0
  31. data/lib/offsite_payments/integrations/nochex.rb +228 -0
  32. data/lib/offsite_payments/integrations/pag_seguro.rb +255 -0
  33. data/lib/offsite_payments/integrations/paxum.rb +114 -0
  34. data/lib/offsite_payments/integrations/pay_fast.rb +269 -0
  35. data/lib/offsite_payments/integrations/paydollar.rb +142 -0
  36. data/lib/offsite_payments/integrations/payflow_link.rb +194 -0
  37. data/lib/offsite_payments/integrations/paypal.rb +362 -0
  38. data/lib/offsite_payments/integrations/paypal_payments_advanced.rb +23 -0
  39. data/lib/offsite_payments/integrations/paysbuy.rb +71 -0
  40. data/lib/offsite_payments/integrations/payu_in.rb +266 -0
  41. data/lib/offsite_payments/integrations/payu_in_paisa.rb +46 -0
  42. data/lib/offsite_payments/integrations/platron.rb +153 -0
  43. data/lib/offsite_payments/integrations/pxpay.rb +271 -0
  44. data/lib/offsite_payments/integrations/quickpay.rb +232 -0
  45. data/lib/offsite_payments/integrations/rbkmoney.rb +110 -0
  46. data/lib/offsite_payments/integrations/robokassa.rb +154 -0
  47. data/lib/offsite_payments/integrations/sage_pay_form.rb +425 -0
  48. data/lib/offsite_payments/integrations/two_checkout.rb +332 -0
  49. data/lib/offsite_payments/integrations/universal.rb +180 -0
  50. data/lib/offsite_payments/integrations/valitor.rb +200 -0
  51. data/lib/offsite_payments/integrations/verkkomaksut.rb +143 -0
  52. data/lib/offsite_payments/integrations/web_pay.rb +186 -0
  53. data/lib/offsite_payments/integrations/webmoney.rb +119 -0
  54. data/lib/offsite_payments/integrations/wirecard_checkout_page.rb +359 -0
  55. data/lib/offsite_payments/integrations/world_pay.rb +273 -0
  56. data/lib/offsite_payments/notification.rb +71 -0
  57. data/lib/offsite_payments/return.rb +37 -0
  58. data/lib/offsite_payments/version.rb +3 -0
  59. metadata +270 -0
@@ -0,0 +1,199 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module Moneybookers
4
+ mattr_accessor :production_url
5
+ self.production_url = 'https://www.moneybookers.com/app/payment.pl'
6
+
7
+ def self.service_url
8
+ self.production_url
9
+ end
10
+
11
+ def self.notification(post, options)
12
+ Notification.new(post, options)
13
+ end
14
+
15
+ def self.return(post, options = {})
16
+ Return.new(post, options)
17
+ end
18
+
19
+ class Helper < OffsitePayments::Helper
20
+ mapping :account, 'pay_to_email'
21
+ mapping :order, 'transaction_id'
22
+ mapping :amount, 'amount'
23
+ mapping :currency, 'currency'
24
+
25
+ mapping :customer,
26
+ :first_name => 'firstname',
27
+ :last_name => 'lastname',
28
+ :email => 'pay_from_email',
29
+ :phone => 'phone_number'
30
+
31
+ mapping :billing_address,
32
+ :city => 'city',
33
+ :address1 => 'address',
34
+ :address2 => 'address2',
35
+ :state => 'state',
36
+ :zip => 'postal_code',
37
+ :country => 'country'
38
+
39
+ mapping :notify_url, 'status_url'
40
+ mapping :return_url, 'return_url'
41
+ mapping :cancel_return_url, 'cancel_url'
42
+ mapping :description, 'detail1_text'
43
+
44
+ MAPPED_COUNTRY_CODES = {
45
+ 'SE' => 'SV',
46
+ 'DK' => 'DA'
47
+ }
48
+
49
+ SUPPORTED_COUNTRY_CODES = [
50
+ 'FI', 'DE', 'ES', 'FR',
51
+ 'IT','PL', 'GR', 'RO',
52
+ 'RU', 'TR', 'CN', 'CZ', 'NL'
53
+ ]
54
+
55
+ def initialize(order, account, options = {})
56
+ super
57
+ add_tracking_token
58
+ add_default_parameters
59
+ add_seller_details(options)
60
+ end
61
+
62
+ private
63
+
64
+ def add_tracking_token
65
+ return if application_id.blank? || application_id == 'ActiveMerchant'
66
+
67
+ add_field('merchant_fields', 'platform')
68
+ add_field('platform', application_id)
69
+ end
70
+
71
+ def add_default_parameters
72
+ add_field('hide_login', 1)
73
+ end
74
+
75
+ def add_seller_details(options)
76
+ add_field('recipient_description', options[:account_name]) if options[:account_name]
77
+ add_field('country', lookup_country_code(options[:country], :alpha3)) if options[:country]
78
+ add_field('language', locale_code(options[:country])) if options[:country]
79
+ end
80
+
81
+ def locale_code(country_code)
82
+ return country_code if SUPPORTED_COUNTRY_CODES.include?(country_code)
83
+ MAPPED_COUNTRY_CODES[country_code] || 'EN'
84
+ end
85
+ end
86
+
87
+ class Notification < OffsitePayments::Notification
88
+ def complete?
89
+ status == 'Completed'
90
+ end
91
+
92
+ # ‘2’ Processed – This status is sent when the transaction is processed and the funds have been received on your Moneybookers account.
93
+ # ‘0’ Pending – This status is sent when the customers pays via the pending bank transfer option. Such transactions will auto-process IF the bank transfer is received by Moneybookers. We strongly recommend that you do NOT process the order/transaction in your system upon receipt of a pending status from Moneybookers.
94
+ # ‘-1’ Cancelled – Pending transactions can either be cancelled manually by the sender in their online account history or they will auto-cancel after 14 days if still pending.
95
+ # ‘-2’ Failed – This status is sent when the customer tries to pay via Credit Card or Direct Debit but our provider declines the transaction. If you do not accept Credit Card or Direct Debit payments via Moneybookers (see page 17) then you will never receive the failed status.
96
+ # ‘-3’ Chargeback – This status could be received only if your account is configured to receive chargebacks. If this is the case, whenever a chargeback is received by Moneybookers, a -3 status will be posted on the status_url for the reversed transaction.
97
+ def status
98
+ case status_code
99
+ when '2'
100
+ 'Completed'
101
+ when '0'
102
+ 'Pending'
103
+ when '-1'
104
+ 'Cancelled'
105
+ when '-2'
106
+ 'Failed'
107
+ when '-3'
108
+ 'Reversed'
109
+ else
110
+ 'Error'
111
+ end
112
+ end
113
+
114
+ def status_code
115
+ params['status']
116
+ end
117
+
118
+ def item_id
119
+ params['transaction_id']
120
+ end
121
+
122
+ def transaction_id
123
+ params['mb_transaction_id']
124
+ end
125
+
126
+ # When was this payment received by the client.
127
+ def received_at
128
+ nil
129
+ end
130
+
131
+ def payer_email
132
+ params['pay_from_email']
133
+ end
134
+
135
+ def receiver_email
136
+ params['pay_to_email']
137
+ end
138
+
139
+ def md5sig
140
+ params['md5sig']
141
+ end
142
+
143
+ #Unique ID from the merchant's Moneybookers.com account, needed for calculatinon of md5 sig
144
+ def merchant_id
145
+ params['merchant_id']
146
+ end
147
+
148
+ # currency of the payment as posted by the merchant on the entry form
149
+ def currency
150
+ params['currency']
151
+ end
152
+
153
+ # amount of the payment as posted by the merchant on the entry form (ex. 39.60/39.6/39)
154
+ def gross
155
+ params['amount']
156
+ end
157
+
158
+ # currency of mb_amount, will always be the same as the currency of the beneficiary's account at Moneybookers.com
159
+ def merchant_currency
160
+ params['mb_currency']
161
+ end
162
+
163
+ # total amount of the payment in Merchants currency (ex 25.46/25.4/25)
164
+ def merchant_amount
165
+ params['mb_amount']
166
+ end
167
+
168
+ # Was this a test transaction?
169
+ def test?
170
+ false
171
+ end
172
+
173
+ def secret
174
+ @options[:credential2]
175
+ end
176
+
177
+ # Acknowledge the transaction to MoneyBooker. This method has to be called after a new
178
+ # apc arrives. It will verify that all the information we received is correct and will return a
179
+ # ok or a fail. The secret (second credential) has to be provided in the parameter :credential2
180
+ # when instantiating the Notification object.
181
+ #
182
+ # Example:
183
+ #
184
+ # def ipn
185
+ # notify = Moneybookers.notification(request.raw_post, :credential2 => 'secret')
186
+ #
187
+ # if notify.acknowledge
188
+ # ... process order ... if notify.complete?
189
+ # else
190
+ # ... log possible hacking attempt ...
191
+ # end
192
+ def acknowledge(authcode = nil)
193
+ fields = [merchant_id, item_id, Digest::MD5.hexdigest(secret.to_s).upcase, merchant_amount, merchant_currency, status_code].join
194
+ md5sig == Digest::MD5.hexdigest(fields).upcase
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,228 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ # To start with Nochex, follow the instructions for installing
4
+ # ActiveMerchant as a plugin, as described on
5
+ # http://www.activemerchant.org/.
6
+ #
7
+ # The plugin will automatically add the ActionView helper for
8
+ # ActiveMerchant, which will allow you to make the Nochex payments.
9
+ # The idea behind the helper is that it generates an invisible
10
+ # forwarding screen that will automatically redirect the user.
11
+ # So you would collect all the information about the order and then
12
+ # simply render the hidden form, which redirects the user to Nochex.
13
+ #
14
+ # The syntax of the helper is as follows:
15
+ #
16
+ # <% payment_service_for 'order id', 'nochex_user_id',
17
+ # :amount => 50.00,
18
+ # :service => :nochex,
19
+ # :html => { :id => 'nochex-form' } do |service| %>
20
+ #
21
+ # <% service.customer :first_name => 'Cody',
22
+ # :last_name => 'Fauser',
23
+ # :phone => '(555)555-5555',
24
+ # :email => 'cody@example.com' %>
25
+ #
26
+ # <% service.billing_address :city => 'Ottawa',
27
+ # :address1 => '21 Snowy Brook Lane',
28
+ # :address2 => 'Apt. 36',
29
+ # :state => 'ON',
30
+ # :country => 'CA',
31
+ # :zip => 'K1J1E5' %>
32
+ #
33
+ # <% service.invoice '#1000' %>
34
+ # <% service.shipping '0.00' %>
35
+ # <% service.tax '0.00' %>
36
+ #
37
+ # <% service.notify_url url_for(:action => 'notify', :only_path => false) %>
38
+ # <% service.return_url url_for(:action => 'done', :only_path => false) %>
39
+ # <% service.cancel_return_url 'http://mystore.com' %>
40
+ # <% end %>
41
+ #
42
+ # The notify_url is the URL that the Nochex IPN will be sent. You can
43
+ # handle the notification in your controller action as follows:
44
+ #
45
+ # class NotificationController < ApplicationController
46
+ # include OffsitePayments::Integrations
47
+ #
48
+ # def notify
49
+ # notification = Nochex::Notification.new(request.raw_post)
50
+ #
51
+ # begin
52
+ # # Acknowledge notification with Nochex
53
+ # raise StandardError, 'Illegal Notification' unless notification.acknowledge
54
+ # # Process the payment
55
+ # rescue => e
56
+ # logger.warn("Illegal notification received: #{e.message}")
57
+ # ensure
58
+ # head(:ok)
59
+ # end
60
+ # end
61
+ # end
62
+ module Nochex
63
+ mattr_accessor :service_url
64
+ self.service_url = 'https://secure.nochex.com'
65
+
66
+ mattr_accessor :notification_confirmation_url
67
+ self.notification_confirmation_url = 'https://www.nochex.com/nochex.dll/apc/apc'
68
+
69
+ # Simply a convenience method that returns a new
70
+ # OffsitePayments::Integrations::Nochex::Notification
71
+ def self.notification(post, options = {})
72
+ Notification.new(post)
73
+ end
74
+
75
+ def self.return(query_string, options = {})
76
+ Return.new(query_string)
77
+ end
78
+
79
+ class Helper < OffsitePayments::Helper
80
+ # Required Parameters
81
+ # email
82
+ # amount
83
+ mapping :account, 'email'
84
+ mapping :amount, 'amount'
85
+
86
+ # Set the field status = test for testing with accounts:
87
+ # Account Password
88
+ # test1@nochex.com 123456
89
+ # test2@nochex.com 123456
90
+ # def initialize(order, account, options = {})
91
+ # super
92
+ # add_field('status', 'test')
93
+ # end
94
+
95
+ # Need to format the amount to have 2 decimal places
96
+ def amount=(money)
97
+ cents = money.respond_to?(:cents) ? money.cents : money
98
+ raise ArgumentError, "amount must be a Money object or an integer" if money.is_a?(String)
99
+ raise ActionViewHelperError, "amount must be greater than $0.00" if cents.to_i <= 0
100
+
101
+ add_field mappings[:amount], sprintf("%.2f", cents.to_f/100)
102
+ end
103
+
104
+ # Optional Parameters
105
+ # ordernumber
106
+ mapping :order, 'ordernumber'
107
+
108
+ # firstname
109
+ # lastname
110
+ # email_address_sender
111
+ mapping :customer, :first_name => 'firstname',
112
+ :last_name => 'lastname',
113
+ :email => 'email_address_sender'
114
+
115
+ # town
116
+ # firstline
117
+ # county
118
+ # postcode
119
+ mapping :billing_address, :city => 'town',
120
+ :address1 => 'firstline',
121
+ :state => 'county',
122
+ :zip => 'postcode'
123
+
124
+ # responderurl
125
+ mapping :notify_url, 'responderurl'
126
+
127
+ # returnurl
128
+ mapping :return_url, 'returnurl'
129
+
130
+ # cancelurl
131
+ mapping :cancel_return_url, 'cancelurl'
132
+
133
+ # description
134
+ mapping :description, 'description'
135
+
136
+ # Currently unmapped
137
+ # logo
138
+ end
139
+
140
+ # Parser and handler for incoming Automatic Payment Confirmations from Nochex.
141
+ class Notification < OffsitePayments::Notification
142
+ include ActiveMerchant::PostsData
143
+
144
+ def complete?
145
+ status == 'Completed'
146
+ end
147
+
148
+ # Id of the order we passed to Nochex
149
+ def item_id
150
+ params['order_id']
151
+ end
152
+
153
+ def transaction_id
154
+ params['transaction_id']
155
+ end
156
+
157
+ def currency
158
+ 'GBP'
159
+ end
160
+
161
+ # When was this payment received by the client.
162
+ def received_at
163
+ # U.K. Format: 27/09/2006 22:30:54
164
+ return if params['transaction_date'].blank?
165
+ time = params['transaction_date'].scan(/\d+/)
166
+ Time.utc(time[2], time[1], time[0], time[3], time[4], time[5])
167
+ end
168
+
169
+ def payer_email
170
+ params['from_email']
171
+ end
172
+
173
+ def receiver_email
174
+ params['to_email']
175
+ end
176
+
177
+ def security_key
178
+ params['security_key']
179
+ end
180
+
181
+ # the money amount we received in X.2 decimal.
182
+ def gross
183
+ sprintf("%.2f", params['amount'].to_f)
184
+ end
185
+
186
+ # Was this a test transaction?
187
+ def test?
188
+ params['status'] == 'test'
189
+ end
190
+
191
+ def status
192
+ 'Completed'
193
+ end
194
+
195
+ # Acknowledge the transaction to Nochex. This method has to be called after a new
196
+ # apc arrives. Nochex will verify that all the information we received are correct and will return a
197
+ # ok or a fail. This is very similar to the PayPal IPN scheme.
198
+ #
199
+ # Example:
200
+ #
201
+ # def nochex_ipn
202
+ # notify = NochexNotification.new(request.raw_post)
203
+ #
204
+ # if notify.acknowledge
205
+ # ... process order ... if notify.complete?
206
+ # else
207
+ # ... log possible hacking attempt ...
208
+ # end
209
+ def acknowledge(authcode = nil)
210
+ payload = raw
211
+
212
+ response = ssl_post(Nochex.notification_confirmation_url, payload,
213
+ 'Content-Length' => "#{payload.size}",
214
+ 'User-Agent' => "Active Merchant -- http://activemerchant.org",
215
+ 'Content-Type' => "application/x-www-form-urlencoded"
216
+ )
217
+
218
+ raise StandardError.new("Faulty Nochex result: #{response}") unless ["AUTHORISED", "DECLINED"].include?(response)
219
+
220
+ response == "AUTHORISED"
221
+ end
222
+ end
223
+
224
+ class Return < OffsitePayments::Return
225
+ end
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,255 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module PagSeguro
4
+ mattr_accessor :service_production_url
5
+ self.service_production_url = 'https://pagseguro.uol.com.br/v2/checkout/payment.html'
6
+
7
+ mattr_accessor :service_test_url
8
+ self.service_test_url = 'https://sandbox.pagseguro.uol.com.br/v2/checkout/payment.html'
9
+
10
+ mattr_accessor :invoicing_production_url
11
+ self.invoicing_production_url = 'https://ws.pagseguro.uol.com.br/v2/checkout/'
12
+
13
+ mattr_accessor :invoicing_test_url
14
+ self.invoicing_test_url = 'https://ws.sandbox.pagseguro.uol.com.br/v2/checkout/'
15
+
16
+ mattr_accessor :notification_production_url
17
+ self.notification_production_url = 'https://ws.pagseguro.uol.com.br/v2/transactions/notifications/'
18
+
19
+ mattr_accessor :notification_test_url
20
+ self.notification_test_url = 'https://ws.sandbox.pagseguro.uol.com.br/v2/transactions/notifications/'
21
+
22
+ def self.service_url
23
+ test? ? service_test_url : service_production_url
24
+ end
25
+
26
+ def self.invoicing_url
27
+ test? ? invoicing_test_url : invoicing_production_url
28
+ end
29
+
30
+ def self.notification_url
31
+ test? ? notification_test_url : notification_production_url
32
+ end
33
+
34
+ def self.notification(query_string, options = {})
35
+ Notification.new(query_string, options)
36
+ end
37
+
38
+ def self.return(query_string, options = {})
39
+ Return.new(query_string, options)
40
+ end
41
+
42
+ def self.test?
43
+ OffsitePayments.mode == :test
44
+ end
45
+
46
+ class Helper < OffsitePayments::Helper
47
+ def initialize(order_id, account, options)
48
+ super
49
+ @account = account
50
+
51
+ add_field('itemAmount1', sprintf("%0.02f", options[:amount]))
52
+ add_field('itemId1', '1')
53
+ add_field('itemQuantity1', '1')
54
+ add_field('shippingType', '3')
55
+ add_field('currency', 'BRL')
56
+ end
57
+
58
+ mapping :account, 'email'
59
+ mapping :credential2, 'token'
60
+
61
+ mapping :order, 'reference'
62
+
63
+ mapping :billing_address, :city => 'shippingAddressCity',
64
+ :address1 => 'shippingAddressStreet',
65
+ :address2 => 'shippingAddressNumber',
66
+ :state => 'shippingAddressState',
67
+ :zip => 'shippingAddressPostalCode',
68
+ :country => 'shippingAddressCountry'
69
+
70
+ mapping :notify_url, 'notificationURL'
71
+ mapping :return_url, 'redirectURL'
72
+ mapping :description, 'itemDescription1'
73
+
74
+ def form_fields
75
+ invoice_id = fetch_token
76
+
77
+ {"code" => invoice_id}
78
+ end
79
+
80
+ def shipping(value)
81
+ add_field("shippingCost", sprintf("%0.02f", value))
82
+ end
83
+
84
+ def customer(params = {})
85
+ phone = area_code_and_number(params[:phone])
86
+ full_name = remove_excessive_whitespace("#{params[:first_name]} #{params[:last_name]}")
87
+
88
+ add_field("senderAreaCode", phone[0])
89
+ add_field("senderPhone", phone[1])
90
+ add_field("senderEmail", params[:email])
91
+ add_field('senderName', full_name)
92
+ end
93
+
94
+ def fetch_token
95
+ uri = URI.parse(PagSeguro.invoicing_url)
96
+ http = Net::HTTP.new(uri.host, uri.port)
97
+ http.use_ssl = true
98
+
99
+ request = Net::HTTP::Post.new(uri.request_uri)
100
+ request.content_type = "application/x-www-form-urlencoded"
101
+ request.set_form_data @fields
102
+
103
+ response = http.request(request)
104
+ xml = Nokogiri::XML.parse(response.body)
105
+
106
+ check_for_errors(response, xml)
107
+
108
+ extract_token(xml)
109
+ rescue Timeout::Error, Errno::ECONNRESET => e
110
+ raise ActionViewHelperError, "Erro ao conectar-se ao PagSeguro. Por favor, tente novamente."
111
+ end
112
+
113
+ def area_code_and_number(phone)
114
+ phone.gsub!(/[^\d]/, '')
115
+
116
+ ddd = phone.slice(0..1)
117
+ number = phone.slice(2..12)
118
+
119
+ [ddd, number]
120
+ end
121
+
122
+ def check_for_errors(response, xml)
123
+ return if response.code == "200"
124
+
125
+ case response.code
126
+ when "400"
127
+ raise ActionViewHelperError, humanize_errors(xml)
128
+ when "401"
129
+ raise ActionViewHelperError, "Token do PagSeguro inválido."
130
+ else
131
+ raise ActiveMerchant::ResponseError, response
132
+ end
133
+ end
134
+
135
+ def extract_token(xml)
136
+ xml.css("code").text
137
+ end
138
+
139
+ def humanize_errors(xml)
140
+ # reference: https://pagseguro.uol.com.br/v2/guia-de-integracao/codigos-de-erro.html
141
+
142
+ xml.css("errors").children.map do |error|
143
+ case error.css('code').text
144
+ when "11013"
145
+ "Código de área inválido"
146
+ when "11014"
147
+ "Número de telefone inválido. Formato esperado: (DD) XXXX-XXXX"
148
+ when "11017"
149
+ "Código postal (CEP) inválido."
150
+ else
151
+ error.css('message').text
152
+ end
153
+ end.join(", ")
154
+ end
155
+
156
+ def remove_excessive_whitespace(text)
157
+ text.gsub(/\s{2,}/, ' ').strip
158
+ end
159
+ end
160
+
161
+ class Notification < OffsitePayments::Notification
162
+ def initialize(post, options = {})
163
+ notify_code = parse_http_query(post)["notificationCode"]
164
+ email = options[:credential1]
165
+ token = options[:credential2]
166
+
167
+ uri = URI.join(PagSeguro.notification_url, notify_code)
168
+ parse_xml(web_get(uri, email: email, token: token))
169
+ end
170
+
171
+ def complete?
172
+ status == "Completed"
173
+ end
174
+
175
+ def item_id
176
+ params["transaction"]["reference"]
177
+ end
178
+
179
+ def transaction_id
180
+ params["transaction"]["code"]
181
+ end
182
+
183
+ def received_at
184
+ params["transaction"]["date"]
185
+ end
186
+
187
+ def payer_email
188
+ params["sender"]["email"]
189
+ end
190
+
191
+ def gross
192
+ params["transaction"]["grossAmount"]
193
+ end
194
+
195
+ def currency
196
+ "BRL"
197
+ end
198
+
199
+ def payment_method_type
200
+ params["transaction"]["paymentMethod"]["type"]
201
+ end
202
+
203
+ def payment_method_code
204
+ params["transaction"]["paymentMethod"]["code"]
205
+ end
206
+
207
+ def status
208
+ case params["transaction"]["status"]
209
+ when "1", "2"
210
+ "Pending"
211
+ when "3"
212
+ "Completed"
213
+ when "4"
214
+ "Available"
215
+ when "5"
216
+ "Dispute"
217
+ when "6"
218
+ "Reversed"
219
+ when "7"
220
+ "Failed"
221
+ end
222
+ end
223
+
224
+ # There's no acknowledge for PagSeguro
225
+ def acknowledge
226
+ true
227
+ end
228
+
229
+ private
230
+
231
+ def web_get(uri, params)
232
+ uri.query = URI.encode_www_form(params)
233
+
234
+ response = Net::HTTP.get_response(uri)
235
+ response.body
236
+ end
237
+
238
+ # Take the posted data and move the relevant data into a hash
239
+ def parse_xml(post)
240
+ @params = Hash.from_xml(post)
241
+ end
242
+
243
+ def parse_http_query(post)
244
+ @raw = post
245
+ params = {}
246
+ for line in post.split('&')
247
+ key, value = *line.scan( %r{^(\w+)\=(.*)$} ).flatten
248
+ params[key] = value
249
+ end
250
+ params
251
+ end
252
+ end
253
+ end
254
+ end
255
+ end