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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 31905ca406036e6f2bf16b640712b428e67b65a0
4
+ data.tar.gz: 70682717c1a7eee957eb260d483c2a7fd4468780
5
+ SHA512:
6
+ metadata.gz: 8387471fcd228734a7ebfa38af8185eda8ccd61a294fbcd46f890148ce157d9bffca6b24499f69563b9d5974791ad602b13e4992778f154fccb73c957679bbcf
7
+ data.tar.gz: 1e96c39aeb02cb2ec032fadc29e538094bd9b3e65c4a171b377b76b4a95b7f149effdcd040246db24b5f35f5d9927e9e877c9bb736a9c6f4cd41141443e42bc9
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005-2014 Tobias Luetke
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.
@@ -0,0 +1,76 @@
1
+ # Better Offsite Payments
2
+ [![Build Status](https://travis-ci.org/yurijmi/better_offsite_payments.svg?branch=master)](https://travis-ci.org/yurijmi/better_offsite_payments)
3
+ [![Code Climate](https://codeclimate.com/github/yurijmi/better_offsite_payments/badges/gpa.svg)](https://codeclimate.com/github/yurijmi/better_offsite_payments)
4
+ [![Test Coverage](https://codeclimate.com/github/yurijmi/better_offsite_payments/badges/coverage.svg)](https://codeclimate.com/github/yurijmi/better_offsite_payments/coverage)
5
+
6
+ Offsite Payments is an extraction from the ecommerce system [Shopify](http://www.shopify.com). Shopify's requirements for a simple and unified API to handle dozens of different offsite payment pages (often called hosted payment pages) with very different exposed APIs was the chief principle in designing the library.
7
+
8
+ It was developed for usage in Ruby on Rails web applications and integrates seamlessly
9
+ as a Rails plugin. It should also work as a stand alone Ruby library, but much of the benefit is in the ActionView helpers which are Rails-specific.
10
+
11
+ Offsite Payments has been in production use (originally as part of the [ActiveMerchant](https://github.com/activemerchant/active_merchant) project) since June 2006. It is maintained by the [Shopify](http://www.shopify.com) team, with much help from an ever-growing set of contributors.
12
+
13
+ *The Universal API defines a standard set of requests and callbacks that can be used to integrate with Shopify. A sample app and documentation are hosted [here](https://github.com/Shopify/offsite-gateway-sim). The Universal API should be used for all integrations in which placement within Shopify is the desired outcome.
14
+
15
+ ## Installation
16
+
17
+ ### From Git
18
+
19
+ You can check out the latest source from git:
20
+
21
+ git clone https://github.com/yurijmi/better_offsite_payments.git
22
+
23
+ ### From RubyGems
24
+
25
+ Installation from RubyGems:
26
+
27
+ gem install better_offsite_payments
28
+
29
+ Or, if you're using Bundler, just add the following to your Gemfile:
30
+
31
+ gem 'better_offsite_payments'
32
+
33
+ [API documentation](http://www.rubydoc.info/github/yurijmi/better_offsite_payments/master).
34
+
35
+ ## Supported Integrations
36
+
37
+ * [2 Checkout](http://www.2checkout.com)
38
+ * [A1Agregator](http://a1agregator.ru/) - RU
39
+ * [Authorize.Net SIM](http://developer.authorize.net/api/sim/) - US
40
+ * [Banca Sella GestPay](https://www.gestpay.it/)
41
+ * [BitPay](https://bitpay.com/)
42
+ * [Chronopay](http://www.chronopay.com)
43
+ * [DirecPay](http://www.timesofmoney.com/direcpay/jsp/home.jsp)
44
+ * [Direct-eBanking / sofortueberweisung.de by Payment-Networks AG](https://www.payment-network.com/deb_com_en/merchantarea/home) - DE, AT, CH, BE, UK, NL
45
+ * [Dotpay](http://dotpay.pl)
46
+ * [Doku](http://doku.com)
47
+ * [Dwolla](https://www.dwolla.com/default.aspx)
48
+ * [ePay](http://www.epay.dk/epay-payment-solutions/)
49
+ * [First Data](https://firstdata.zendesk.com/entries/407522-first-data-global-gateway-e4sm-payment-pages-integration-manual)
50
+ * [HiTRUST](http://www.hitrust.com.hk/)
51
+ * [MegaKassa](https://megakassa.ru) - RU
52
+ * [MOLPay](http://www.molpay.com/v2/) - MY, SG, ID, TH, VN, PH, CN, AU
53
+ * [Moneybookers](http://www.moneybookers.com)
54
+ * [Nochex](http://www.nochex.com)
55
+ * [PagSeguro](http://www.pagseguro.com.br/) - BR
56
+ * [Paxum](https://www.paxum.com/)
57
+ * [PayPal Website Payments Standard](https://www.paypal.com/cgi-bin/webscr?cmd#_wp-standard-overview-outside)
58
+ * [PayDollar](http://www.paydollar.com)
59
+ * [Paysbuy](https://www.paysbuy.com/) - TH
60
+ * [Platron](https://www.platron.ru/) - RU
61
+ * [Realex](http://www.realexpayments.com)
62
+ * [RBK Money](https://rbkmoney.ru/) - RU
63
+ * [Robokassa](http://robokassa.ru/) - RU
64
+ * [SagePay Form](http://www.sagepay.com/products_services/sage_pay_go/integration/form)
65
+ * [Suomen Maksuturva](https://www.maksuturva.fi/services/vendor_services/integration_guidelines.html)
66
+ * [Valitor](http://www.valitor.is/) - IS
67
+ * [Verkkomaksut](http://www.verkkomaksut.fi) - FI
68
+ * [WebMoney](http://www.webmoney.ru) - RU
69
+ * [WebPay](http://webpay.by/)
70
+ * [WorldPay](http://www.worldpay.com)
71
+ * [YandexMoney](https://kassa.yandex.ru) - RU
72
+
73
+ ## Misc.
74
+
75
+ - This library is MIT licensed.
76
+ - We will gladly accept contributions. See **CONTRIBUTING.md** for more information.
@@ -0,0 +1,39 @@
1
+ require 'securerandom'
2
+ require 'cgi'
3
+ require "timeout"
4
+ require "socket"
5
+
6
+ require 'active_utils'
7
+
8
+ require "offsite_payments/helper"
9
+ require "offsite_payments/notification"
10
+ require "offsite_payments/return"
11
+ require "offsite_payments/integrations"
12
+ require "offsite_payments/action_view_helper"
13
+
14
+ I18n.enforce_available_locales = false
15
+
16
+ module OffsitePayments
17
+ # Return the matching integration module
18
+ # You can then get the notification from the module
19
+ # * <tt>bogus</tt>: Bogus - Does nothing (for testing)
20
+ # * <tt>chronopay</tt>: Chronopay
21
+ # * <tt>paypal</tt>: Paypal
22
+ #
23
+ # chronopay = OffsitePayments.integration('chronopay')
24
+ # notification = chronopay.notification(raw_post)
25
+ #
26
+ def self.integration(name)
27
+ Integrations.const_get("#{name.to_s.downcase}".camelize)
28
+ end
29
+
30
+ mattr_accessor :mode
31
+ self.mode = :production
32
+
33
+ # A check to see if we're in test mode
34
+ def self.test?
35
+ self.mode == :test
36
+ end
37
+
38
+ CURRENCIES_WITHOUT_FRACTIONS = [ 'BIF', 'BYR', 'CLP', 'CVE', 'DJF', 'GNF', 'HUF', 'ISK', 'JPY', 'KMF', 'KRW', 'PYG', 'RWF', 'TWD', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF' ]
39
+ end
@@ -0,0 +1,72 @@
1
+ require 'action_pack'
2
+
3
+ module OffsitePayments #:nodoc:
4
+ ActionViewHelperError = Class.new(StandardError)
5
+
6
+ module ActionViewHelper
7
+ # This helper allows the usage of different payment integrations
8
+ # through a single form helper. Payment integrations are the
9
+ # type of service where the user is redirected to the secure
10
+ # site of the service, like Paypal or Chronopay.
11
+ #
12
+ # The helper creates a scope around a payment service helper
13
+ # which provides the specific mapping for that service.
14
+ #
15
+ # <% payment_service_for 1000, 'paypalemail@mystore.com',
16
+ # :amount => 50.00,
17
+ # :currency => 'CAD',
18
+ # :service => :paypal,
19
+ # :html => { :id => 'payment-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(:only_path => false, :action => 'notify') %>
38
+ # <% service.return_url url_for(:only_path => false, :action => 'done') %>
39
+ # <% service.cancel_return_url 'http://mystore.com' %>
40
+ # <% end %>
41
+ #
42
+ def payment_service_for(order, account, options = {}, &proc)
43
+ raise ArgumentError, "Missing block" unless block_given?
44
+
45
+ integration_module = OffsitePayments::integration(options.delete(:service).to_s)
46
+ service_class = integration_module.const_get('Helper')
47
+
48
+ form_options = options.delete(:html) || {}
49
+ service = service_class.new(order, account, options)
50
+ form_options[:method] = service.form_method
51
+ result = []
52
+ service_url = service.respond_to?(:credential_based_url) ? service.credential_based_url : integration_module.service_url
53
+ result << form_tag(service_url, form_options)
54
+
55
+ result << capture(service, &proc)
56
+
57
+ service.form_fields.each do |field, value|
58
+ result << hidden_field_tag(field, value)
59
+ end
60
+
61
+ service.raw_html_fields.each do |field, value|
62
+ result << "<input id=\"#{field}\" name=\"#{field}\" type=\"hidden\" value=\"#{value}\" />\n"
63
+ end
64
+
65
+ result << '</form>'
66
+ result= result.join("\n")
67
+
68
+ concat(result.respond_to?(:html_safe) ? result.html_safe : result)
69
+ nil
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,120 @@
1
+ module OffsitePayments #:nodoc:
2
+ class Helper #:nodoc:
3
+ attr_reader :fields
4
+ class_attribute :service_url
5
+ class_attribute :mappings
6
+ class_attribute :country_format
7
+ self.country_format = :alpha2
8
+
9
+ # The application making the calls to the gateway
10
+ # Useful for things like the PayPal build notation (BN) id fields
11
+ class_attribute :application_id
12
+ self.application_id = 'ActiveMerchant'
13
+
14
+ def self.inherited(subclass)
15
+ subclass.mappings ||= {}
16
+ end
17
+
18
+ def initialize(order, account, options = {})
19
+ options.assert_valid_keys([:amount, :currency, :test, :credential2, :credential3, :credential4, :country, :account_name, :description, :transaction_type, :authcode, :notify_url, :return_url, :redirect_param, :forward_url, :checkout_token])
20
+ @fields = {}
21
+ @raw_html_fields = []
22
+ @test = options[:test]
23
+ self.order = order
24
+ self.account = account
25
+ self.amount = options[:amount]
26
+ self.currency = options[:currency]
27
+ self.credential2 = options[:credential2]
28
+ self.credential3 = options[:credential3]
29
+ self.credential4 = options[:credential4]
30
+ self.notify_url = options[:notify_url]
31
+ self.return_url = options[:return_url]
32
+ self.redirect_param = options[:redirect_param]
33
+ self.checkout_token = options[:checkout_token]
34
+ end
35
+
36
+ def self.mapping(attribute, options = {})
37
+ self.mappings[attribute] = options
38
+ end
39
+
40
+ def add_field(name, value)
41
+ return if name.blank? || value.blank?
42
+ @fields[name.to_s] = value.to_s
43
+ end
44
+
45
+ def add_fields(subkey, params = {})
46
+ params.each do |k, v|
47
+ field = mappings[subkey][k]
48
+ add_field(field, v) unless field.blank?
49
+ end
50
+ end
51
+
52
+ # Add a field that has characters that CGI::escape would mangle. Allows
53
+ # for multiple fields with the same name (e.g., to support line items).
54
+ def add_raw_html_field(name, value)
55
+ return if name.blank? || value.blank?
56
+ @raw_html_fields << [name, value]
57
+ end
58
+
59
+ def raw_html_fields
60
+ @raw_html_fields
61
+ end
62
+
63
+ def billing_address(params = {})
64
+ add_address(:billing_address, params)
65
+ end
66
+
67
+ def shipping_address(params = {})
68
+ add_address(:shipping_address, params)
69
+ end
70
+
71
+ def form_fields
72
+ @fields
73
+ end
74
+
75
+ def test?
76
+ @test_mode ||= OffsitePayments.mode == :test || !!@test
77
+ end
78
+
79
+ def form_method
80
+ "POST"
81
+ end
82
+
83
+ private
84
+
85
+ def add_address(key, params)
86
+ return if mappings[key].nil?
87
+
88
+ code = lookup_country_code(params.delete(:country))
89
+ add_field(mappings[key][:country], code)
90
+ add_fields(key, params)
91
+ end
92
+
93
+ def lookup_country_code(name_or_code, format = country_format)
94
+ country = ActiveUtils::Country.find(name_or_code)
95
+ country.code(format).to_s
96
+ rescue ActiveUtils::InvalidCountryCodeError
97
+ name_or_code
98
+ end
99
+
100
+ def method_missing(method_id, *args)
101
+ method_id = method_id.to_s.gsub(/=$/, '').to_sym
102
+ # Return and do nothing if the mapping was not found. This allows
103
+ # for easy substitution of the different integrations
104
+ return if mappings[method_id].nil?
105
+
106
+ mapping = mappings[method_id]
107
+
108
+ case mapping
109
+ when Array
110
+ mapping.each{ |field| add_field(field, args.last) }
111
+ when Hash
112
+ options = args.last.is_a?(Hash) ? args.pop : {}
113
+
114
+ mapping.each{ |key, field| add_field(field, options[key]) }
115
+ else
116
+ add_field(mapping, args.last)
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,14 @@
1
+ module OffsitePayments
2
+ module Integrations
3
+ Dir[File.dirname(__FILE__) + '/integrations/*.rb'].each do |f|
4
+ # Get camelized class name
5
+ filename = File.basename(f, '.rb')
6
+
7
+ # Camelize the string to get the class name
8
+ integration_class = filename.camelize.to_sym
9
+
10
+ # Register for autoloading
11
+ autoload integration_class, f
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,245 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module A1agregator
4
+ mattr_accessor :service_url
5
+ self.service_url = 'https://partner.a1agregator.ru/a1lite/input/'
6
+
7
+ mattr_accessor :signature_parameter_name
8
+ self.signature_parameter_name = 'check'
9
+
10
+ def self.notification(*args)
11
+ Notification.new(*args)
12
+ end
13
+
14
+ def self.status(login, password)
15
+ Status.new(login, password)
16
+ end
17
+
18
+ class Helper < OffsitePayments::Helper
19
+ # public key
20
+ mapping :account, 'key'
21
+
22
+ mapping :amount, 'cost'
23
+
24
+ mapping :order, 'order_id'
25
+
26
+ mapping :customer, :email => 'email',
27
+ :phone => 'phone_number'
28
+
29
+ # payment description
30
+ mapping :credential2, 'name'
31
+
32
+ mapping :credential3, 'comment'
33
+
34
+ # on error
35
+ # 1 - raise error
36
+ # 0 - redirect
37
+ mapping :credential4, 'verbose'
38
+ end
39
+
40
+ class Notification < OffsitePayments::Notification
41
+ self.production_ips = [
42
+ '78.108.178.206',
43
+ '79.137.235.129',
44
+ '95.163.96.79',
45
+ '212.24.38.100'
46
+ ]
47
+
48
+ def initialize(*args)
49
+ super
50
+ guess_notification_type
51
+ end
52
+
53
+ # Simple notification request params:
54
+ # tid
55
+ # name
56
+ # comment
57
+ # partner_id
58
+ # service_id
59
+ # order_id
60
+ # type
61
+ # partner_income
62
+ # system_income
63
+
64
+ def complete?
65
+ true
66
+ end
67
+
68
+ def transaction_id
69
+ params['tid']
70
+ end
71
+
72
+ def title
73
+ params['name']
74
+ end
75
+
76
+ def comment
77
+ params['comment']
78
+ end
79
+
80
+ def partner_id
81
+ params['partner_id']
82
+ end
83
+
84
+ def service_id
85
+ params['service_id']
86
+ end
87
+
88
+ def item_id
89
+ params['order_id']
90
+ end
91
+
92
+ def type
93
+ params['type']
94
+ end
95
+
96
+ def partner_income
97
+ params['partner_income']
98
+ end
99
+
100
+ def system_income
101
+ params['system_income']
102
+ end
103
+
104
+ # Additional notification request params:
105
+ # tid
106
+ # name
107
+ # comment
108
+ # partner_id
109
+ # service_id
110
+ # order_id
111
+ # type
112
+ # cost
113
+ # income_total
114
+ # income
115
+ # partner_income
116
+ # system_income
117
+ # command
118
+ # phone_number
119
+ # email
120
+ # resultStr
121
+ # date_created
122
+ # version
123
+ # check
124
+
125
+ def inclome_total
126
+ params['income_total']
127
+ end
128
+
129
+ def income
130
+ params['income']
131
+ end
132
+
133
+ def partner_income
134
+ params['partner_income']
135
+ end
136
+
137
+ def system_income
138
+ params['system_income']
139
+ end
140
+
141
+ def command
142
+ params['command']
143
+ end
144
+
145
+ def phone_number
146
+ params['phone_number']
147
+ end
148
+
149
+ def payer_email
150
+ params['email']
151
+ end
152
+
153
+ def result_string
154
+ params['resultStr']
155
+ end
156
+
157
+ def received_at
158
+ params['date_created']
159
+ end
160
+
161
+ def version
162
+ params['version']
163
+ end
164
+
165
+ def security_key
166
+ params[A1agregator.signature_parameter_name].to_s.downcase
167
+ end
168
+
169
+ # the money amount we received in X.2 decimal.
170
+ alias_method :gross, :system_income
171
+
172
+ def currency
173
+ 'RUB'
174
+ end
175
+
176
+ # Was this a test transaction?
177
+ def test?
178
+ params['test'] == '1'
179
+ end
180
+
181
+ def simple_notification?
182
+ @notification_type == :simple
183
+ end
184
+
185
+ def additional_notification?
186
+ @notification_type == :additional
187
+ end
188
+
189
+ def acknowledge(authcode = nil)
190
+ security_key == signature
191
+ end
192
+
193
+ private
194
+
195
+ def signature
196
+ data = "#{params['tid']}\
197
+ #{params['name']}\
198
+ #{params['comment']}\
199
+ #{params['partner_id']}\
200
+ #{params['service_id']}\
201
+ #{params['order_id']}\
202
+ #{params['type']}\
203
+ #{params['partner_income']}\
204
+ #{params['system_income']}\
205
+ #{params['test']}\
206
+ #{@options[:secret]}"
207
+ Digest::MD5.hexdigest(data)
208
+ end
209
+
210
+ def guess_notification_type
211
+ @notification_type = params['version'] ? :additional : :simple
212
+ end
213
+ end
214
+
215
+ class Status
216
+ include ActiveUtils::PostsData
217
+
218
+ STATUS_TEST_URL = 'https://partner.a1pay.ru/a1lite/info/'
219
+
220
+ attr_accessor :login, :password
221
+
222
+ def initialize(login, password)
223
+ @login, @password = login, password
224
+ end
225
+
226
+ # agregator provides two methods:
227
+ # by tid - transaction id
228
+ # by order_id & service_id
229
+ def update(options = {})
230
+ data = PostData.new
231
+ data[:user] = @login
232
+ data[:pass] = @password
233
+ if options[:tid]
234
+ data[:tid] = options[:tid]
235
+ else
236
+ data[:ord_id] = options[:ord_id]
237
+ data[:service_id] = options[:service_id]
238
+ end
239
+
240
+ ssl_post(STATUS_TEST_URL, data.to_post_data)
241
+ end
242
+ end
243
+ end
244
+ end
245
+ end