ideal 0.2.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/.kick ADDED
@@ -0,0 +1,5 @@
1
+ recipe :ignore
2
+
3
+ ignore(/^(pkg)/)
4
+
5
+ recipe :ruby
@@ -1,19 +1,8 @@
1
- h1. Active_merchant_ideal
1
+ h1. iDEAL
2
2
 
3
3
  "!https://secure.travis-ci.org/Fingertips/Ideal.png!":http://travis-ci.org/Fingertips/Ideal
4
4
 
5
- h2. ATTENTION: transition period with a new certificate (ING only)
6
-
7
- Recently ING issued a new iDEAL certificate, which should be in production before May 23 2011. See "Wijzigen van een acquiring certificaat in
8
- iDEAL Advanced":http://www.ing.nl/Images/Wijzigen_van_een_acquiring_certificaat_in_iDEAL_Advanced_internet_tcm7-82882.pdf. However ING is not able to say exactly when this migration will take place. This means there will be a transition period in which it's uncertain which iDEAL certificate is needed.
9
-
10
- Luckily Roel van Dijk (Voormedia BV) has written a gem/patch, so you can use the old and the new certificate during this transition period.
11
-
12
- See "active_merchant_ideal_multicert":https://github.com/rdvdijk/active_merchant_ideal_multicert
13
-
14
- h2. Description:
15
-
16
- "iDEAL":http://www.ideal.nl payment gateway for "ActiveMerchant":http://www.activemerchant.org.
5
+ Library for the "iDEAL":http://www.ideal.nl payment standard.
17
6
 
18
7
  h2. What is iDEAL?
19
8
 
@@ -33,172 +22,223 @@ In order to use iDEAL you will need to get an iDEAL merchant account from your b
33
22
  * Rabobank: Rabo iDEAL Professional. (Unverified)
34
23
  * SNS Bank: "Not yet available":http://www.snsbank.nl/zakelijk/betalingsverkeer/kan-ik-ideal-gebruiken-voor-mijn-webwinkel.html
35
24
 
36
- If you implement tests for other banks, if they require such acceptance tests, please do submit a patch or contact me directly: frank@dovadi.com.
25
+ h2. Install
37
26
 
38
- h2. Install active_merchant_ideal:
27
+ The iDEAL gem does not have any large external dependencies. It depends on Nap (a small HTTP library) and Builder (for building XML files). Because of these minor dependencies it's suited to use in Ruby projects other than Ruby on Rails.
39
28
 
40
- As a gem:
29
+ The easiest way to install is as a gem.
41
30
 
42
- <pre>
43
- sudo gem install active_merchant_ideal
44
- </pre>
31
+ <pre><code>sudo gem install ideal</code></pre>
45
32
 
46
- Add the following to your Gemfile:
33
+ Or you can add it as a dependency in your Gemfile.
47
34
 
48
- <pre>
49
- gem 'active_merchant_ideal'
50
- </pre>
35
+ <pre><code>gem 'ideal'</code></pre>
51
36
 
52
- As a plugin:
53
- <pre>
54
- ./script/plugin install git://github.com/dovadi/active_merchant_ideal.git
55
- </pre>
37
+ Finally, if you don't dig any of that gemming that's so popular nowadays, you can install it as a plugin;
56
38
 
57
- h2. Generate private keys and certificates
39
+ <pre><code>cd vendor/plugins
40
+ git clone --depth 1 git://github.com/Fingertips/Ideal.git ideal</code></pre>
58
41
 
59
- Messages to, and from, the acquirer, are all signed in order to prove their authenticity. This means that you will have to have a certificate to sign your messages going to the acquirer _and_ you will need to have the certificate of the acquirer to verify its signed messages.
42
+ h2. Generate private keys and certificates
60
43
 
61
- The latter can be downloaded from your acquirer after registration. The former, however, can be a certificate signed by a CA authority or a self-signed certificate.
44
+ Messages between you and the acquirer are all signed in order to prove their authenticity. You will need a certificate for your side, this can be self-issued. If you like spending money, you can buy a certificate from some SSL authority. The certificate of the acquirer is probably hidden somewhere in plain sight in their documentation.
62
45
 
63
46
  To create a self-signed certificate follow these steps:
64
47
 
65
48
  * /usr/bin/openssl genrsa -des3 -out private_key.pem -passout pass:the_passphrase 1024
66
49
  * /usr/bin/openssl req -x509 -new -key private_key.pem -passin pass:the_passphrase -days 3650 -out private_certificate.cer
67
50
 
68
- Substitute _the_passphrase__ with your own passphrase.
51
+ Substitute _the_passphrase_ with your own passphrase. You will need to configure that passphrase later on, so hand on to it.
69
52
 
70
- With the ING bank you upload your private certificate with your iDEAL Dashboard. Be aware that there are two dashboards, one "dashboard":https://idealtest.secure-ing.com/ideal/logon_ing.do for the test environment and one "dashboard":https://ideal.secure-ing.com/ideal/logon_ing.do for the production environment!
53
+ You will need to upload your public key (certificate) to your iDEAL dashboard. Usually they have a completely independent test and live environment so you _can_ use different certificates for both.
71
54
 
72
- For more information see:
55
+ For more information on certificates and encryption see:
73
56
  * "http://en.wikipedia.org/wiki/Certificate_authority":http://en.wikipedia.org/wiki/Certificate_authority
74
57
  * "http://en.wikipedia.org/wiki/Self-signed_certificate":http://en.wikipedia.org/wiki/Self-signed_certificate
75
58
 
76
- h2. Test
59
+ h2. Test and activation
77
60
 
78
- h3. Test the gem
61
+ Once you've uploaded the certificate you need to initiate a number of transactions to complete the activation process. Luckily these transactions are part of the remote test for the gem. It's still kind of a pain, but here we go!
79
62
 
80
- You can run the tests from this gem with (inside the active_merchant_ideal directory):
63
+ <pre><code>git clone --depth 1 git://github.com/Fingertips/Ideal.git ideal
64
+ cd ideal
65
+ bundle install</code></pre>
81
66
 
82
- <pre>
83
- bundle install
84
- bundle exec rake test
85
- </pre>
67
+ * Create the <code>~/.ideal</code> directory.
68
+ * Copy <code>test/fixtures.yml</code> to <code>~/.ideal</code>.
69
+ * Fill in your own merchant id, passphrase and the correct locations to your private key and certificates.
86
70
 
87
- h3. Run the remote tests (For ING BANK and Rabobank only)
71
+ <pre><code>ruby test/remote_test.rb</code></pre>
88
72
 
