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.
- data/.gitignore +23 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE +23 -0
- data/README.md +82 -0
- data/Rakefile +4 -0
- data/init.rb +1 -0
- data/lib/encoding/converter.rb +5 -0
- data/lib/payzilla/config.rb +224 -0
- data/lib/payzilla/gateways/akado.rb +59 -0
- data/lib/payzilla/gateways/beeline.rb +205 -0
- data/lib/payzilla/gateways/cyberplat.rb +97 -0
- data/lib/payzilla/gateways/dummy.rb +72 -0
- data/lib/payzilla/gateways/gorod.rb +80 -0
- data/lib/payzilla/gateways/mailru.rb +56 -0
- data/lib/payzilla/gateways/matrix.rb +66 -0
- data/lib/payzilla/gateways/megafon.rb +120 -0
- data/lib/payzilla/gateways/mts.rb +200 -0
- data/lib/payzilla/gateways/osmp.rb +85 -0
- data/lib/payzilla/gateways/rapida.rb +127 -0
- data/lib/payzilla/gateways/skylink.rb +105 -0
- data/lib/payzilla/gateways/webmoney.rb +102 -0
- data/lib/payzilla/gateways/yamoney.rb +93 -0
- data/lib/payzilla/gateways/yota.rb +63 -0
- data/lib/payzilla/gateways.rb +173 -0
- data/lib/payzilla/payment.rb +161 -0
- data/lib/payzilla/revision.rb +18 -0
- data/lib/payzilla/transports/http.rb +62 -0
- data/lib/payzilla/utils/string_file.rb +14 -0
- data/lib/payzilla/version.rb +3 -0
- data/lib/payzilla.rb +19 -0
- data/lib/string.rb +12 -0
- data/payzilla.gemspec +33 -0
- data/schemas/.gitkeep +0 -0
- data/schemas/beeline.wsdl +538 -0
- data/spec/lib/payzilla/gateways/akado_spec.rb +31 -0
- data/spec/lib/payzilla/gateways/beeline_spec.rb +52 -0
- data/spec/lib/payzilla/gateways/cyberplat_spec.rb +44 -0
- data/spec/lib/payzilla/gateways/gorod_spec.rb +36 -0
- data/spec/lib/payzilla/gateways/mailru_spec.rb +24 -0
- data/spec/lib/payzilla/gateways/matrix_spec.rb +35 -0
- data/spec/lib/payzilla/gateways/megafon_spec.rb +45 -0
- data/spec/lib/payzilla/gateways/mts_spec.rb +55 -0
- data/spec/lib/payzilla/gateways/osmp_spec.rb +30 -0
- data/spec/lib/payzilla/gateways/rapida_spec.rb +48 -0
- data/spec/lib/payzilla/gateways/skylink_spec.rb +39 -0
- data/spec/lib/payzilla/gateways/webmoney_spec.rb +38 -0
- data/spec/lib/payzilla/gateways/yamoney_spec.rb +31 -0
- data/spec/lib/payzilla/gateways/yota_spec.rb +30 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/config_stub.rb +7 -0
- metadata +236 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'cyberplat_pki'
|
|
4
|
+
require 'cgi'
|
|
5
|
+
|
|
6
|
+
module Payzilla
|
|
7
|
+
module Gateways
|
|
8
|
+
class Cyberplat < Gateway
|
|
9
|
+
include Payzilla::Transports::HTTP
|
|
10
|
+
|
|
11
|
+
register_settings %w(host operator point key_password dealer)
|
|
12
|
+
register_attachments %w(private_key public_key)
|
|
13
|
+
|
|
14
|
+
def check(payment)
|
|
15
|
+
result = request 'pay_check', payment.gateway_provider_id,
|
|
16
|
+
:SD => @config.setting_dealer,
|
|
17
|
+
:AP => @config.setting_point,
|
|
18
|
+
:OP => @config.setting_operator,
|
|
19
|
+
:SESSION => "c#{payment.id}",
|
|
20
|
+
:NUMBER => payment.account,
|
|
21
|
+
:ACCOUNT => payment.fields['account'],
|
|
22
|
+
:AMOUNT => 100,
|
|
23
|
+
:AMOUNT_ALL => 100
|
|
24
|
+
|
|
25
|
+
return retval(result)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def pay(payment)
|
|
29
|
+
result = request 'pay', payment.gateway_provider_id,
|
|
30
|
+
:SD => @config.setting_dealer,
|
|
31
|
+
:AP => @config.setting_point,
|
|
32
|
+
:OP => @config.setting_operator,
|
|
33
|
+
:SESSION => "p#{payment.id}",
|
|
34
|
+
:NUMBER => payment.account,
|
|
35
|
+
:ACCOUNT => payment.fields['account'],
|
|
36
|
+
:AMOUNT => payment.enrolled_amount,
|
|
37
|
+
:AMOUNT_ALL => payment.paid_amount
|
|
38
|
+
|
|
39
|
+
return retval(result)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def sign(text)
|
|
45
|
+
@private_key ||= CyberplatPKI::Key.new_private(
|
|
46
|
+
@config.attachment_private_key.read,
|
|
47
|
+
@config.setting_key_password
|
|
48
|
+
)
|
|
49
|
+
@private_key.sign(text)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def retval(code)
|
|
53
|
+
{:success => (code == "0"), :error => code}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def request(operation, provider, params)
|
|
57
|
+
if @config.setting_host.blank? ||
|
|
58
|
+
@config.setting_operator.blank? ||
|
|
59
|
+
@config.setting_point.blank? ||
|
|
60
|
+
@config.setting_key_password.blank? ||
|
|
61
|
+
@config.attachment_private_key.blank? ||
|
|
62
|
+
@config.attachment_public_key.blank?
|
|
63
|
+
return -1001
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
begin
|
|
67
|
+
data = params.collect{|k,v| "#{k}=#{v.to_s.encode('cp1251')}"}
|
|
68
|
+
data = data.join("\r\n")
|
|
69
|
+
|
|
70
|
+
provider_params = provider.split('$')
|
|
71
|
+
url_appendix = provider_params[1] ? "/#{provider_params[1]}" : ''
|
|
72
|
+
|
|
73
|
+
url = "https://#{@config.setting_host}/cgi-bin/#{provider_params[0]}/#{provider_params[0]}_pay_check.cgi#{url_appendix}"
|
|
74
|
+
data = "inputmessage=#{CGI::escape sign(data)}"
|
|
75
|
+
|
|
76
|
+
result = post url, data, :content_type => 'application/x-www-form-urlencoded'
|
|
77
|
+
|
|
78
|
+
result = result.gsub("\r", '')
|
|
79
|
+
result = result.split('BEGIN')[1]
|
|
80
|
+
result = result.split('END')[0]
|
|
81
|
+
|
|
82
|
+
logger.debug(result) unless logger.blank?
|
|
83
|
+
|
|
84
|
+
result = result.split("\n").map{|x| x.split '='}.select{|x| x[0] == 'ERROR'}.first[1]
|
|
85
|
+
|
|
86
|
+
return result
|
|
87
|
+
rescue Errno::ECONNRESET
|
|
88
|
+
return -1000
|
|
89
|
+
rescue Exception => e
|
|
90
|
+
logger.fatal e.to_s unless logger.blank?
|
|
91
|
+
return -1002
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'builder'
|
|
2
|
+
|
|
3
|
+
module Payzilla
|
|
4
|
+
module Gateways
|
|
5
|
+
class Dummy < Gateway
|
|
6
|
+
requires_revision
|
|
7
|
+
register_switches %w(allow_fails)
|
|
8
|
+
|
|
9
|
+
# Validate payment on server's side
|
|
10
|
+
#
|
|
11
|
+
# @param [Payment] payment
|
|
12
|
+
# @return [Hash] hash with error code
|
|
13
|
+
def check(payment)
|
|
14
|
+
retval
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Send payment to the carrier's server
|
|
18
|
+
#
|
|
19
|
+
# @param [Payment] payment
|
|
20
|
+
# @return [Hash] hash with error code
|
|
21
|
+
def pay(payment)
|
|
22
|
+
retval
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Generate revision
|
|
26
|
+
#
|
|
27
|
+
# @param [Revision] revision
|
|
28
|
+
# @return [Array] array with ready-to-send revision
|
|
29
|
+
def generate_revision(revision)
|
|
30
|
+
buffer = []
|
|
31
|
+
|
|
32
|
+
paginate_payments(revision.payments, buffer) do |slice, buffer|
|
|
33
|
+
buffer << generate_revision_page(slice)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
[:xml, buffer.join('')]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Send revision to the carrier's server
|
|
40
|
+
#
|
|
41
|
+
# @param [Revision] revision
|
|
42
|
+
# @param [Array] data is generated from `generate_revision` method
|
|
43
|
+
# @return [Hash] hash with error code
|
|
44
|
+
def send_revision(revision, data)
|
|
45
|
+
retval
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
# Generate revision page for revision payments pagination
|
|
51
|
+
# @param [Array] payments array of instances of Payzilla::Payment
|
|
52
|
+
# @return [String] with XML-formatted payments
|
|
53
|
+
def generate_revision_page(payments)
|
|
54
|
+
payments.to_xml(:skip_instruct => true, :root => 'slice')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Return user-friendly error code
|
|
58
|
+
#
|
|
59
|
+
# @return [Hash] hash with error code
|
|
60
|
+
def retval
|
|
61
|
+
if @config.switch_allow_fails
|
|
62
|
+
[
|
|
63
|
+
{:success => true, :error => 0},
|
|
64
|
+
{:success => false, :error => -1}
|
|
65
|
+
].sample
|
|
66
|
+
else
|
|
67
|
+
{:success => true, :error => 0}
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'builder'
|
|
4
|
+
|
|
5
|
+
module Payzilla
|
|
6
|
+
module Gateways
|
|
7
|
+
class Gorod < Gateway
|
|
8
|
+
include Payzilla::Transports::HTTP
|
|
9
|
+
|
|
10
|
+
register_settings %w(domain key_password)
|
|
11
|
+
register_attachments %w(cert key)
|
|
12
|
+
|
|
13
|
+
def check(payment)
|
|
14
|
+
return retval(-1001) if settings_miss?
|
|
15
|
+
|
|
16
|
+
begin
|
|
17
|
+
xml = Builder::XmlMarkup.new and xml.instruct!
|
|
18
|
+
|
|
19
|
+
xml.Document do
|
|
20
|
+
xml.BILLING do
|
|
21
|
+
xml.ReqAbonentList do
|
|
22
|
+
xml.AbonentsOn do
|
|
23
|
+
xml.AbonentId payment.account
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
result = request xml.target!
|
|
30
|
+
return retval(result['fault']['faultactor'])
|
|
31
|
+
rescue Errno::ECONNRESET
|
|
32
|
+
return retval(-1000)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def pay(payment)
|
|
37
|
+
return retval(-1001) if settings_miss?
|
|
38
|
+
|
|
39
|
+
begin
|
|
40
|
+
xml = Builder::XmlMarkup.new and xml.instruct!
|
|
41
|
+
|
|
42
|
+
xml.Document do
|
|
43
|
+
xml.GIN2 do
|
|
44
|
+
xml.FORM do
|
|
45
|
+
xml.Service payment.service
|
|
46
|
+
xml.Abonent do
|
|
47
|
+
xml.id payment.account
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
result = request xml.target!
|
|
54
|
+
return retval(result['fault']['faultactor'])
|
|
55
|
+
rescue Errno::ECONNRESET
|
|
56
|
+
return retval(-1000)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def retval(code)
|
|
63
|
+
{:success => (code == "0"), :error => code}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def request(xml)
|
|
67
|
+
result = post @config.setting_domain, xml,
|
|
68
|
+
ssl(
|
|
69
|
+
@config.attachment_cert,
|
|
70
|
+
@config.attachment_key,
|
|
71
|
+
@config.setting_password
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
logger.debug(dump_xml result) unless logger.blank?
|
|
75
|
+
return Crack::XML.parse(result)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
module Payzilla
|
|
4
|
+
module Gateways
|
|
5
|
+
class Mailru < Gateway
|
|
6
|
+
register_settings %w(key)
|
|
7
|
+
|
|
8
|
+
def check(payment)
|
|
9
|
+
begin
|
|
10
|
+
result = send 'user/check',
|
|
11
|
+
:rcpt => payment.account
|
|
12
|
+
|
|
13
|
+
if result == 'OK'
|
|
14
|
+
return {:success => true, :error => "0"}
|
|
15
|
+
else
|
|
16
|
+
result = result.split(':')[0].gsub('E', '').to_i
|
|
17
|
+
return {:success => false, :error => result}
|
|
18
|
+
end
|
|
19
|
+
rescue Errno::ECONNRESET
|
|
20
|
+
return retval(-1000)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def pay(payment)
|
|
25
|
+
begin
|
|
26
|
+
result = send 'payment/make',
|
|
27
|
+
:rcpt => payment.account,
|
|
28
|
+
:currency => 'RUR',
|
|
29
|
+
:sum => payment.enrolled_amount,
|
|
30
|
+
:description => Base64.encode64("Пополнение кошелька")
|
|
31
|
+
|
|
32
|
+
if result[0] == 'E'
|
|
33
|
+
result = result.split(':')[0].gsub('E', '').to_i
|
|
34
|
+
return {:success => false, :error => result}
|
|
35
|
+
else
|
|
36
|
+
return {:success => true, :gateway_payment_id => result}
|
|
37
|
+
end
|
|
38
|
+
rescue Errno::ECONNRESET
|
|
39
|
+
return retval(-1000)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def send(operation, params)
|
|
46
|
+
params[:key] = @config.setting_key
|
|
47
|
+
|
|
48
|
+
resource = RestClient::Resource.new("https://merchant.money.mail.ru/api/#{operation}")
|
|
49
|
+
result = resource.get :params => params
|
|
50
|
+
|
|
51
|
+
return result.to_s
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'crack'
|
|
4
|
+
|
|
5
|
+
module Payzilla
|
|
6
|
+
module Gateways
|
|
7
|
+
class Matrix < Gateway
|
|
8
|
+
include Payzilla::Transports::HTTP
|
|
9
|
+
|
|
10
|
+
register_settings %w(dealer_id key_password url)
|
|
11
|
+
register_attachments %w(cert key ca)
|
|
12
|
+
|
|
13
|
+
def check(payment)
|
|
14
|
+
begin
|
|
15
|
+
result = send 'process_payment',
|
|
16
|
+
:i_service_id => 2,
|
|
17
|
+
:i_phone => payment.account,
|
|
18
|
+
:i_pamount => payment.enrolled_amount,
|
|
19
|
+
:i_pdate => payment.created_at
|
|
20
|
+
|
|
21
|
+
return retval(result['ERROR']['@SQLCODE'], result['PAYMENT_ID'])
|
|
22
|
+
rescue Errno::ECONNRESET
|
|
23
|
+
return retval(-1000)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def pay(payment)
|
|
28
|
+
begin
|
|
29
|
+
result = send 'process_payment',
|
|
30
|
+
:i_transaction_id => payment.gateway_payment_id,
|
|
31
|
+
:i_receipt_num => payment.id
|
|
32
|
+
|
|
33
|
+
return retval(result['ERROR']['SQLCODE'], result['PAYMENT_ID'])
|
|
34
|
+
rescue Errno::ECONNRESET
|
|
35
|
+
return retval(-1000)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def retval(code, foreign_id=false)
|
|
42
|
+
result = {:success => (code == "0"), :error => code}
|
|
43
|
+
result[:gateway_payment_id] = foreign_id if foreign_id
|
|
44
|
+
result
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def send(operation, params)
|
|
48
|
+
params[:i_dealer_id] = @config.setting_dealer_id
|
|
49
|
+
|
|
50
|
+
resource = RestClient::Resource.new(
|
|
51
|
+
"#{@config.setting_url}#{operation}",
|
|
52
|
+
ssl(
|
|
53
|
+
@config.attachment_cert,
|
|
54
|
+
@config.attachment_key,
|
|
55
|
+
@config.setting_key_password,
|
|
56
|
+
@config.attachment_ca
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
result = resource.get :params => params
|
|
61
|
+
return Crack::XML.parse(result.to_s)['DEALER_PAYMENT']
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'crack'
|
|
4
|
+
require 'builder'
|
|
5
|
+
|
|
6
|
+
module Payzilla
|
|
7
|
+
module Gateways
|
|
8
|
+
class Megafon < Gateway
|
|
9
|
+
include Payzilla::Transports::HTTP
|
|
10
|
+
|
|
11
|
+
requires_revision
|
|
12
|
+
register_settings %w(domain client password key_password)
|
|
13
|
+
register_attachments %w(cert key ca)
|
|
14
|
+
|
|
15
|
+
def check(payment)
|
|
16
|
+
result = request 'HTTP_ADD_PAYMENT', :get,
|
|
17
|
+
:P_MSISDN => payment.account
|
|
18
|
+
|
|
19
|
+
return retval(result)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def pay(payment)
|
|
23
|
+
begin
|
|
24
|
+
result = request 'HTTP_ADD_PAYMENT', :get,
|
|
25
|
+
:P_MSISDN => payment.account,
|
|
26
|
+
:P_PAY_AMOUNT => payment.enrolled_amount,
|
|
27
|
+
:P_RECEIPT_NUM => payment.id
|
|
28
|
+
ensure
|
|
29
|
+
pay(payment) if result == "100"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
return retval(result)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def generate_revision(revision)
|
|
36
|
+
builder = Builder::XmlMarkup.new
|
|
37
|
+
count = 0
|
|
38
|
+
sum = 0
|
|
39
|
+
|
|
40
|
+
builder.instruct! :xml, version: "1.0", encoding: "WINDOWS-1251"
|
|
41
|
+
data = builder.reestr do
|
|
42
|
+
totals = paginate_payments(revision.payments, builder) do |slice, builder|
|
|
43
|
+
generate_revision_page(slice, builder)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
builder.pay_sum totals[:enrolled_sum]
|
|
47
|
+
builder.pay_count totals[:count]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
[:xml, data]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def send_revision(revision, data)
|
|
54
|
+
result = request 'HTTP_LOAD_REESTR', :post,
|
|
55
|
+
:LOGIN => @config.setting_client,
|
|
56
|
+
:PASSWORD => @config.setting_password,
|
|
57
|
+
:P_DATE => revision.date.strftime('%d.%m.%Y'),
|
|
58
|
+
:FILE_DATA => Payzilla::Utils::StringFile.new('data.xml', data)
|
|
59
|
+
return retval(result)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def check_revision(revision)
|
|
63
|
+
result = request 'HTTP_GET_REESTR_STATUS', :get,
|
|
64
|
+
:LOGIN => @config.setting_client,
|
|
65
|
+
:PASSWORD => @config.setting_password,
|
|
66
|
+
:P_DATE => revision.date.strftime('%d.%m.%Y')
|
|
67
|
+
return retval(result)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def generate_revision_page(payments, builder)
|
|
73
|
+
payments.each do |p|
|
|
74
|
+
builder.r do
|
|
75
|
+
builder.m p.account
|
|
76
|
+
builder.s p.enrolled_amount
|
|
77
|
+
builder.n p.id
|
|
78
|
+
builder.d p.created_at.strftime("%d.%m.%Y %H:%M:%S")
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def retval(code)
|
|
84
|
+
{:success => (code == "0"), :error => code}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def request(operation, method, params)
|
|
88
|
+
begin
|
|
89
|
+
if @config.setting_client.blank? ||
|
|
90
|
+
@config.setting_password.blank? ||
|
|
91
|
+
@config.attachment_cert.blank? ||
|
|
92
|
+
@config.attachment_key.blank?
|
|
93
|
+
return -1001
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
params = {
|
|
97
|
+
:P_LOGIN_NAME => @config.setting_client,
|
|
98
|
+
:P_LOGIN_PASSWD => @config.setting_password,
|
|
99
|
+
}.merge(params)
|
|
100
|
+
|
|
101
|
+
result = send method, "https://#{@config.setting_domain}/PAYS/#{operation}", params,
|
|
102
|
+
ssl(
|
|
103
|
+
@config.attachment_cert,
|
|
104
|
+
@config.attachment_key,
|
|
105
|
+
@config.attachment_ca
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
logger.debug(dump_xml result) unless logger.blank?
|
|
109
|
+
return Crack::XML.parse(result)['KKM_PG_GATE']['ERROR']['SQLCODE']
|
|
110
|
+
rescue Errno::ECONNRESET
|
|
111
|
+
return -1000
|
|
112
|
+
rescue Exception => e
|
|
113
|
+
logger.fatal e unless logger.blank?
|
|
114
|
+
return -1002
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
require 'crack'
|
|
2
|
+
require 'digest/md5'
|
|
3
|
+
require 'base64'
|
|
4
|
+
|
|
5
|
+
module Payzilla
|
|
6
|
+
module Gateways
|
|
7
|
+
class Mts < Gateway
|
|
8
|
+
include Payzilla::Transports::HTTP
|
|
9
|
+
|
|
10
|
+
requires_revision
|
|
11
|
+
register_settings %w(url agent contract key_password signature_key_password terminal_prefix)
|
|
12
|
+
register_attachments %w(cert key ca signature_key)
|
|
13
|
+
|
|
14
|
+
def check(payment)
|
|
15
|
+
return retval(-1001) if settings_miss?
|
|
16
|
+
|
|
17
|
+
begin
|
|
18
|
+
xml = Builder::XmlMarkup.new
|
|
19
|
+
|
|
20
|
+
xml.f_01(payment.account, :"xsi:type" => 'espp-constraints:PHN_CODE_fmt_01')
|
|
21
|
+
xml.f_02("%.2f" % payment.enrolled_amount)
|
|
22
|
+
xml.f_03(810, :"xsi:type" => 'espp-constraints:CUR_fmt_01')
|
|
23
|
+
xml.f_04(7)
|
|
24
|
+
xml.f_05(terminal(payment))
|
|
25
|
+
xml.f_06(1)
|
|
26
|
+
xml.f_07(@config.setting_agent)
|
|
27
|
+
xml.f_08(@config.setting_contract)
|
|
28
|
+
xml.f_10(payment.gateway_provider_id)
|
|
29
|
+
|
|
30
|
+
result = request 'ESPP_0104010', xml.target!
|
|
31
|
+
|
|
32
|
+
if !result['ESPP_1204010'].blank?
|
|
33
|
+
return retval(0, result['ESPP_1204010']['f_05'])
|
|
34
|
+
else
|
|
35
|
+
return retval(result['ESPP_2204010']['f_01'])
|
|
36
|
+
end
|
|
37
|
+
rescue Errno::ECONNRESET
|
|
38
|
+
return retval(-1000)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def pay(payment)
|
|
43
|
+
return retval(-1001) if settings_miss?
|
|
44
|
+
|
|
45
|
+
begin
|
|
46
|
+
xml = Builder::XmlMarkup.new
|
|
47
|
+
|
|
48
|
+
signature = [
|
|
49
|
+
"#{payment.account}",
|
|
50
|
+
"%.2f" % payment.enrolled_amount,
|
|
51
|
+
810,
|
|
52
|
+
7,
|
|
53
|
+
"",
|
|
54
|
+
payment.id,
|
|
55
|
+
payment.created_at.strftime("%Y-%m-%dT%H:%M:%S"),
|
|
56
|
+
@config.setting_agent,
|
|
57
|
+
terminal(payment),
|
|
58
|
+
1,
|
|
59
|
+
payment.created_at.to_s,
|
|
60
|
+
"",
|
|
61
|
+
"MTS"
|
|
62
|
+
].join('&')
|
|
63
|
+
|
|
64
|
+
encryptor = OpenSSL::PKey::RSA.new(
|
|
65
|
+
File.open(@config.attachment_signature_key.path).read,
|
|
66
|
+
@config.setting_signature_key_password
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
signature = encryptor.sign(OpenSSL::Digest::MD5.new, signature)
|
|
70
|
+
signature = Base64.encode64(signature.force_encoding('UTF-8'))
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
xml.f_01(payment.account, :"xsi:type" => 'espp-constraints:PHN_CODE_fmt_01')
|
|
74
|
+
xml.f_02("%.2f" % payment.enrolled_amount)
|
|
75
|
+
xml.f_03(810, :"xsi:type" => 'espp-constraints:CUR_fmt_01')
|
|
76
|
+
xml.f_04(7)
|
|
77
|
+
xml.f_06(0)
|
|
78
|
+
xml.f_07(payment.id)
|
|
79
|
+
xml.f_08(payment.created_at.strftime("%Y-%m-%dT%H:%M:%S"))
|
|
80
|
+
xml.f_10(payment.gateway_payment_id)
|
|
81
|
+
xml.f_11(@config.setting_agent)
|
|
82
|
+
xml.f_12(terminal(payment))
|
|
83
|
+
xml.f_13(1)
|
|
84
|
+
xml.f_15("138020")
|
|
85
|
+
xml.f_16(payment.created_at.to_s)
|
|
86
|
+
xml.f_18(signature)
|
|
87
|
+
xml.f_19(@config.setting_contract)
|
|
88
|
+
xml.f_21(payment.gateway_provider_id)
|
|
89
|
+
result = request 'ESPP_0104090', xml.target!
|
|
90
|
+
|
|
91
|
+
if !result['ESPP_1204090'].blank?
|
|
92
|
+
return retval
|
|
93
|
+
else
|
|
94
|
+
return retval(result['ESPP_2204090']['f_01'])
|
|
95
|
+
end
|
|
96
|
+
rescue Errno::ECONNRESET
|
|
97
|
+
return retval(-1000)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def generate_revision(revision)
|
|
102
|
+
xml = Builder::XmlMarkup.new
|
|
103
|
+
|
|
104
|
+
xml.summary do
|
|
105
|
+
xml.contract @config.setting_contract
|
|
106
|
+
xml.comparePeriod do
|
|
107
|
+
xml.from revision.date.to_date.to_datetime
|
|
108
|
+
xml.to DateTime.new(
|
|
109
|
+
revision.date.year,
|
|
110
|
+
revision.date.month,
|
|
111
|
+
revision.date.day,
|
|
112
|
+
23,
|
|
113
|
+
59,
|
|
114
|
+
59
|
|
115
|
+
)
|
|
116
|
+
end
|
|
117
|
+
xml.totalAmountOfPayments revision.payments.count
|
|
118
|
+
xml.currency(810, :"xsi:type" => 'espp-constraints:CUR_fmt_01')
|
|
119
|
+
xml.totalSum revision.payments.map{|x| x.enrolled_amount}.inject(:+)
|
|
120
|
+
xml.totalDebt 0
|
|
121
|
+
end
|
|
122
|
+
xml.payments do
|
|
123
|
+
revision.payments.each_with_index do |p,i|
|
|
124
|
+
row = [
|
|
125
|
+
@config.setting_agent,
|
|
126
|
+
p.gateway_payment_id,
|
|
127
|
+
p.created_at,
|
|
128
|
+
p.id,
|
|
129
|
+
p.terminal_id,
|
|
130
|
+
p.account,
|
|
131
|
+
'',
|
|
132
|
+
'',
|
|
133
|
+
"%.2f" % p.enrolled_amount,
|
|
134
|
+
810,
|
|
135
|
+
1,
|
|
136
|
+
0
|
|
137
|
+
].join(';')
|
|
138
|
+
|
|
139
|
+
xml.p(row, :id => i+1)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
[:xml, wrap_xml('comparePacket', xml, revision.id)]
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
private
|
|
147
|
+
|
|
148
|
+
def terminal(payment)
|
|
149
|
+
"#{@config.setting_terminal_prefix[0..10].rjust(11, '0')}.#{payment.terminal_id}"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def settings_miss?
|
|
153
|
+
@config.setting_terminal_prefix.blank? ||
|
|
154
|
+
@config.attachment_cert.blank? ||
|
|
155
|
+
@config.attachment_key.blank? ||
|
|
156
|
+
@config.attachment_signature_key.blank? ||
|
|
157
|
+
@config.setting_url.blank? ||
|
|
158
|
+
@config.setting_agent.blank? ||
|
|
159
|
+
@config.setting_contract.blank?
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def retval(code=0, payment_id=false)
|
|
163
|
+
result = {:success => (code.to_s == "0"), :error => code}
|
|
164
|
+
result[:gateway_payment_id] = payment_id unless payment_id.blank?
|
|
165
|
+
|
|
166
|
+
result
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def wrap_xml(operation, xml, operation_id='')
|
|
170
|
+
operation_id = "id='#{operation_id}'" unless operation_id.blank?
|
|
171
|
+
|
|
172
|
+
return <<-XML
|
|
173
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
|
174
|
+
<#{operation}
|
|
175
|
+
#{operation_id}
|
|
176
|
+
xmlns="http://schema.mts.ru/ESPP/AgentPayments/Protocol/Messages/v5_01"
|
|
177
|
+
xmlns:espp-constraints="http://schema.mts.ru/ESPP/Core/Constraints/v5_01"
|
|
178
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
179
|
+
xsi:schemaLocation="http://schema.mts.ru/ESPP/AgentPayments/Protocol/Messages/v5_01 ESPP_AgentPayments_Protocol_Messages_v5_01.xsd http://schema.mts.ru/ESPP/Core/Constraints/v5_01 ESPP_Core_Constraints_v5_01.xsd" #{"a_01 = \"60\"" if operation == "ESPP_0104010"}>
|
|
180
|
+
#{xml}
|
|
181
|
+
</#{operation}>
|
|
182
|
+
XML
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def request(operation, xml)
|
|
186
|
+
result = post @config.setting_url, wrap_xml(operation, xml),
|
|
187
|
+
ssl(
|
|
188
|
+
@config.attachment_cert,
|
|
189
|
+
@config.attachment_key,
|
|
190
|
+
@config.setting_key_password,
|
|
191
|
+
@config.attachment_ca
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
logger.debug(dump_xml result) unless logger.blank?
|
|
195
|
+
return Crack::XML.parse(result)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|