croipg 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/croipg.rb +1 -0
  2. data/lib/web_teh_xml.rb +340 -0
  3. metadata +78 -0
data/lib/croipg.rb ADDED
@@ -0,0 +1 @@
1
+ require "web_teh_xml.rb"
@@ -0,0 +1,340 @@
1
+ # endcoding: utf-8
2
+
3
+ require "activemerchant"
4
+
5
+ module ActiveMerchant #:nodoc:
6
+ module Billing #:nodoc:
7
+ class WebTehXmlGateway < Gateway
8
+ self.test_url = 'https://ipgtest.webteh.hr'
9
+
10
+ # TODO: replace with production value
11
+ self.live_url = 'https://live.webteh.hr'
12
+
13
+ # The countries the gateway supports merchants from as 2 digit ISO country codes
14
+ self.supported_countries = ['HR']
15
+
16
+ # The card types supported by the payment gateway
17
+ self.supported_cardtypes = [ :american_express, :diners_club, :maestro, :master, :visa ]
18
+
19
+ # The homepage URL of the gateway
20
+ self.homepage_url = 'http://www.webteh.hr/'
21
+
22
+ # The name of the gateway
23
+ self.display_name = 'WebPay'
24
+
25
+ # Default currency
26
+ self.default_currency = 'HRK'
27
+
28
+ # Constants
29
+ REQUEST_APPROVED = "approved"
30
+
31
+ RESPONSE_TYPE = {
32
+ :secure_3d => "secure-message",
33
+ :error => "errors"
34
+ }
35
+
36
+ # ActiveMerchant::PostsData::ssl_strict
37
+ self.ssl_strict = false
38
+
39
+ # TODO: process response code in response message from authentification/purchase
40
+
41
+ def initialize(options = {})
42
+ requires!(options, :login, :password, :key, :auth_token)
43
+ @key = options[ :key ]
44
+ @auth_token = options[ :auth_token ]
45
+
46
+ super
47
+ end
48
+
49
+ def authorize(money, creditcard, options = {})
50
+ return transfer_funds( money, creditcard, options, "authorize" )
51
+ end
52
+
53
+ def purchase(money, creditcard, options = {})
54
+ return transfer_funds( money, creditcard, options, "purchase" )
55
+ end
56
+
57
+ def capture(money, authorization, options = {})
58
+ return settle_transfer( money, authorization, options, "capture" )
59
+ end
60
+
61
+ def refund(money, authorization, options = {})
62
+ return settle_transfer( money, authorization, options, "refund" )
63
+ end
64
+
65
+ def void(money, authorization, options = {})
66
+ return settle_transfer( money, authorization, options, "void" )
67
+ end
68
+
69
+ def complete_3ds( md, pares )
70
+ xml = generate_3ds_complete_request( md, pares )
71
+
72
+ return commit( "pares", xml )
73
+ end
74
+
75
+ private
76
+
77
+ def transfer_funds( money, credit_card, options, action )
78
+ params = normalize_params( money, credit_card, options )
79
+ params[ :transaction_type ] = action
80
+
81
+ xml = generate_auth_request( params )
82
+
83
+ return commit('api', money, xml)
84
+ end
85
+
86
+ # |
87
+ # |--- money
88
+ # |--- authorization
89
+ # |--- options
90
+ # | |--- currency
91
+ def settle_transfer( money, authorization, options, action )
92
+ requires!( options, :currency )
93
+
94
+ # TODO: xml generation not implemented
95
+ xml = generate_settle_request( money, authorization, options[ :currency ] )
96
+
97
+ path = "transactions/#{authorization}/#{action}.xml"
98
+
99
+ commit( path, money, xml )
100
+ end
101
+
102
+ #**********************
103
+ # * XML docs *
104
+ # ***********
105
+ def generate_auth_request( params )
106
+ xml_out = ""
107
+ xml = Builder::XmlMarkup.new( :target => xml_out)
108
+
109
+ xml.instruct!( :xml, :version => "1.0", :encoding => "UTF-8" )
110
+ xml.transaction() do |transaction|
111
+ add_invoice( transaction, params )
112
+ end
113
+
114
+ return xml_out
115
+ end
116
+
117
+ def add_customer_data( parent, params )
118
+ parent.tag!( "ch-email", params[ :options ][ :email ] )
119
+ parent.tag!( "ch-full-name", full_name( params[ :credit_card ] ) )
120
+ parent.tag!( "ch-phone", params[ :options ][ :address ][ :phone ] )
121
+ end
122
+
123
+ def add_address( parent, params )
124
+ address = params[ :options ][ :address ]
125
+
126
+ parent.tag!( "ch-address", replace_diacritics( address[ :address1 ] ) )
127
+ parent.tag!( "ch-city", replace_diacritics( address[ :city ] ) )
128
+ parent.tag!( "ch-country", replace_diacritics( address[ :country ] ) )
129
+ add_customer_data( parent, params )
130
+ parent.tag!( "ch-zip", params[ :options ][ :address ][ :zip ] )
131
+ end
132
+
133
+ def add_invoice(parent, params)
134
+ signature_values = [
135
+ @key,
136
+ params[ :options ][ :order_id ],
137
+ params[ :amount ],
138
+ params[ :options ][ :currency ]
139
+ ]
140
+
141
+ parent.tag!( "transaction-type", params[ :transaction_type ] )
142
+ parent.tag!( "amount", params[ :amount ] )
143
+ add_creditcard( parent, params )
144
+ parent.tag!( "ip", params[ :options ][ :ip ] )
145
+ parent.tag!( "order-info", replace_diacritics( params[ :options ][ :description ] ) )
146
+ add_address( parent, params )
147
+ parent.tag!( "currency", params[ :options ][ :currency ] )
148
+ parent.tag!( "digest", generate_signature( signature_values ) )
149
+ parent.tag!( "authenticity-token", @auth_token )
150
+ parent.tag!( "order-number", params[ :options ][ :order_id ] )
151
+ # TODO: language is not regular param in active merchant
152
+ parent.tag!( "language", "hr" )
153
+ end
154
+
155
+ def add_creditcard( parent, params )
156
+ credit_card = params[ :credit_card ]
157
+ parent.tag!( "expiration-date", format_expiry_date( credit_card ) )
158
+ parent.tag!( "cvv", credit_card.verification_value )
159
+ parent.tag!( "pan", credit_card.number )
160
+ end
161
+
162
+ def generate_settle_request( amount, authorization, currency )
163
+ xml_out = ""
164
+ xml = Builder::XmlMarkup.new( :target => xml_out )
165
+
166
+ signature_values = [ @key, authorization, amount, currency ]
167
+
168
+ xml.instruct!( :xml, :version => "1.0", :encoding => "UTF-8" )
169
+ xml.transaction() do |transaction|
170
+ xml.tag!( "amount", amount )
171
+ xml.tag!( "currency", currency )
172
+ xml.tag!( "digest", generate_signature( signature_values ) )
173
+ xml.tag!( "authenticity-token", @auth_token )
174
+ xml.tag!( "order-number", authorization )
175
+ end
176
+
177
+ return xml_out
178
+ end
179
+
180
+ def generate_3ds_complete_request( md, pares )
181
+ xml_out = ""
182
+
183
+ xml = Builder::XmlMarkup.new( :target => xml_out, :indent=> 2, :margin=> 4 )
184
+
185
+ xml.instruct!( :xml, :version => "1.0", :encoding => "UTF-8" )
186
+ xml.tag!( "secure-message" ) do |secure_message|
187
+ secure_message.tag!( "MD", md )
188
+ secure_message.tag!( "PaRes", pares )
189
+ end
190
+
191
+ return xml_out
192
+ end
193
+
194
+ def parse(body)
195
+ data = {}
196
+ xml = REXML::Document.new( body )
197
+
198
+ data[ "response-type" ] = xml.root().name
199
+
200
+ processed_nodes = {}
201
+ xml.root().elements.each() do |node|
202
+ if processed_nodes.has_key?( node.name )
203
+ processed_nodes[ node.name ] += 1
204
+ else
205
+ processed_nodes[ node.name ] = 0
206
+ end
207
+ node_repetition = processed_nodes[ node.name ]
208
+ node_name = node.name + ( node_repetition == 0 ? "" : node_repetition.to_s() )
209
+ data[ node_name ] = node.text
210
+ end
211
+ return data
212
+ end
213
+
214
+ def commit(action, money, xml)
215
+ url = "#{self.test_url}/#{action}"
216
+
217
+ begin
218
+ response_body = ssl_post( url, xml, { "Content-Type" => "application/xml" } )
219
+ rescue ActiveMerchant::ResponseError => error
220
+ response_body = error.response.body
221
+ end
222
+ response_data = parse( response_body )
223
+
224
+ return process_response_data( response_data )
225
+ end
226
+
227
+ def process_response_data( response_data )
228
+ # Authentification/Purchase response
229
+ if response_data[ "status" ]
230
+ return Response.new(
231
+ response_data[ "status" ] == REQUEST_APPROVED,
232
+ response_data[ "response-message" ],
233
+ response_data
234
+ )
235
+ # 3D Secure/Error
236
+ else
237
+ # 3D Secure
238
+ if response_data[ "response-type" ] == RESPONSE_TYPE[ :secure_3d ]
239
+ return Response.new(
240
+ false,
241
+ "3D secure enabled card. Additional authentication needed",
242
+ response_data
243
+ )
244
+ # Error
245
+ else
246
+ return Response.new(
247
+ false,
248
+ "Errors",
249
+ response_data
250
+ )
251
+ end
252
+ end
253
+ end
254
+
255
+ def message_from(response)
256
+ end
257
+
258
+ def post_data(action, parameters = {})
259
+ end
260
+
261
+ # module WebTehCommons
262
+
263
+ CRO_DIACRITICS_MAP = {
264
+ [ 'Š' ] => 'S',
265
+ [ 'š' ] => 's',
266
+ [ 'Č', 'Ć' ] => 'C',
267
+ [ 'č', 'ć' ] => 'c',
268
+ [ 'Ž' ] => 'Z',
269
+ [ 'ž' ] => 'z',
270
+ [ 'Đ' ] => 'D',
271
+ [ 'đ' ] => 'd'
272
+ }
273
+
274
+ def replace_diacritics( input )
275
+ clear_text = input
276
+
277
+ CRO_DIACRITICS_MAP.each() do |diacritics, letter|
278
+ diacritics.each() do |diacritic|
279
+ clear_text = clear_text.gsub( diacritic, letter )
280
+ end
281
+ end
282
+
283
+ return clear_text
284
+ end
285
+
286
+ def generate_signature( values )
287
+ text = ""
288
+ values.each() { |value| text += "#{value}" }
289
+
290
+ signature = Digest::SHA1.hexdigest( text )
291
+ return signature
292
+ end
293
+
294
+ def format_expiry_date( credit_card )
295
+ return format( credit_card.year, :two_digits ) + format( credit_card.month, :two_digits )
296
+ end
297
+
298
+ def full_name( credit_card )
299
+ return replace_diacritics( credit_card.name )
300
+ end
301
+
302
+ =begin
303
+ params
304
+ |--- amount
305
+ |--- ? transaction_type => { authorize | purchase} sets invoked method
306
+ |--- credit_card
307
+ | |--- first_name
308
+ | |--- last_name
309
+ | |--- number
310
+ | |--- year
311
+ | |--- month
312
+ | |--- verification_value
313
+ |
314
+ |--- options
315
+ | |--- order_id
316
+ | |--- description
317
+ | |--- currency
318
+ | |--- email
319
+ | |--- ip
320
+ | |--- address
321
+ | | |--- address1
322
+ | | |--- city
323
+ | | |--- country
324
+ | | |--- zip
325
+ | | |--- phone
326
+ =end
327
+ def normalize_params( amount, credit_card, options )
328
+ requires!( options, :order_id, :description, :currency, :email, :ip, :address )
329
+ requires!( options[ :address ], :address1, :city, :country, :zip, :phone )
330
+ params = {
331
+ :amount => amount,
332
+ :credit_card => credit_card,
333
+ :options => options
334
+ }
335
+
336
+ return params
337
+ end
338
+ end
339
+ end
340
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: croipg
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ja Vrabac
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activemerchant
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.29'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.29'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activemerchant
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.29'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.29'
46
+ description: Support for cro IPG's
47
+ email: ja@vrabac.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - lib/croipg.rb
53
+ - lib/web_teh_xml.rb
54
+ homepage: http://www.example.com
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.25
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Cro ActiveMerchant IPG
78
+ test_files: []