89
- * Create .active_merchant directory in your own home directory
90
- * Copy test/fixtures.yml to the .active_merchant directory
91
- * Fill in your own merchant id, passphrase and the correct locations to your private key and certificates.
92
- * For running the *seven prescribed remote test transactions* (ING bank and Rabobank) which are needed to activate the iDEAL account use
73
+ If you've succeeded you will see the following:
93
74
 
94
- <pre>
95
- bundle exec rake test:remote
96
- </pre>
75
+ <pre><code>ruby test/remote_test.rb
76
+ Loaded suite test/remote_test
77
+ Started
78
+ ...........
79
+ Finished in 9.768389 seconds.
97
80
 
98
- h3. Compatibility
81
+ 11 tests, 33 assertions, 0 failures, 0 errors</code></pre>
99
82
 
100
- Active_merchant_ideal is tested with Ruby 1.8.7 and 1.9.2.
83
+ If you see test errors, you're on your own (; You can run the test in debug mode to check what's sent across the wire.
101
84
 
102
- h2. Example (Rails)
85
+ <pre><code>ruby -d test/remote_test.rb </code></pre>
103
86
 
104
- h3. First configure the gateway
87
+ h2. Dashboards
105
88
 
106
- Put the following code in, for instance, an initializer:
89
+ h3. ING
90
+
91
+ * "Test dashboard":https://idealtest.secure-ing.com/ideal/logon_ing.do
92
+ * "Live dashboard":https://ideal.secure-ing.com/ideal/logon_ing.do
107
93
 
108
- <pre>
109
- ActiveMerchant::Billing::IdealGateway.acquirer = :ing # Other banks preloaded are :abnamro and :rabobank
110
- ActiveMerchant::Billing::IdealGateway.merchant_id = '00123456789'
111
- ActiveMerchant::Billing::IdealGateway.passphrase = 'the_private_key_passphrase'
112
-
113
- # CERTIFICATE_ROOT points to a directory where the key and certificates are located
114
- ActiveMerchant::Billing::IdealGateway.private_key_file = File.join(CERTIFICATE_ROOT, 'private_key.pem')
115
- ActiveMerchant::Billing::IdealGateway.private_certificate_file = File.join(CERTIFICATE_ROOT, 'private_certificate.cer')
116
- ActiveMerchant::Billing::IdealGateway.ideal_certificate_file = File.join(CERTIFICATE_ROOT, 'ideal.cer')
117
- </pre>
94
+ h3. ABN AMRO
118
95
 
119
- h3. View
96
+ * "Test dashboard":https://abnamro-test.ideal-payment.de/ideal/signupInitiatePreAction.do
97
+ * "Live dashboard":https://abnamro.ideal-payment.de/ideal/signupInitiatePreAction.do
120
98
 
121
- Give the consumer a list of available issuer options:
99
+ h3. Compatibility
122
100
 
