payzilla 0.0.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.
Files changed (52) hide show
  1. data/.gitignore +23 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +23 -0
  5. data/README.md +82 -0
  6. data/Rakefile +4 -0
  7. data/init.rb +1 -0
  8. data/lib/encoding/converter.rb +5 -0
  9. data/lib/payzilla/config.rb +224 -0
  10. data/lib/payzilla/gateways/akado.rb +59 -0
  11. data/lib/payzilla/gateways/beeline.rb +205 -0
  12. data/lib/payzilla/gateways/cyberplat.rb +97 -0
  13. data/lib/payzilla/gateways/dummy.rb +72 -0
  14. data/lib/payzilla/gateways/gorod.rb +80 -0
  15. data/lib/payzilla/gateways/mailru.rb +56 -0
  16. data/lib/payzilla/gateways/matrix.rb +66 -0
  17. data/lib/payzilla/gateways/megafon.rb +120 -0
  18. data/lib/payzilla/gateways/mts.rb +200 -0
  19. data/lib/payzilla/gateways/osmp.rb +85 -0
  20. data/lib/payzilla/gateways/rapida.rb +127 -0
  21. data/lib/payzilla/gateways/skylink.rb +105 -0
  22. data/lib/payzilla/gateways/webmoney.rb +102 -0
  23. data/lib/payzilla/gateways/yamoney.rb +93 -0
  24. data/lib/payzilla/gateways/yota.rb +63 -0
  25. data/lib/payzilla/gateways.rb +173 -0
  26. data/lib/payzilla/payment.rb +161 -0
  27. data/lib/payzilla/revision.rb +18 -0
  28. data/lib/payzilla/transports/http.rb +62 -0
  29. data/lib/payzilla/utils/string_file.rb +14 -0
  30. data/lib/payzilla/version.rb +3 -0
  31. data/lib/payzilla.rb +19 -0
  32. data/lib/string.rb +12 -0
  33. data/payzilla.gemspec +33 -0
  34. data/schemas/.gitkeep +0 -0
  35. data/schemas/beeline.wsdl +538 -0
  36. data/spec/lib/payzilla/gateways/akado_spec.rb +31 -0
  37. data/spec/lib/payzilla/gateways/beeline_spec.rb +52 -0
  38. data/spec/lib/payzilla/gateways/cyberplat_spec.rb +44 -0
  39. data/spec/lib/payzilla/gateways/gorod_spec.rb +36 -0
  40. data/spec/lib/payzilla/gateways/mailru_spec.rb +24 -0
  41. data/spec/lib/payzilla/gateways/matrix_spec.rb +35 -0
  42. data/spec/lib/payzilla/gateways/megafon_spec.rb +45 -0
  43. data/spec/lib/payzilla/gateways/mts_spec.rb +55 -0
  44. data/spec/lib/payzilla/gateways/osmp_spec.rb +30 -0
  45. data/spec/lib/payzilla/gateways/rapida_spec.rb +48 -0
  46. data/spec/lib/payzilla/gateways/skylink_spec.rb +39 -0
  47. data/spec/lib/payzilla/gateways/webmoney_spec.rb +38 -0
  48. data/spec/lib/payzilla/gateways/yamoney_spec.rb +31 -0
  49. data/spec/lib/payzilla/gateways/yota_spec.rb +30 -0
  50. data/spec/spec_helper.rb +9 -0
  51. data/spec/support/config_stub.rb +7 -0
  52. metadata +236 -0
