-
Notifications
You must be signed in to change notification settings - Fork 19
/
notification.rb
146 lines (129 loc) · 4.36 KB
/
notification.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# encoding: utf-8
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
module Integrations #:nodoc:
module Sermepa
class Notification < ActiveMerchant::Billing::Integrations::Notification
include PostsData
def complete?
status == 'Completed'
end
def transaction_id
params['ds_order']
end
# When was this payment received by the client.
def received_at
if params['ds_date']
(day, month, year) = params['ds_date'].split('/')
Time.parse("#{year}-#{month}-#{day} #{params['ds_hour']}")
else
Time.now # Not provided!
end
end
# the money amount we received in cents in X.2 format
def gross
sprintf("%.2f", params['ds_amount'].to_f / 100)
end
# Was this a test transaction?
def test?
false
end
def currency
Sermepa.currency_from_code( params['ds_currency'] )
end
# Status of transaction. List of possible values:
# <tt>Completed</tt>
# <tt>Failed</tt>
# <tt>Pending</tt>
def status
case error_code.to_i
when 0..99
'Completed'
when 900
'Pending'
else
'Failed'
end
end
def error_code
params['ds_response']
end
def error_message
msg = Sermepa.response_code_message(error_code)
error_code.to_s + ' - ' + (msg.nil? ? 'Operación Aceptada' : msg)
end
def secure_payment?
params['ds_securepayment'] == '1'
end
# Acknowledge the transaction.
#
# Validate the details provided by the gateway by ensuring that the signature
# matches up with the details provided.
#
# Optionally, a set of credentials can be provided that should contain a
# :secret_key instead of using the global credentials defined in the Sermepa::Helper.
#
# Example:
#
# def notify
# notify = Sermepa::Notification.new(request.query_parameters)
#
# if notify.acknowledge
# ... process order ... if notify.complete?
# else
# ... log possible hacking attempt ...
# end
#
#
def acknowledge(credentials = nil)
return false if params['ds_signature'].blank?
str =
params['ds_amount'].to_s +
params['ds_order'].to_s +
params['ds_merchantcode'].to_s +
params['ds_currency'].to_s +
params['ds_response'].to_s
if xml?
str += params['ds_transactiontype'].to_s + params['ds_securepayment'].to_s
end
str += (credentials || Sermepa::Helper.credentials)[:secret_key]
sig = Digest::SHA1.hexdigest(str)
sig.upcase == params['ds_signature'].to_s.upcase
end
private
def xml?
!params['code'].blank?
end
# Take the posted data and try to extract the parameters.
#
# Posted data can either be a parameters hash, XML string or CGI data string
# of parameters.
#
def parse(post)
if post.is_a?(Hash)
post.each { |key, value| params[key.downcase] = value }
elsif post.to_s =~ /<retornoxml>/i
# XML source
self.params = xml_response_to_hash(@raw)
else
for line in post.to_s.split('&')
key, value = *line.scan( %r{^([A-Za-z0-9_.]+)\=(.*)$} ).flatten
params[key.downcase] = CGI.unescape(value)
end
end
@raw = post.inspect.to_s
end
def xml_response_to_hash(xml)
result = { }
doc = Nokogiri::XML(xml)
doc.css('RETORNOXML OPERACION').children().each do |child|
result[child.name.downcase] = child.inner_text
end
result['code'] = doc.css('RETORNOXML CODIGO').inner_text
result
end
end
end
end
end
end