123
- <pre>
124
- gateway = ActiveMerchant::Billing::IdealGateway.new
125
- issuers = gateway.issuers.list
126
- sorted_issuers = issuers.sort_by { |issuer| issuer[:name] }
127
- select('purchase', 'issuer_id', issuers.map { |issuer| [issuer[:name], issuer[:id]] })
128
- </pre>
101
+ We run continuous integration tests with Ruby 1.8.7, 1.9.2, and 1.9.3. We're pretty sure that means it works (see the badge at the top of this file).
102
+
103
+ h2. Example (Rails)
104
+
105
+ The following code was written as an example and should not be used without further testing in your application. USE AT YOUR OWN PERIL. Remember to have fun (;
106
+
107
+ h3. Config
129
108
 
130
- Could become:
109
+ Configure the Gateway somewhere. One place could be <code>config/initializers/ideal.rb</code>.
131
110
 
132
111
  <pre>
133
- <select name="purchase[issuer_id]">
112
+ unless Rails.env.production?
113
+ Ideal::Gateway.environment = :test
114
+ end
115
+
116
+ # Other banks preloaded are :abnamro and :rabobank
117
+ Ideal::Gateway::IdealGateway.acquirer = :ing
118
+ Ideal::Gateway::IdealGateway.merchant_id = '00123456789'
119
+
120
+ # Maybe you'd like another location
121
+ ideal_directory = Rails.root + 'config/ideal'
122
+ Ideal::Gateway::IdealGateway.passphrase = 'the_passphrase'
123
+ Ideal::Gateway::IdealGateway.private_key_file = ideal_directory + 'private_key.pem'
124
+ Ideal::Gateway::IdealGateway.private_certificate_file = ideal_directory + 'private_certificate.cer'
125
+ Ideal::Gateway::IdealGateway.ideal_certificate_file = ideal_directory + 'ideal.cer'
126
+ </pre>
127
+
128
+ h3. Show a payment form
129
+
130
+ Show a list of all issuers (banks) to choose from.
131
+
132
+ <pre><code>class PaymentsController < ActionController::Base
133
+ def new
134
+ @payment = Payment.new
135
+ @issuers = sorted_issuers
136
+ end
137
+
138
+ private
139
+
140
+ def ideal
141
+ Ideal::Gateway.new
142
+ end
143
+
144
+ def sorted_issuers
145
+ # NOTE: this does a GET on the bankend, you might want to memoize this
146
+ ideal.issuers.list.sort_by do |issuer|
147
+ issuer[:name]
148
+ end.map do |issuer|
149
+ [issuer[:name], issuer[:id]]
150
+ end
151
+ end
152
+ end
153
+ </code></pre>
154
+
155
+ <pre><code>
156
+ <%= form_for(@payment) do |f| %
157
+ <%= f.select(:issuer_id, @issuers)
158
+ <% end %</code></pre>
159
+
160
+ Would result in something like:
161
+
162
+ <select name="payment[issuer_id]">
134
163
  <option value="1006" selected="selected">ABN AMRO Bank</option>
135
164
  <option value="1017">Asr bank</option>
136
165
  <option value="1003">Postbank</option>
137
166
  <option value="1005">Rabobank</option>
138
167
  <option value="1023">Van Lanschot</option>
139
168
  </select>
140
- </pre>
141
169
 
142
- h3. Controller
170
+ h3. Set up a payment
143
171
 
144
172
  First you'll need to setup a transaction and redirect the consumer there so she can make the payment:
145
173
 
146
- <pre>
147
- class PurchasesController < ActionController::Base
148
- def create
149
- purchase = @user.purchases.build(:price => 1000) # €10.00 in cents.
150
- purchase.save(false) # We want an id for the URL.
151
-
152
- purchase_options = {
153
- :issuer_id => params[:purchase][:issuer_id],
154
- :order_id => purchase.id,
155
- :return_url => purchase_url(purchase),
156
- :description => 'A Dutch windmill'
157
- }
158
-
159
- # Save the purchase instance so that the consumer can return to its resource url to finish the transaction.
160
- purchase.update_attributes!(purchase_options)
161
-
162
- gateway = ActiveMerchant::Billing::IdealGateway.new
163
- transaction_response = gateway.setup_purchase(purchase.price, purchase_options)
164
- if transaction_response.success?
165
-
166
- # Store the transaction_id that the acquirer has created to identify the transaction.
167
- purchase.update_attributes!(:transaction_id => transaction_response.transaction_id)
168
-
169
- # Redirect the consumer to the issuer’s payment page.
170
- redirect_to transaction_response.service_url
171
- end
172
- end
173
- end
174
- </pre>
174
+ <pre><code>class Payment < ActiveRecord::Base
175
+ # Validation code used to validate returning notifications from iDeal
176
+ def ideal_entrance_code
177
+ Digest::SHA1.hexdigest("#{id}-#{created_at}-#{access_token}")
178
+ end
179
+
180
+ def ideal_attributes
181
+ {
182
+ # The customer has 30 minutes to complete the iDeal transaction (ISO 8601)
183
+ :expiration_period => "PT30M",
184
+ :issuer_id => issuer_id,
185
+ :return_url => return_url,
186
+ :order_id => id.to_s,
187
+ :description => description,
188
+ :entrance_code => ideal_entrance_code
189
+ }
190
+ end
191
+ end
192
+
193
+ class PaymentsController < ActionController::Base
194
+ def create
195
+ payment = Payment.create(params[:payment].merge(
196
+ :price_in_cents => 1000, # €10.00 in cents
197
+ :return_url => payment_url(payment), # This is where the customer will be returned to
198
+ :description => 'A Dutch windmill' # This will end up on the customer's bank statement (max 32 ASCII chars)
199
+ ))
200
+
201
+ response = ideal.setup_purchase(payment.price_in_cents, payment.ideal_attributes)
202
+ if response.success?
203
+ payment.transaction_id = response.transaction_id
204
+ payment.status = 'pending'
205
+ payment.save(false)
206
+ else
207
+ Rails.logger.info("Payment initialization failed: [#{response.error_message}] #{response.error_details}")
208
+ end
209
+
210
+ # Redirect the consumer to the issuer’s payment page.
211
+ redirect_to response.service_url
212
+ end
213
+ end</code></pre>
175
214
 
176
215
  After the consumer is done with the payment she will be redirected to the _:return_url_. It's now _your_ responsibility as merchant to check if the payment has been made:
177
216
 
178
- <pre>
179
- class PurchasesController < ActionController::Base
180
- def show
181
- gateway = ActiveMerchant::Billing::IdealGateway.new
182
- transaction_status = gateway.capture(@purchase.transaction_id)
183
-
184
- if transaction_status.success?
185
- @purchase.update_attributes!(:paid => true)
186
- flash[:notice] = "Congratulations, you are now the proud owner of a Dutch windmill!"
187
- end
188
- end
189
- end
190
- </pre>
217
+ <pre><code>
218
+ class PaymentsController < ActionController::Base
219
+ def show
220
+ @payment = Payment.find(params[:id])
221
+ status = ideal.capture(@payment.transaction_id)
222
+ if status.success?
223
+ @payment.update_attributes!(:status => 'paid')
224
+ flash[:notice] = "Congratulations, you are now the proud owner of a Dutch windmill!"
225
+ end
226
+ end
227
+ end
228
+ </code></pre>
191
229
 
192
- h2. History
230
+ h2. Help out!
193
231
 
194
- In 2006 an iDEAL payment library was written in Ruby for a web shop build in Rails for selling mobile phone credits. It was basically a translation of the PHP example given by the iDEAL organization (see iDEAL Advanced Integration Manual PHP). Is was released as the ideal-on-rails library (see "http://dev.dovadi.com/projects/ideal":http://dev.dovadi.com/projects/ideal).
232
+ If you find anything wrong with the gem, we would love to hear from you. Please "create an issue with a patch":https://github.com/Fingertips/iDeal/issues if you run into anything.
233
+
234
+ h2. History
195
235
 
196
- In 2007 this code was refactored as a patch for the ActiveMerchant library, this was mainly done by "Fingertips":http://www.fngtps.com/ for a client project. This patch was never accepted due to the fact it was too different (and maybe too obscure) from the 'normal' credit card gateways.
236
+ In 2006 an iDEAL payment library was written in Ruby for a web shop build in Rails for selling mobile phone credits. It was basically a translation of the PHP example given by the iDEAL organization (see iDEAL Advanced Integration Manual PHP). Is was released as the ideal-on-rails library.
197
237
 
198
- In 2009 Fingertips forked the ActiveMerchant library and added an iDEAL gateway (presumable based on the first ActiveMerchant patch) to a new ideal branch.
238
+ In 2007 this code was refactored as a patch for the ActiveMerchant library, this was mainly done by "Fingertips":http://www.fngtps.com/ for a client project. This patch was never accepted due to the fact it was too different (and maybe too obscure) from the 'normal' credit card gateways. After some lobbying an older patch of the code eventually found it's way into ActiveMerchant.
199
239
 
200
- In 2010 this code was extracted and converted into a separate gem, so it can be more easily used in combination with the latest version of ActiveMerchant. This library is just an extraction, nothing more and nothing less. There are no fundamental changes between the code from the ideal branch and the code of this gem. Later that year "Sernin van de Krol":http://github.com/paneidos added support for ABN AMRO.
240
+ In 2009 Fingertips forked the ActiveMerchant library and added an iDEAL gateway based on the ActiveMerchant path.
201
241
 
202
- h2. Maintainer
242
+ In 2010 this code was extracted and converted into a separate gem by Frank Oxener of Agile Dovadi, so it can be more easily used in combination with the latest version of ActiveMerchant. This library was just an extraction, nothing more and nothing less. There were no fundamental changes between the code from the ideal branch and the code of this gem. Later that year "Sernin van de Krol":http://github.com/paneidos added support for ABN AMRO.
203
243
 
204
- This gem is maintained by "Agile Dovadi BV":http://dovadi.com, contact "Frank Oxener":mailto:frank@dovadi.com
244
+ At the end of 2011 Fingertips made yet another fork of the code as the iDeal gem. They ripped out all ActiveMerchant and Rails dependencies. In 2012 ABN AMRO switched their backend and support for this was also added.
@@ -11,13 +11,8 @@ module Ideal
11
11
  'test_url' => 'https://idealtest.rabobank.nl/ideal/iDeal'
12
12
  },
13
13
  'abnamro' => {
14
- 'live_directory_url' => 'https://idealm.abnamro.nl/nl/issuerInformation/getIssuerInformation.xml',
15
- 'live_transaction_url' => 'https://idealm.abnamro.nl/nl/acquirerTrxRegistration/getAcquirerTrxRegistration.xml',
16
- 'live_status_url' => 'https://idealm.abnamro.nl/nl/acquirerStatusInquiry/getAcquirerStatusInquiry.xml',
17
-
18
- 'test_directory_url' => 'https://itt.idealdesk.com/ITTEmulatorAcquirer/Directory.aspx',
19
- 'test_transaction_url' => 'https://itt.idealdesk.com/ITTEmulatorAcquirer/Transaction.aspx',
20
- 'test_status_url' => 'https://itt.idealdesk.com/ITTEmulatorAcquirer/Status.aspx'
14
+ 'live_url' => 'https://abnamro.ideal-payment.de/ideal/iDeal',
15
+ 'test_url' => 'https://abnamro-test.ideal-payment.de/ideal/iDeal'
21
16
  }
22
17
  }