@@ -0,0 +1,85 @@
1
+ # coding: utf-8
2
+
3
+ require 'nokogiri'
4
+ require 'crack'
5
+
6
+ module Payzilla
7
+ module Gateways
8
+ class Osmp < Gateway
9
+ register_settings %w(client password terminal domain)
10
+
11
+ def check(payment)
12
+ builder = Builder::XmlMarkup.new
13
+ builder.instruct!
14
+ data = builder.request do
15
+ builder.tag! "request-type", 32
16
+ builder.tag! "terminal-id", @config.setting_client
17
+ builder.extra @config.setting_password, "name" => "password"
18
+ builder.extra payment.account, "name" => "phone"
19
+ end
20
+
21
+ begin
22
+ result = send data
23
+ result = Crack::XML.parse(result)
24
+ # TODO: Change returning code, when user doesn't exist
25
+ code = if result["response"]["exist"] == "0"
26
+ "1"
27
+ else
28
+ result["response"]["result_code"]
29
+ end
30
+ rescue Errno::ECONNRESET
31
+ code = -1000
32
+ end
33
+
34
+ retval(code)
35
+ end
36
+
37
+ def pay(payment)
38
+ builder = Builder::XmlMarkup.new
39
+ builder.instruct!
40
+ data = builder.request do
41
+ builder.tag! "request-type", 10
42
+ builder.extra @config.setting_password, "name" => "password"
43
+ builder.tag! "terminal-id", @config.setting_client
44
+ builder.auth do
45
+ builder.payment do
46
+ builder.tag! "transaction-number", Time.now.to_i
47
+ builder.to do
48
+ builder.amount payment.paid_amount
49
+ builder.tag! "service-id", 99
50
+ builder.tag! "account-number", payment.account
51
+ end
52
+ end
53
+ end
54
+ end
55
+ begin
56
+ result = send data
57
+ code = Nokogiri.XML(result).css("payment").
58
+ first.attributes["status"].value
59
+ rescue Errno::ECONNRESET
60
+ code = -1000
61
+ end
62
+
63
+ retval(code, true)
64
+ end
65
+
66
+ private
67
+
68
+ def retval(code, payment=nil)
69
+ if payment
70
+ {:success => (code == "50"), :error => code}
71
+ else
72
+ {:success => (code == "0"), :error => code}
73
+ end
74
+ end
75
+
76
+ def send(data)
77
+ result = RestClient.post @config.setting_domain, data
78
+
79
+ logger.debug(result.body) unless logger.blank?
80
+ return result.body
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,127 @@
1
+ # coding: utf-8
2
+
3
+ require 'crack'
4
+
5
+ module Payzilla
6
+ module Gateways
7
+ class Rapida < Gateway
8
+ include Payzilla::Transports::HTTP
9
+
10
+ can_list_providers
11
+ register_settings %w(url key_password)
12
+ register_attachments %w(cert key ca)
13
+
14
+ def providers
15
+ return retval(-1001) if settings_miss?
16
+
17
+ begin
18
+ providers = request("getfee")
19
+ providers = providers['rapida']
20
+ result = providers
21
+
22
+ return retval("0", result)
23
+ rescue Errno::ECONNRESET
24
+ return retval(-1000)
25
+ rescue Exception => e
26
+ logger.fatal e.to_s unless logger.blank?
27
+ return retval(-1002)
28
+ end
29
+ end
30
+
31
+ def check(payment)
32
+ return retval(-1001) if settings_miss?
33
+
34
+ begin
35
+ result = request "check", terminal(payment).merge(
36
+ :PaymExtId => payment.id,
37
+ :PaymSubjTp => payment.gateway_provider_id,
38
+ :Amount => 100,
39
+ :Params => fields(payment),
40
+ :FeeSum => 10
41
+ )
42
+
43
+ if result['Response']['Result'] == 'OK'
44
+ result['Response']['ErrCode'] = 0
45
+ else
46
+ result['Response']['ErrCode'] = -1002 if result['Response']['ErrCode'].blank?
47
+ end
48
+
49
+ return retval(result['Response']['ErrCode'])
50
+ rescue Errno::ECONNRESET
51
+ return retval(-1000)
52
+ rescue Exception => e
53
+ logger.fatal e.to_s unless logger.blank?
54
+ return retval(-1002)
55
+ end
56
+ end
57
+
58
+ def pay(payment)
59
+ return retval(-1001) if settings_miss?
60
+
61
+ begin
62
+ result = request "payment", terminal(payment).merge(
63
+ :PaymExtId => payment.id,
64
+ :PaymSubjTp => payment.gateway_provider_id,
65
+ :Amount => payment.enrolled_amount,
66
+ :Params => fields(payment),
67
+ :FeeSum => payment.commission_amount
68
+ )
69
+
70
+ if result['Response']['Result'] == 'OK'
71
+ result['Response']['ErrCode'] = 0
72
+ else
73
+ result['Response']['ErrCode'] = -1002 if result['Response']['ErrCode'].blank?
74
+ end
75
+
76
+ return retval(result['Response']['ErrCode'])
77
+ rescue Errno::ECONNRESET
78
+ return retval(-1000)
79
+ rescue Exception => e
80
+ logger.fatal e.to_s unless logger.blank?
81
+ return retval(-1002)
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def settings_miss?
88
+ @config.attachment_cert.blank? ||
89
+ @config.attachment_key.blank?
90
+ end
91
+
92
+ def terminal(payment)
93
+ return {
94
+ :TermType => payment.terminal_id.blank? ? '001-07' : '003-07',
95
+ :TermId => payment.terminal_id.blank? ? payment.user_id : payment.terminal_id
96
+ }
97
+ end
98
+
99
+ def fields(payment)
100
+ fields = payment.fields || {}
101
+ fields.collect{|k,v| "#{k}+#{v}"}.join(';')
102
+ end
103
+
104
+ def retval(code, data=nil)
105
+ result = {:success => (code.to_s == "0"), :error => code}
106
+ result[:data] = data unless data.blank?
107
+
108
+ result
109
+ end
110
+
111
+ def request(method, params={})
112
+ params[:function] = method
113
+
114
+ result = get @config.setting_url, params,
115
+ ssl(
116
+ @config.attachment_cert,
117
+ @config.attachment_key,
118
+ @config.setting_key_password,
119
+ @config.attachment_ca
120
+ )
121
+
122
+ logger.debug(dump_xml result) unless logger.blank?
123
+ return Crack::XML.parse(result)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,105 @@
1
+ # coding: utf-8
2
+
3
+ require 'builder'
4
+ require 'crack'
5
+
6
+ module Payzilla
7
+ module Gateways
8
+ class Skylink < Gateway
9
+ requires_revision
10
+ register_settings %w(client url)
11
+
12
+ def check(payment)
13
+ begin
14
+ result = send 'VALIDATE_PHONE',
15
+ :PhoneNum => payment.account
16
+
17
+ return retval(result['string'].split(':').first)
18
+ rescue Errno::ECONNRESET
19
+ return retval(-1000)
20
+ end
21
+ end
22
+
23
+ def pay(payment)
24
+ begin
25
+ transaction = get_transaction
26
+
27
+ result = send 'PAY_CASH_INPUT',
28
+ :PayNum => transaction,
29
+ :PurposeID => 2,
30
+ :PurposeNum => payment.account,
31
+ :PaySum => (payment.enrolled_amount * 100).to_i,
32
+ :PayDate => payment.created_at.strftime("%d.%m.%Y %H:%M:%S"),
33
+ :RegDate => payment.created_at.strftime("%d.%m.%Y %H:%M:%S"),
34
+ :Payer => 'Tester',
35
+ :CardNum => '',
36
+ :PosNum => "0",
37
+ :PayDocNum => payment.id,
38
+ :Dsc => '1'
39
+
40
+
41
+ return retval(result['string'].split(':').first, transaction) #retval(result, transaction)
42
+ rescue Errno::ECONNRESET
43
+ return retval(-1000)
44
+ end
45
+ end
46
+
47
+ def revise(payments, date)
48
+ builder = Builder::XmlMarkup.new
49
+
50
+ builder.instruct!
51
+ data = builder.payments do
52
+ paginate_payments(payments, builder) do |slice, builder|
53
+ generate_revision_page(slice, builder)
54
+ end
55
+ end
56
+
57
+ result = send 'REPORT_XML_SEND',
58
+ :RegDate => date.strftime("%d.%m.%Y"),
59
+ :Register => data
60
+
61
+ return retval(result['string'].split(':').first)
62
+ end
63
+
64
+ private
65
+
66
+ def generate_revision_page(payments, builder)
67
+ payments.each do |p|
68
+ builder.payment(
69
+ :PaySum => (p.enrolled_amount * 100).to_i,
70
+ :PayType => 1,
71
+ :PurposeID => 2,
72
+ :PurposeNum => p.account,
73
+ :PayNum => p.gateway_payment_id,
74
+ :PayDate => p.created_at.strftime("%d.%m.%Y %H:%M:%S"),
75
+ :RegDate => p.created_at.strftime("%d.%m.%Y %H:%M:%S"),
76
+ :PosNum => "0",
77
+ :PayDocNum => p.id
78
+ )
79
+ end
80
+ end
81
+
82
+ def retval(code, transaction=false)
83
+ result = {:success => (code == "0"), :error => code}
84
+ result[:gateway_payment_id] = transaction if transaction
85
+
86
+ result
87
+ end
88
+
89
+ def get_transaction
90
+ return send('PAY_NUM_GET')["int"].to_i
91
+ end
92
+
93
+ def send(operation, params={})
94
+ if @config.setting_client.blank? ||
95
+ @config.setting_url.blank?
96
+ return -1001
97
+ end
98
+
99
+ params[:PaySystemCode] = @config.setting_client
100
+ result = RestClient.post "#{@config.setting_url}/#{operation}", params
101
+ return Crack::XML.parse(result)
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,102 @@
1
+ # coding: utf-8
2
+
3
+ require 'webmoney'
4
+ require 'gyoku'
5
+ require 'crack'
6
+
7
+ module Payzilla
8
+ module Gateways
9
+ class Webmoney < Gateway
10
+ class Signer
11
+ include ::Webmoney
12
+ end
13
+
14
+ register_settings %w(wmid kiosk_id key_password)
15
+ register_attachments %w(cert key)
16
+ register_switches %w(test_mode)
17
+
18
+ def check(payment)
19
+ begin
20
+ result = send 'XMLBankGatewaysInputAccess1',
21
+ :sign => signer.sign("#{@config.setting_wmid}100#{payment.fields['purse']}#{payment.fields['phone']}#{@config.setting_kiosk_id}"),
22
+ :'attributes!' => {
23
+ :sign => {
24
+ :type => 1
25
+ }
26
+ },
27
+ :payment => {
28
+ :price => 100,
29
+ :purse => payment.fields['purse'],
30
+ :phone => payment.fields['phone']
31
+ }
32
+
33
+ return retval(result['retval'])
34
+ rescue Errno::ECONNRESET
35
+ return retval(-1000)
36
+ end
37
+ end
38
+
39
+ def pay(payment)
40
+ begin
41
+ result = send 'XMLBankGatewaysInput',
42
+ :sign => signer.sign("#{payment.id}#{payment.enrolled_amount}#{payment.id}#{payment.fields['purse']}#{payment.fields['phone']}"),
43
+ :attributes! => {
44
+ :sign => {
45
+ :type => 1
46
+ },
47
+ :payment => {
48
+ :id => payment.id,
49
+ :test => @config.switch_test_mode
50
+ }
51
+ },
52
+ :payment => {
53
+ :name => payment.fields['name'],
54
+ :passport_serie => payment.fields['passport_serie'],
55
+ :passport_number => payment.fields['passport_number'],
56
+ :passport_date => payment.fields['passport_date'],
57
+ :price => payment.enrolled_amount,
58
+ :purse => payment.fields['purse'],
59
+ :cheque => payment.id,
60
+ :date => payment.created_at,
61
+ :kiosk_id => @config.setting_kiosk_id,
62
+ :phone => payment.fields['phone']
63
+ }
64
+
65
+ return retval(result['retval'], result['payment']['wmtranid'])
66
+ rescue Errno::ECONNRESET
67
+ return retval(-1000)
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def signer
74
+ if @signer.blank?
75
+ cert = OpenSSL::X509::Certificate.new(File.read @config.attachment_cert)
76
+ key = OpenSSL::PKey::RSA.new(File.read(@config.attachment_key), @config.setting_key_password)
77
+
78
+ @signer = Signer.new :wmid => @config.setting_wmid, :cert => cert, :key => key
79
+ end
80
+
81
+ @signer
82
+ end
83
+
84
+ def retval(result, foreign_id = false)
85
+ result = {:success => result.to_s == "0", :error => result}
86
+ result[:gateway_payment_id] = foreign_id if foreign_id
87
+ return result
88
+ end
89
+
90
+ def send(operation, params)
91
+ params[:wmid] = @config.setting_wmid
92
+ resource = RestClient::Resource.new("https://w3s.guarantee.ru/#{operation}.aspx")
93
+
94
+ params = Gyoku.xml(:'w3s.request' => params)
95
+ result = resource.post params, :content_type => 'application/xml'
96
+
97
+ return Nori.parse(result.to_s)
98
+ end
99
+
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,93 @@
1
+ # coding: utf-8
2
+
3
+ require 'gpgme'
4
+
5
+ module Payzilla
6
+ module Gateways
7
+ class Yamoney < Gateway
8
+ register_settings %w(url currency password gpg_key)
9
+ register_attachments %w(public_key secret_key)
10
+
11
+ def check(payment)
12
+ begin
13
+ result = send :VERSION => '2.02',
14
+ :TR_NR => payment.id,
15
+ :DSTACNT_NR => payment.account,
16
+ :TR_AMT => payment.enrolled_amount,
17
+ :CUR_CD => @config.setting_currency,
18
+ :ACT_CD => 1002,
19
+ :SIGN => sign([payment.id, 1002, payment.account, payment.enrolled_amount, @config.setting_currency])
20
+
21
+ return retval(result)
22
+ rescue Errno::ECONNRESET
23
+ return {:success => false, :error => -1000}
24
+ end
25
+ end
26
+
27
+ def pay(payment)
28
+ begin
29
+ result = send :VERSION => '2.02',
30
+ :TR_NR => payment.id,
31
+ :DSTACNT_NR => payment.account,
32
+ :TR_AMT => payment.enrolled_amount,
33
+ :CUR_CD => @config.setting_currency,
34
+ :ACT_CD => 1,
35
+ :CONT => "Пополнение кошелька".force_encoding("Windows-1251"),
36
+ :SIGN => sign([payment.id, 1002, payment.account, payment.enrolled_amount, @config.setting_currency])
37
+
38
+ return retval(result)
39
+ rescue Errno::ECONNRESET
40
+ return {:success => false, :error => -1000}
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def retval(result)
47
+ if result["RES_CD"].strip == "0"
48
+ return {:success => true, :error => "0"}
49
+ else
50
+ return {:success => false, :error => result["ERR_CD"].strip}
51
+ end
52
+ end
53
+
54
+ def sign(values)
55
+ attach_keys
56
+
57
+ crypto = GPGME::Crypto.new :armor => true
58
+ crypto.clearsign(values.map{|x| x.to_s}.join('&'),
59
+ {
60
+ :password => @config.setting_password,
61
+ :signer => @config.setting_gpg_key
62
+ }
63
+ )
64
+ end
65
+
66
+ def attach_keys
67
+ %w(public secret).each do |key|
68
+ if GPGME::Key.find(key.to_sym, @config.setting_gpg_key).empty?
69
+ GPGME::Key.import(File.open(@config.send("attachment_#{key}_key".to_sym)))
70
+ end
71
+ end
72
+ end
73
+
74
+ def send(params)
75
+ resource = RestClient::Resource.new(@config.setting_url)
76
+ headers = { :content_type => "application/x-www-form-urlencoded;charset=Windows-1251" }
77
+
78
+ result = resource.post params, headers
79
+ sign = GPGME::Crypto.new(:armor => true)
80
+ params = sign.verify(result.to_s) do |sig|
81
+ result = {"RES_CD" => "1", "ERR_CD" => "Bad signature" } if sig.bad?
82
+ end
83
+
84
+ return result if result.kind_of?(Hash)
85
+ result = params.to_s.split("\n").map{|x| x.split("=")}.flatten
86
+ result = Hash[*result]
87
+
88
+ return result
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,63 @@
1
+ # coding: utf-8
2
+
3
+ require 'crack'
4
+
5
+ module Payzilla
6
+ module Gateways
7
+ class Yota < Gateway
8
+ register_settings %w(url key_password)
9
+ register_attachments %w(cert key ca)
10
+
11
+ def check(payment)
12
+ begin
13
+ result = send 'check',
14
+ :number => payment.account,
15
+ :amount => 100
16
+
17
+ return retval(result)
18
+ rescue Errno::ECONNRESET
19
+ return retval(-1000)
20
+ end
21
+ end
22
+
23
+ def pay(payment)
24
+ begin
25
+ result = send 'payment',
26
+ :number => payment.account,
27
+ :amount => 100,
28
+ :receipt => payment.id,
29
+ :date => payment.created_at
30
+
31
+ return retval(result)
32
+ rescue Errno::ECONNRESET
33
+ return retval(-1000)
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def retval(code)
40
+ {:success => (code == "0"), :error => code}
41
+ end
42
+
43
+ def send(operation, params)
44
+ params[:action] = operation
45
+ params[:type] = 1
46
+
47
+ resource = RestClient::Resource.new(
48
+ @config.setting_url,
49
+ ssl_settings(
50
+ @config.attachment_cert,
51
+ @config.attachment_key,
52
+ @config.setting_key_password,
53
+ @config.attachment_ca
54
+ )
55
+ )
56
+
57
+ result = resource.get :params => params
58
+ return Crack::XML.parse(result.to_s)['response']['code']
59
+ end
60
+
61
+ end
62
+ end
63
+ end