23
18
  end
@@ -40,12 +40,7 @@ module Ideal
40
40
  attr_accessor :passphrase
41
41
 
42
42
  # Holds the test and production urls for your iDeal acquirer.
43
- attr_accessor :live_url, :test_url
44
-
45
- # For ABN AMRO only assign the three separate directory, transaction and status urls.
46
- attr_accessor :live_directory_url, :test_directory_url
47
- attr_accessor :live_transaction_url, :test_transaction_url
48
- attr_accessor :live_status_url, :test_status_url
43
+ attr_accessor :live_url, :test_url
49
44
  end
50
45
 
51
46
  # Environment defaults to test
@@ -119,11 +114,6 @@ module Ideal
119
114
  end
120
115
  end
121
116
 
122
- # Returns true when the acquirer was set to :abnamro
123
- def self.abn_amro?
124
- acquirer.to_sym == :abnamro
125
- end
126
-
127
117
  # Returns the merchant `subID' being used for this Gateway instance.
128
118
  # Defaults to 0.
129
119
  attr_reader :sub_id
@@ -135,11 +125,11 @@ module Ideal
135
125
  @sub_id = options[:sub_id] || 0
136
126
  end
137
127
 
138
- # Returns the endpoint for a certain request.
128
+ # Returns the endpoint for the request.
139
129
  #
140
130
  # Automatically uses test or live URLs based on the configuration.
141
- def request_url(request_type)
142
- self.class.send("#{self.class.environment}#{request_url_prefix(request_type)}_url")
131
+ def request_url
132
+ self.class.send("#{self.class.environment}_url")
143
133
  end
144
134
 
145
135
  # Sends a directory request to the acquirer and returns an
@@ -148,7 +138,7 @@ module Ideal
148
138
  #
149
139
  # gateway.issuers.list # => [{ :id => '1006', :name => 'ABN AMRO Bank' }, …]
150
140
  def issuers
151
- post_data request_url(:directory), build_directory_request_body, DirectoryResponse
141
+ post_data request_url, build_directory_request_body, DirectoryResponse
152
142
  end
153
143
 
154
144
  # Starts a purchase by sending an acquirer transaction request for the
@@ -196,7 +186,7 @@ module Ideal
196
186
  #
197
187
  # See the Gateway class description for a more elaborate example.
198
188
  def setup_purchase(money, options)
199
- post_data request_url(:transaction), build_transaction_request_body(money, options), TransactionResponse
189
+ post_data request_url, build_transaction_request_body(money, options), TransactionResponse
200
190
  end
201
191
 
202
192
  # Sends a acquirer status request for the specified +transaction_id+ and
@@ -216,23 +206,22 @@ module Ideal
216
206
  #
217
207
  # See the Gateway class description for a more elaborate example.
218
208
  def capture(transaction_id)
219
- post_data request_url(:status), build_status_request_body(:transaction_id => transaction_id), StatusResponse
209
+ post_data request_url, build_status_request_body(:transaction_id => transaction_id), StatusResponse
220
210
  end
221
211
 
222
212
  private
223
213
 
224
- # Returns the prefix to locate the setting for a certain request type. Only applies
225
- # in the case of ABN AMRO because they use more than one endpoint.
226
- def request_url_prefix(request_type)
227
- (request_type && self.class.abn_amro?) ? "_#{request_type.to_s}" : nil
228
- end
229
-
230
214
  def ssl_post(url, body)
231
- response = REST.post(url, body, {}, {
215
+ log('URL', url)
216
+ log('Request', body)
217
+ response = REST.post(url, body, {
218
+ 'Content-Type' => 'application/xml; charset=utf-8'
219
+ }, {
232
220
  :tls_verify => true,
233
221
  :tls_key => self.class.private_key,
234
222
  :tls_certificate => self.class.private_certificate
235
223
  })
224
+ log('Response', response.body)
236
225
  response.body
237
226
  end
238
227
 
@@ -260,7 +249,7 @@ module Ideal
260
249
  end
261
250
 
262
251
  def strip_whitespace(str)
263
- self.class.abn_amro? ? str.gsub(/(\f|\n|\r|\t|\v)/m, '') : str.gsub(/\s/m,'')
252
+ str.gsub(/\s/m,'')
264
253
  end
265
254
 
266
255
  # Creates a +tokenCode+ from the specified +message+.
@@ -421,5 +410,9 @@ module Ideal
421
410
  ]]
422
411
  ])
423
412
  end
413
+
414
+ def log(thing, contents)
415
+ $stderr.write("\n#{thing}:\n\n#{contents}\n") if $DEBUG
416
+ end
424
417
  end
425
418
  end
@@ -196,7 +196,7 @@ module Ideal
196
196
  # Returns whether or not the authenticity of the message could be
197
197
  # verified.
198
198
  def verified?
199
- @verified ||= Gateway.ideal_certificate.public_key.
199
+ @verified ||= Ideal::Gateway.ideal_certificate.public_key.
200
200
  verify(OpenSSL::Digest::SHA1.new, signature, message)
201
201
  end
202
202
 
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Ideal
4
- VERSION = '0.2.0'
4
+ VERSION = '0.9.0'
5
5
  end
@@ -43,9 +43,7 @@ module IdealTestCases
43
43
 
44
44
  def test_verify_live_urls_for_abnamro
45
45
  Ideal::Gateway.acquirer = :abnamro
46
- assert_equal 'https://idealm.abnamro.nl/nl/issuerInformation/getIssuerInformation.xml', Ideal::Gateway.live_directory_url
47
- assert_equal 'https://idealm.abnamro.nl/nl/acquirerTrxRegistration/getAcquirerTrxRegistration.xml', Ideal::Gateway.live_transaction_url
48
- assert_equal 'https://idealm.abnamro.nl/nl/acquirerStatusInquiry/getAcquirerStatusInquiry.xml', Ideal::Gateway.live_status_url
46
+ assert_equal 'https://abnamro.ideal-payment.de/ideal/iDeal', Ideal::Gateway.live_url
49
47
  end
50
48
 
51
49
  def test_does_not_allow_configuration_of_unknown_acquirers
@@ -57,7 +55,7 @@ module IdealTestCases
57
55
  def test_acquirers
58
56
  assert_equal 'https://ideal.rabobank.nl/ideal/iDeal', Ideal::Gateway.acquirers['rabobank']['live_url']
59
57
  assert_equal 'https://ideal.secure-ing.com/ideal/iDeal', Ideal::Gateway.acquirers['ing']['live_url']
60
- assert_equal 'https://idealm.abnamro.nl/nl/acquirerTrxRegistration/getAcquirerTrxRegistration.xml', Ideal::Gateway.acquirers['abnamro']['live_transaction_url']
58
+ assert_equal 'https://abnamro.ideal-payment.de/ideal/iDeal', Ideal::Gateway.acquirers['abnamro']['live_url']
61
59
  end
62
60
 
63
61
  def test_private_certificate_returns_a_loaded_Certificate_instance
@@ -80,39 +78,31 @@ module IdealTestCases
80
78
  def setup
81
79
  @gateway = Ideal::Gateway.new
82
80
  end
83
-
81
+
84
82
  def test_optional_initialization_options
85
83
  assert_equal 0, Ideal::Gateway.new.sub_id
86
84
  assert_equal 1, Ideal::Gateway.new(:sub_id => 1).sub_id
87
85
  end
88
-
86
+
89
87
  def test_returns_the_test_url_when_in_the_test_env
90
88
  Ideal::Gateway.acquirer = :ing
91
89
  Ideal::Gateway.environment = :test
92
- assert_equal Ideal::Gateway.test_url, @gateway.send(:request_url, :directory)
90
+ assert_equal Ideal::Gateway.test_url, @gateway.send(:request_url)
93
91
  end
94
-
92
+
95
93
  def test_returns_the_live_url_when_not_in_the_test_env
96
94
  Ideal::Gateway.acquirer = :ing
97
95
  Ideal::Gateway.environment = :live
98
- assert_equal Ideal::Gateway.live_url, @gateway.send(:request_url, :directory)
96
+ assert_equal Ideal::Gateway.live_url, @gateway.send(:request_url)
99
97
  end
100
98
 
101
- def test_returns_the_special_urls_for_abnamro_when_in_the_test_env
102
- Ideal::Gateway.acquirer = :abnamro
103
- Ideal::Gateway.environment = :test
104
- assert_equal Ideal::Gateway.test_directory_url, @gateway.send(:request_url, :directory)
105
- assert_equal Ideal::Gateway.test_transaction_url, @gateway.send(:request_url, :transaction)
106
- assert_equal Ideal::Gateway.test_status_url, @gateway.send(:request_url, :status)
107
- end
108
-
109
99
  def test_returns_created_at_timestamp
110
100
  timestamp = '2001-12-17T09:30:47.000Z'
111
101
  Time.any_instance.stubs(:gmtime).returns(DateTime.parse(timestamp))
112
-
102
+
113
103
  assert_equal timestamp, @gateway.send(:created_at_timestamp)
114
104
  end
115
-
105
+
116
106
  def test_ruby_to_java_keys_conversion
117
107
  keys = [
118
108
  [:acquirer_transaction_request, 'AcquirerTrxReq'],
@@ -131,77 +121,63 @@ module IdealTestCases
131
121
  [:expiration_period, 'expirationPeriod'],
132
122
  [:entrance_code, 'entranceCode']
133
123
  ]
134
-
124
+
135
125
  keys.each do |key, expected_key|
136
126
  assert_equal expected_key, @gateway.send(:javaize_key, key)
137
127
  end
138
128
  end
139
-
129
+
140
130
  def test_does_not_convert_unknown_key_to_java_key
141
131
  assert_equal 'not_a_registered_key', @gateway.send(:javaize_key, :not_a_registered_key)
142
132
  end
143
-
133
+
144
134
  def test_token_generation
145
135
  expected_token = Digest::SHA1.hexdigest(OpenSSL::X509::Certificate.new(PRIVATE_CERTIFICATE).to_der).upcase
146
136
  assert_equal expected_token, @gateway.send(:token)
147
137
  end
148
-
138
+
149
139
  def test_token_code_generation
150
140
  Ideal::Gateway.acquirer = :ing
151
141
  message = "Top\tsecret\tman.\nI could tell you, but then I'd have to kill you…"
152
142
  stripped_message = message.gsub(/\s/m, '')
153
-
154
- sha1 = OpenSSL::Digest::SHA1.new
155
- OpenSSL::Digest::SHA1.stubs(:new).returns(sha1)
156
-
157
- signature = Ideal::Gateway.private_key.sign(sha1, stripped_message)
158
- encoded_signature = Base64.encode64(signature).strip.gsub(/\n/, '')
159
-
160
- assert_equal encoded_signature, @gateway.send(:token_code, message)
161
- end
162
-
163
- def test_token_code_generation_on_abn_amro
164
- Ideal::Gateway.acquirer = :abnamro
165
- message = "Top\tsecret\tman.\nI could tell you, but\r then I'd have to kill you…"
166
- stripped_message = message.gsub(/(\f|\n|\r|\t|\v)/m, '')
167
-
143
+
168
144
  sha1 = OpenSSL::Digest::SHA1.new
169
145
  OpenSSL::Digest::SHA1.stubs(:new).returns(sha1)
170
-
146
+
171
147
  signature = Ideal::Gateway.private_key.sign(sha1, stripped_message)
172
148
  encoded_signature = Base64.encode64(signature).strip.gsub(/\n/, '')
173
-
149
+
174
150
  assert_equal encoded_signature, @gateway.send(:token_code, message)
175
151
  end
176
-
152
+
177
153
  def test_posts_data_with_ssl_to_request_url_and_return_the_correct_response_for_test
178
154
  Ideal::Gateway.environment = :test
179
155
  Ideal::Response.expects(:new).with('response', :test => true)
180
- @gateway.expects(:ssl_post).with(@gateway.request_url(:directory), 'data').returns('response')
181
- @gateway.send(:post_data, @gateway.request_url(:directory), 'data', Ideal::Response)
156
+ @gateway.expects(:ssl_post).with(@gateway.request_url, 'data').returns('response')
157
+ @gateway.send(:post_data, @gateway.request_url, 'data', Ideal::Response)
182
158
  end
183
-
159
+
184
160
  def test_posts_data_with_ssl_to_request_url_and_return_the_correct_response_for_live
185
161
  Ideal::Gateway.environment = :live
186
162
  Ideal::Response.expects(:new).with('response', :test => false)
187
- @gateway.expects(:ssl_post).with(@gateway.request_url(:directory), 'data').returns('response')
188
- @gateway.send(:post_data, @gateway.request_url(:directory), 'data', Ideal::Response)
163
+ @gateway.expects(:ssl_post).with(@gateway.request_url, 'data').returns('response')
164
+ @gateway.send(:post_data, @gateway.request_url, 'data', Ideal::Response)
189
165
  end
190
166
  end
191
-
167
+
192
168
  class XMLBuildingTest < Test::Unit::TestCase
193
169
  def setup
194
170
  @gateway = Ideal::Gateway.new
195
171
  end
196
-
172
+
197
173
  def test_contains_correct_info_in_root_node
198
174
  expected_xml = Builder::XmlMarkup.new
199
175
  expected_xml.instruct!
200
176
  expected_xml.tag!('AcquirerTrxReq', 'xmlns' => Ideal::Gateway::XML_NAMESPACE, 'version' => Ideal::Gateway::API_VERSION) {}
201
-
177
+
202
178
  assert_equal expected_xml.target!, @gateway.send(:xml_for, :acquirer_transaction_request, [])
203
179
  end
204
-
180
+
205
181
  def test_creates_correct_xml_with_java_keys_from_array_with_ruby_keys
206
182
  expected_xml = Builder::XmlMarkup.new
207
183
  expected_xml.instruct!
@@ -210,42 +186,42 @@ module IdealTestCases
210
186
  expected_xml.tag!('createDateTimeStamp', '2009-01-26')
211
187
  end
212
188
  end
213
-
189
+
214
190
  assert_equal expected_xml.target!, @gateway.send(:xml_for, :acquirer_transaction_request, [[:a_parent, [[:created_at, '2009-01-26']]]])
215
191
  end
216
192
  end
217
-
193
+
218
194
  class RequestBodyBuildingTest < Test::Unit::TestCase
219
195
  def setup
220
196
  @gateway = Ideal::Gateway.new
221
-
197
+
222
198
  @gateway.stubs(:created_at_timestamp).returns('created_at_timestamp')
223
199
  @gateway.stubs(:token).returns('the_token')
224
200
  @gateway.stubs(:token_code)
225
-
201
+
226
202
  @transaction_id = '0001023456789112'
227
203
  end
228
-
204
+
229
205
  def test_build_transaction_request_body_raises_ArgumentError_with_missing_required_options
230
206
  options = VALID_PURCHASE_OPTIONS.dup
231
207
  options.keys.each do |key|
232
208
  options.delete(key)
233
-
209
+
234
210
  assert_raise(ArgumentError) do
235
211
  @gateway.send(:build_transaction_request_body, 100, options)
236
212
  end
237
213
  end
238
214
  end
239
-
215
+
240
216
  def test_valid_with_valid_options
241
217
  assert_not_nil @gateway.send(:build_transaction_request_body, 4321, VALID_PURCHASE_OPTIONS)
242
218
  end
243
-
219
+
244
220
  def test_checks_that_fields_are_not_too_long
245
221
  assert_raise ArgumentError do
246
222
  @gateway.send(:build_transaction_request_body, 1234567890123, VALID_PURCHASE_OPTIONS) # 13 chars
247
223
  end
248
-
224
+
249
225
  [
250
226
  [:order_id, '12345678901234567'], # 17 chars,
251
227
  [:description, '123456789012345678901234567890123'], # 33 chars
@@ -253,31 +229,31 @@ module IdealTestCases
253
229
  ].each do |key, value|
254
230
  options = VALID_PURCHASE_OPTIONS.dup
255
231
  options[key] = value
256
-
232
+
257
233
  assert_raise ArgumentError do
258
234
  @gateway.send(:build_transaction_request_body, 4321, options)
259
235
  end
260
236
  end
261
237
  end
262
-
238
+
263
239
  def test_checks_that_fields_do_not_contain_diacritical_characters
264
240
  assert_raise ArgumentError do
265
241
  @gateway.send(:build_transaction_request_body, 'graphème', VALID_PURCHASE_OPTIONS)
266
242
  end
267
-
243
+
268
244
  [:order_id, :description, :entrance_code].each do |key, value|
269
245
  options = VALID_PURCHASE_OPTIONS.dup
270
246
  options[key] = 'graphème'
271
-
247
+
272
248
  assert_raise ArgumentError do
273
249
  @gateway.send(:build_transaction_request_body, 4321, options)
274
250
  end
275
251
  end
276
252
  end
277
-
253
+
278
254
  def test_builds_a_transaction_request_body
279
255
  money = 4321
280
-
256
+
281
257
  message = 'created_at_timestamp' +
282
258
  VALID_PURCHASE_OPTIONS[:issuer_id] +
283
259
  Ideal::Gateway.merchant_id +
@@ -289,13 +265,13 @@ module IdealTestCases
289
265
  Ideal::Gateway::LANGUAGE +
290
266
  VALID_PURCHASE_OPTIONS[:description] +
291
267
  VALID_PURCHASE_OPTIONS[:entrance_code]
292
-
268
+
293
269
  @gateway.expects(:token_code).with(message).returns('the_token_code')
294
-
270
+
295
271
  @gateway.expects(:xml_for).with(:acquirer_transaction_request, [
296
272
  [:created_at, 'created_at_timestamp'],
297
273
  [:issuer, [[:issuer_id, VALID_PURCHASE_OPTIONS[:issuer_id]]]],
298
-
274
+
299
275
  [:merchant, [
300
276
  [:merchant_id, Ideal::Gateway.merchant_id],
301
277
  [:sub_id, @gateway.sub_id],
@@ -304,7 +280,7 @@ module IdealTestCases
304
280
  [:token_code, 'the_token_code'],
305
281
  [:merchant_return_url, VALID_PURCHASE_OPTIONS[:return_url]]
306
282
  ]],
307
-
283
+
308
284
  [:transaction, [
309
285
  [:purchase_id, VALID_PURCHASE_OPTIONS[:order_id]],
310
286
  [:amount, money],
@@ -315,14 +291,14 @@ module IdealTestCases
315
291
  [:entrance_code, VALID_PURCHASE_OPTIONS[:entrance_code]]
316
292
  ]]
317
293
  ])
318
-
294
+
319
295
  @gateway.send(:build_transaction_request_body, money, VALID_PURCHASE_OPTIONS)
320
296
  end
321
-
297
+
322
298
  def test_builds_a_directory_request_body
323
299
  message = 'created_at_timestamp' + Ideal::Gateway.merchant_id + @gateway.sub_id.to_s
324
300
  @gateway.expects(:token_code).with(message).returns('the_token_code')
325
-
301
+
326
302
  @gateway.expects(:xml_for).with(:directory_request, [
327
303
  [:created_at, 'created_at_timestamp'],
328
304
  [:merchant, [
@@ -333,22 +309,22 @@ module IdealTestCases
333
309
  [:token_code, 'the_token_code']
334
310
  ]]
335
311
  ])
336
-
312
+
337
313
  @gateway.send(:build_directory_request_body)
338
314
  end
339
-
315
+
340
316
  def test_builds_a_status_request_body_raises_ArgumentError_with_missing_required_options
341
317
  assert_raise(ArgumentError) do
342
318
  @gateway.send(:build_status_request_body, {})
343
319
  end
344
320
  end
345
-
321
+
346
322
  def test_builds_a_status_request_body
347
323
  options = { :transaction_id => @transaction_id }
348
-
324
+
349
325
  message = 'created_at_timestamp' + Ideal::Gateway.merchant_id + @gateway.sub_id.to_s + options[:transaction_id]
350
326
  @gateway.expects(:token_code).with(message).returns('the_token_code')
351
-
327
+
352
328
  @gateway.expects(:xml_for).with(:acquirer_status_request, [
353
329
  [:created_at, 'created_at_timestamp'],
354
330
  [:merchant, [
@@ -358,67 +334,67 @@ module IdealTestCases
358
334
  [:token, 'the_token'],
359
335
  [:token_code, 'the_token_code']
360
336
  ]],
361
-
337
+
362
338
  [:transaction, [
363
339
  [:transaction_id, options[:transaction_id]]
364
340
  ]],
365
341
  ])
366
-
342
+
367
343
  @gateway.send(:build_status_request_body, options)
368
344
  end
369
345
  end
370
-
346
+
371
347
  class GeneralResponseTest < Test::Unit::TestCase
372
348
  def test_resturns_if_it_is_a_test_request
373
349
  assert Ideal::Response.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS, :test => true).test?
374
-
350
+
375
351
  assert !Ideal::Response.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS, :test => false).test?
376
352
  assert !Ideal::Response.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS).test?
377
353
  end
378
354
  end
379
-
355
+
380
356
  class SuccessfulResponseTest < Test::Unit::TestCase
381
357
  def setup
382
358
  @response = Ideal::Response.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS)
383
359
  end
384
-
360
+
385
361
  def test_initializes_with_only_response_body
386
362
  assert_equal REXML::Document.new(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS).root.to_s,
387
363
  @response.instance_variable_get(:@response).to_s
388
364
  end
389
-
365
+
390
366
  def test_successful
391
367
  assert @response.success?
392
368
  end
393
-
369
+
394
370
  def test_returns_no_error_messages
395
371
  assert_nil @response.error_message
396
372
  end
397
-
373
+
398
374
  def test_returns_no_error_code
399
375
  assert_nil @response.error_code
400
376
  end
401
377
  end
402
-
378
+
403
379
  class ErrorResponseTest < Test::Unit::TestCase
404
380
  def setup
405
381
  @response = Ideal::Response.new(ERROR_RESPONSE)
406
382
  end
407
-
383
+
408
384
  def test_unsuccessful
409
385
  assert !@response.success?
410
386
  end
411
-
387
+
412
388
  def test_returns_error_messages
413
389
  assert_equal 'Failure in system', @response.error_message
414
390
  assert_equal 'System generating error: issuer', @response.error_details
415
391
  assert_equal 'Betalen met iDEAL is nu niet mogelijk.', @response.consumer_error_message
416
392
  end
417
-
393
+
418
394
  def test_returns_error_code
419
395
  assert_equal 'SO1000', @response.error_code
420
396
  end
421
-
397
+
422
398
  def test_returns_error_type
423
399
  [
424
400
  ['IX1000', :xml],
@@ -432,27 +408,27 @@ module IdealTestCases
432
408
  end
433
409
  end
434
410
  end
435
-
411
+
436
412
  class DirectoryTest < Test::Unit::TestCase
437
413
  def setup
438
414
  @gateway = Ideal::Gateway.new
439
415
  end
440
-
416
+
441
417
  def test_returns_a_list_with_only_one_issuer
442
418
  @gateway.stubs(:build_directory_request_body).returns('the request body')
443
- @gateway.expects(:ssl_post).with(@gateway.request_url(:directory), 'the request body').returns(DIRECTORY_RESPONSE_WITH_ONE_ISSUER)
444
-
419
+ @gateway.expects(:ssl_post).with(@gateway.request_url, 'the request body').returns(DIRECTORY_RESPONSE_WITH_ONE_ISSUER)
420
+
445
421
  expected_issuers = [{ :id => '1006', :name => 'ABN AMRO Bank' }]
446
-
422
+
447
423
  directory_response = @gateway.issuers
448
424
  assert_instance_of Ideal::DirectoryResponse, directory_response
449
425
  assert_equal expected_issuers, directory_response.list
450
426
  end
451
-
427
+
452
428
  def test_returns_list_of_issuers_from_response
453
429
  @gateway.stubs(:build_directory_request_body).returns('the request body')
454
- @gateway.expects(:ssl_post).with(@gateway.request_url(:directory), 'the request body').returns(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS)
455
-
430
+ @gateway.expects(:ssl_post).with(@gateway.request_url, 'the request body').returns(DIRECTORY_RESPONSE_WITH_MULTIPLE_ISSUERS)
431
+
456
432
  expected_issuers = [
457
433
  { :id => '1006', :name => 'ABN AMRO Bank' },
458
434
  { :id => '1003', :name => 'Postbank' },
@@ -460,85 +436,85 @@ module IdealTestCases
460
436
  { :id => '1017', :name => 'Asr bank' },
461
437
  { :id => '1023', :name => 'Van Lanschot' }
462
438
  ]
463
-
439
+
464
440
  directory_response = @gateway.issuers
465
441
  assert_instance_of Ideal::DirectoryResponse, directory_response
466
442
  assert_equal expected_issuers, directory_response.list
467
443
  end
468
444
  end
469
-
445
+
470
446
  class SetupPurchaseTest < Test::Unit::TestCase
471
447
  def setup
472
448
  @gateway = Ideal::Gateway.new
473
-
449
+
474
450
  @gateway.stubs(:build_transaction_request_body).with(4321, VALID_PURCHASE_OPTIONS).returns('the request body')
475
- @gateway.expects(:ssl_post).with(@gateway.request_url(:transaction), 'the request body').returns(ACQUIRER_TRANSACTION_RESPONSE)
476
-
451
+ @gateway.expects(:ssl_post).with(@gateway.request_url, 'the request body').returns(ACQUIRER_TRANSACTION_RESPONSE)
452
+
477
453
  @setup_purchase_response = @gateway.setup_purchase(4321, VALID_PURCHASE_OPTIONS)
478
454
  end
479
-
455
+
480
456
  def test_setup_purchase_returns_IdealTransactionResponse
481
457
  assert_instance_of Ideal::TransactionResponse, @setup_purchase_response
482
458
  end
483
-
459
+
484
460
  def test_setup_purchase_returns_response_with_service_url
485
461
  assert_equal 'https://ideal.example.com/long_service_url?X009=BETAAL&X010=20', @setup_purchase_response.service_url
486
462
  end
487
-
463
+
488
464
  def test_setup_purchase_returns_response_with_transaction_and_order_ids
489
465
  assert_equal '0001023456789112', @setup_purchase_response.transaction_id
490
466
  assert_equal 'iDEAL-aankoop 21', @setup_purchase_response.order_id
491
467
  end
492
468
  end
493
-
469
+
494
470
  class CapturePurchaseTest < Test::Unit::TestCase
495
471
  def setup
496
472
  @gateway = Ideal::Gateway.new
497
-
473
+
498
474
  @gateway.stubs(:build_status_request_body).
499
475
  with(:transaction_id => '0001023456789112').returns('the request body')
500
476
  end
501
-
477
+
502
478
  def test_setup_purchase_returns_IdealStatusResponse
503
479
  expects_request_and_returns ACQUIRER_SUCCEEDED_STATUS_RESPONSE
504
480
  assert_instance_of Ideal::StatusResponse, @gateway.capture('0001023456789112')
505
481
  end
506
-
482
+
507
483
  # Because we don't have a real private key and certificate we stub
508
484
  # verified? to return true. However, this is properly tested in the remote
509
485
  # tests.
510
486
  def test_capture_of_successful_payment
511
487
  Ideal::StatusResponse.any_instance.stubs(:verified?).returns(true)
512
-
488
+
513
489
  expects_request_and_returns ACQUIRER_SUCCEEDED_STATUS_RESPONSE
514
490
  capture_response = @gateway.capture('0001023456789112')
515
-
491
+
516
492
  assert capture_response.success?
517
493
  end
518
-
494
+
519
495
  def test_capture_of_failed_payment
520
496
  expects_request_and_returns ACQUIRER_FAILED_STATUS_RESPONSE
521
497
  capture_response = @gateway.capture('0001023456789112')
522
-
498
+
523
499
  assert !capture_response.success?
524
500
  end
525
-
501
+
526
502
  def test_capture_of_successful_payment_but_message_does_not_match_signature
527
503
  expects_request_and_returns ACQUIRER_SUCCEEDED_BUT_WRONG_SIGNATURE_STATUS_RESPONSE
528
504
  capture_response = @gateway.capture('0001023456789112')
529
-
505
+
530
506
  assert !capture_response.success?
531
507
  end
532
-
508
+
533
509
  def test_capture_of_consumer_fields
534
510
  expects_request_and_returns ACQUIRER_SUCCEEDED_STATUS_RESPONSE
535
511
  capture_response = @gateway.capture('0001023456789112')
536
-
512
+
537
513
  assert_equal '0949298989', capture_response.consumer_account_number
538
514
  assert_equal 'Onderheuvel', capture_response.consumer_name
539
515
  assert_equal 'DEN HAAG', capture_response.consumer_city
540
516
  end
541
-
517
+
542
518
  def test_returns_status
543
519
  response = Ideal::StatusResponse.new(ACQUIRER_SUCCEEDED_STATUS_RESPONSE)
544
520
  [
@@ -552,11 +528,11 @@ module IdealTestCases
552
528
  assert_equal expected_status, response.status
553
529
  end
554
530
  end
555
-
531
+
556
532
  private
557
-
533
+
558
534
  def expects_request_and_returns(str)
559
- @gateway.expects(:ssl_post).with(@gateway.request_url(:status), 'the request body').returns(str)
535
+ @gateway.expects(:ssl_post).with(@gateway.request_url, 'the request body').returns(str)
560
536
  end
561
537
  end
562
538
 
@@ -9,8 +9,10 @@ class IdealTest < Test::Unit::TestCase
9
9
 
10
10
  @gateway = Ideal::Gateway.new
11
11
 
12
+ @@issuer ||= @gateway.issuers.list[0]
13
+
12
14
  @valid_options = {
13
- :issuer_id => '0151',
15
+ :issuer_id => @@issuer[:id],
14
16
  :expiration_period => 'PT10M',
15
17
  :return_url => 'http://return_to.example.com',
16
18
  :order_id => '123456789012',
@@ -59,7 +61,10 @@ class IdealTest < Test::Unit::TestCase
59
61
  #
60
62
 
61
63
  def test_retrieval_of_issuers
62
- assert_equal [{ :id => '0151', :name => 'Issuer Simulator' }], @gateway.issuers.list
64
+ issuer_list = @gateway.issuers.list
65
+ assert_equal 1, issuer_list.length
66
+ assert_match /^Issuer\ Sim/, issuer_list[0][:name]
67
+ assert_match /^\d{4}$/, issuer_list[0][:id]
63
68
  end
64
69
 
65
70
  def test_successful_transaction
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ideal
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 59
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 9
9
9
  - 0
10
- version: 0.2.0
10
+ version: 0.9.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Soemirno Kartosoewito
@@ -19,7 +19,7 @@ autorequire:
19
19
  bindir: bin
20
20
  cert_chain: []
21
21
 
22
- date: 2012-01-03 00:00:00 Z
22
+ date: 2012-01-19 00:00:00 Z
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
25
25
  name: builder
@@ -75,6 +75,7 @@ extra_rdoc_files:
75
75
  files:
76
76
  - .document
77
77
  - .gitignore
78
+ - .kick
78
79
  - .travis.yml
79
80
  - Gemfile
80
81
  - Gemfile.lock