datatrans 2.4.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 00dfb98ec54350ac1a4d6d2a932a4ee08ed1ddd5
4
+ data.tar.gz: 599f998c0f9bd6e489d9571e171893c3b463be24
5
+ SHA512:
6
+ metadata.gz: 06eeebeafc026f0fdfc1296be4f2a2e8201aa7de21a12f950b4f938225bcee6b0ffe19f2e47a4a5432c30d68c478c9733bca30b20a55dda593d5e1135e898738
7
+ data.tar.gz: 2a285a435167deae93bca53229ad7b01f4b536c739b50ca293c54f599312ad179fe90fbcc06789a4c6b0d94eb45650a585d0cea10d0e6bf7f36895da9fe93d81
@@ -3,5 +3,6 @@ rvm:
3
3
  - 1.8.7
4
4
  - 1.9.3
5
5
  - ree
6
+ - 2.0.0
6
7
  gemfile:
7
8
  - Gemfile
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- datatrans (2.4.0)
4
+ datatrans (3.0.0)
5
5
  activesupport (>= 3.0.0)
6
6
  builder
7
7
  httparty
8
8
  i18n
9
+ multi_xml (>= 0.5.1)
9
10
 
10
11
  GEM
11
12
  remote: http://rubygems.org/
@@ -30,13 +31,13 @@ GEM
30
31
  diff-lcs (1.1.3)
31
32
  erubis (2.7.0)
32
33
  hike (1.2.1)
33
- httparty (0.10.2)
34
+ httparty (0.11.0)
34
35
  multi_json (~> 1.0)
35
36
  multi_xml (>= 0.5.2)
36
37
  i18n (0.6.1)
37
38
  journey (1.0.4)
38
39
  multi_json (1.5.0)
39
- multi_xml (0.5.2)
40
+ multi_xml (0.5.5)
40
41
  rack (1.4.4)
41
42
  rack-cache (1.2)
42
43
  rack (>= 0.4)
@@ -6,21 +6,23 @@ Ruby adapter for the Datatrans payment gateway (http://www.datatrans.ch).
6
6
  Configuration
7
7
  -------------
8
8
 
9
- Set your datatrans credentials in your environment.
10
-
11
- Datatrans.configure do |config|
12
- config.merchant_id = '1234567'
13
- config.sign_key = 'ab739fd5b7c2a1...'
14
- config.environment = :production
15
- config.proxy = {
16
- :host => "proxy.com",
17
- :port => 80,
18
- :user => "hans",
19
- :password => "xxx",
9
+ Buidl your Datatrans Configuration like so:
10
+
11
+ datatrans = Datatrans::Config.new(
12
+ :merchant_id => '1234567',
13
+ :sign_key => 'ab739fd5b7c2a1...',
14
+ :environment => :production,
15
+ :proxy => {
16
+ :http_proxyaddr => "proxy.com",
17
+ :http_proxyport => 80,
18
+ :http_proxyuser => "hans",
19
+ :http_proxpass => "xxx",
20
20
  }
21
- end
21
+ )
22
22
 
23
- If you don't want to use signed requests (disabled in datatrans web console), you must set `config.sign_key` to `false`.
23
+
24
+ If you don't want to use signed requests (disabled in datatrans web console), you can set `config.sign_key` to `false`.
25
+ The configuration is then used as parameter to all the constructors and helpers, see examples below.
24
26
 
25
27
  Possible values for the environment: `:production`, `:development`
26
28
 
@@ -30,14 +32,13 @@ Web Authorization
30
32
  If you want to process a credit card the first time a web authorization is
31
33
  necessary. Add the following code to a controller action that shows the form.
32
34
  You need to pass at least `amount`, `currency` and `refno` (order number).
33
-
34
- @transaction = Datatrans::Web::Transaction.new({
35
+ @transaction = datatrans.web_transaction(
35
36
  :amount => 1000, # in cents!
36
37
  :currency => 'CHF',
37
38
  :refno => 'ABCDEF',
38
- :uppCustomerEmail => 'customer@email.com'
39
+ :uppCustomerEmail => 'customer@email.com',
39
40
  # feel free to add more upp infos here ...
40
- })
41
+ )
41
42
 
42
43
  In your View your show the credit card form with a convenient helper:
43
44
 
@@ -53,7 +54,7 @@ In your View your show the credit card form with a convenient helper:
53
54
  = hidden_field_tag :cancelUrl, <your_application_return_url>
54
55
  = hidden_field_tag :errorUrl, <your_application_return_url>
55
56
 
56
- = datatrans_notification_request_hidden_fields(@transaction)
57
+ = datatrans_notification_request_hidden_fields(datatrans, @transaction)
57
58
 
58
59
  = submit_tag "send"
59
60
 
@@ -66,7 +67,7 @@ After you submit the request to Datatrans they redirect back to your application
66
67
  Now you can process the transaction like this:
67
68
 
68
69
  begin
69
- transaction = Datatrans::Web::Transaction.new(params)
70
+ transaction = datatrans.web_transaction(params)
70
71
 
71
72
  if transaction.authorize
72
73
  # transaction was successful, access the following attributes
@@ -94,13 +95,13 @@ use the convenient XML methods to process payments.
94
95
  Authorize
95
96
  ---------
96
97
 
97
- transaction = Datatrans::XML::Transaction.new(
98
+ transaction = datatrans.xml_transaction(
98
99
  :refno => 'ABCDEF',
99
100
  :amount => 1000, # in cents!
100
101
  :currency => 'CHF',
101
102
  :aliasCC => '8383843729284848348',
102
103
  :expm => 12,
103
- :expy => 15
104
+ :expy => 15,
104
105
  )
105
106
 
106
107
  if transaction.authorize
@@ -116,11 +117,11 @@ Capture
116
117
 
117
118
  To capture an authorized transaction you use the following code:
118
119
 
119
- transaction = Datatrans::XML::Transaction.new(
120
+ transaction = datatrans.xml_transaction(
120
121
  :refno => 'ABCDEF',
121
122
  :amount => 1000, # in cents!
122
123
  :currency => 'CHF',
123
- :transaction_id => 19834324987349723948729834
124
+ :transaction_id => 19834324987349723948729834,
124
125
  )
125
126
 
126
127
  if transaction.capture
@@ -135,11 +136,11 @@ Void
135
136
 
136
137
  To make an authorized transaction invalid use void.
137
138
 
138
- transaction = Datatrans::XML::Transaction.new(
139
+ transaction = datatrans.xml_transaction(
139
140
  :refno => 'ABCDEF',
140
141
  :amount => 1000, # in cents!
141
142
  :currency => 'CHF',
142
- :transaction_id => 19834324987349723948729834
143
+ :transaction_id => 19834324987349723948729834,
143
144
  )
144
145
 
145
146
  if transaction.void
@@ -152,6 +153,11 @@ To make an authorized transaction invalid use void.
152
153
  CHANGELOG
153
154
  =========
154
155
 
156
+ 3.0.0
157
+ -------
158
+ * Refactored Code to allow multiple configurations
159
+ * Proxy config now uses HTTParty naming convention.
160
+
155
161
  2.2.2
156
162
  -------
157
163
  * added ability to skip signing by setting config.sign_key = false
@@ -5,8 +5,8 @@ require "datatrans/version"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "datatrans"
7
7
  s.version = Datatrans::VERSION
8
- s.authors = ["Tobias Miesel", "Thomas Maurer", "Corin Langosch"]
9
- s.email = ["tobias.miesel@simplificator.com", "thomas.maurer@simplificator.com", "corin.langosch@simplificator.com"]
8
+ s.authors = ["Tobias Miesel", "Thomas Maurer", "Corin Langosch", "Pascal Betz"]
9
+ s.email = ["info@simplificator.com"]
10
10
  s.homepage = ""
11
11
  s.summary = %q{Datatrans Integration for Ruby on Rails}
12
12
  s.description = %q{Datatrans Integration for Ruby on Rails}
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_dependency 'activesupport', '>= 3.0.0'
23
23
  s.add_dependency 'i18n'
24
24
  s.add_dependency 'builder'
25
+ s.add_dependency 'multi_xml', '>= 0.5.1'
25
26
 
26
27
  s.add_development_dependency 'rake'
27
28
  s.add_development_dependency 'rspec'
@@ -1,59 +1,18 @@
1
1
  require 'active_support/core_ext/module'
2
- require 'action_view'
3
2
 
4
3
  module Datatrans
5
- BASE_URL = 'https://payment.datatrans.biz'
6
- WEB_AUTHORIZE_URL = "#{BASE_URL}/upp/jsp/upStart.jsp"
7
- XML_AUTHORIZE_URL = "#{BASE_URL}/upp/jsp/XML_authorize.jsp"
8
- XML_SETTLEMENT_URL = "#{BASE_URL}/upp/jsp/XML_processor.jsp"
9
- XML_STATUS_URL = "#{BASE_URL}/upp/jsp/XML_status.jsp"
10
-
11
- TEST_BASE_URL = 'https://pilot.datatrans.biz'
12
- TEST_WEB_AUTHORIZE_URL = "#{TEST_BASE_URL}/upp/jsp/upStart.jsp"
13
- TEST_XML_AUTHORIZE_URL = "#{TEST_BASE_URL}/upp/jsp/XML_authorize.jsp"
14
- TEST_XML_SETTLEMENT_URL = "#{TEST_BASE_URL}/upp/jsp/XML_processor.jsp"
15
- TEST_XML_STATUS_URL = "#{TEST_BASE_URL}/upp/jsp/XML_status.jsp"
16
-
17
- mattr_accessor :merchant_id
18
- mattr_accessor :sign_key
19
- mattr_accessor :proxy
20
-
21
- mattr_reader :base_url
22
- mattr_reader :web_authorize_url
23
- mattr_reader :xml_authorize_url
24
- mattr_reader :xml_settlement_url
25
- mattr_reader :xml_status_url
26
-
27
- def self.configure
28
- self.environment = :development # default
29
- yield self
30
- end
31
-
32
- def self.environment=(environment)
33
- case environment
34
- when :development
35
- @@base_url = TEST_BASE_URL
36
- @@web_authorize_url = TEST_WEB_AUTHORIZE_URL
37
- @@xml_authorize_url = TEST_XML_AUTHORIZE_URL
38
- @@xml_settlement_url = TEST_XML_SETTLEMENT_URL
39
- @@xml_status_url = TEST_XML_STATUS_URL
40
- when :production
41
- @@base_url = BASE_URL
42
- @@web_authorize_url = WEB_AUTHORIZE_URL
43
- @@xml_authorize_url = XML_AUTHORIZE_URL
44
- @@xml_settlement_url = XML_SETTLEMENT_URL
45
- @@xml_status_url = XML_STATUS_URL
46
- else
47
- raise "Unknown environment '#{environment}'. Available: :development, :production."
48
- end
49
- end
50
-
51
- class InvalidSignatureError < StandardError; end
4
+ InvalidSignatureError = Class.new(StandardError)
52
5
  end
53
6
 
54
7
  require 'datatrans/version'
55
8
  require 'datatrans/common'
9
+ require 'datatrans/config'
56
10
  require 'datatrans/xml/transaction'
57
11
  require 'datatrans/web/transaction'
58
12
 
59
- ActionView::Base.send :include, Datatrans::Web::ViewHelper if defined? ActionView
13
+ begin
14
+ require 'action_view'
15
+ require 'datatrans/web/view_helper'
16
+ ActionView::Base.send(:include, Datatrans::Web::ViewHelper)
17
+ rescue LoadError
18
+ end
@@ -2,8 +2,8 @@ require 'openssl'
2
2
 
3
3
  module Datatrans::Common
4
4
  def sign(*fields)
5
- return nil unless Datatrans.sign_key
6
- key = Datatrans.sign_key.split(/([a-f0-9][a-f0-9])/).reject(&:empty?)
5
+ return nil unless self.datatrans.sign_key
6
+ key = self.datatrans.sign_key.split(/([a-f0-9][a-f0-9])/).reject(&:empty?)
7
7
  key = key.pack("H*" * key.size)
8
8
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest::MD5.new, key, fields.join)
9
9
  end
@@ -0,0 +1,63 @@
1
+ module Datatrans
2
+ class Config
3
+ ENVIRONMENTS = [:development, :production].freeze
4
+ DEFAULT_ENVIRONMENT = :development
5
+
6
+ DEFAULT_SIGN_KEY = false
7
+
8
+ BASE_URL_PRODUCTION = 'https://payment.datatrans.biz'.freeze
9
+ BASE_URL_DEVELOPMENT = 'https://pilot.datatrans.biz'.freeze
10
+
11
+ URLS = {
12
+ :development => {
13
+ :web_authorize_url => "#{BASE_URL_PRODUCTION}/upp/jsp/upStart.jsp".freeze,
14
+ :xml_authorize_url => "#{BASE_URL_PRODUCTION}/upp/jsp/XML_authorize.jsp".freeze,
15
+ :xml_settlement_url => "#{BASE_URL_PRODUCTION}/upp/jsp/XML_processor.jsp".freeze,
16
+ :xml_status_url => "#{BASE_URL_PRODUCTION}/upp/jsp/XML_status.jsp".freeze
17
+ },
18
+ :production => {
19
+ :web_authorize_url => "#{BASE_URL_DEVELOPMENT}/upp/jsp/upStart.jsp".freeze,
20
+ :xml_authorize_url => "#{BASE_URL_DEVELOPMENT}/upp/jsp/XML_authorize.jsp".freeze,
21
+ :xml_settlement_url => "#{BASE_URL_DEVELOPMENT}/upp/jsp/XML_processor.jsp".freeze,
22
+ :xml_status_url => "#{BASE_URL_DEVELOPMENT}/upp/jsp/XML_status.jsp".freeze
23
+ }.freeze
24
+ }.freeze
25
+
26
+ attr_reader :environment, :merchant_id, :sign_key, :proxy
27
+
28
+ # Configure with following options
29
+ # * :merchant_id (required)
30
+ # * :sign_key (defaults to false)
31
+ # * :environment (defaults to :development, available environments are defined in ENVIRONMENTS)
32
+ # * :proxy (a hash containing :http_proxyaddr, :http_proxyport, :http_proxyuser, :http_proxypass)
33
+ def initialize(options = {})
34
+ @merchant_id = options[:merchant_id]
35
+ raise ArgumentError.new(":merchant_id is required") unless self.merchant_id
36
+ self.environment = options[:environment] || DEFAULT_ENVIRONMENT
37
+ @sign_key = options[:sign_key] || DEFAULT_SIGN_KEY
38
+ @proxy = options[:proxy] || {}
39
+ end
40
+
41
+ def environment=(environment)
42
+ environment = environment.try(:to_sym)
43
+ if ENVIRONMENTS.include?(environment)
44
+ @environment = environment
45
+ else
46
+ raise "Unknown environment '#{environment}'. Available: #{ENVIRONMENTS.join(', ')}"
47
+ end
48
+ end
49
+
50
+ # Access a url, is automatically scoped to environment
51
+ def url(what)
52
+ URLS[self.environment][what]
53
+ end
54
+
55
+ def web_transaction(*args)
56
+ Web::Transaction.new(self, *args)
57
+ end
58
+
59
+ def xml_transaction(*args)
60
+ XML::Transaction.new(self, *args)
61
+ end
62
+ end
63
+ end
@@ -1,3 +1,3 @@
1
1
  module Datatrans
2
- VERSION = "2.4.0"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -5,11 +5,10 @@ module Datatrans::Web
5
5
  include Datatrans::Common
6
6
 
7
7
  attr_accessor :request
8
- attr_reader :response, :params
9
-
10
- def initialize(params)
11
- raise 'Please define Datatrans.sign_key or set it to false!' unless Datatrans.sign_key == false || Datatrans.sign_key.present?
8
+ attr_reader :response, :params, :datatrans
12
9
 
10
+ def initialize(datatrans, params)
11
+ @datatrans = datatrans
13
12
  params = params.to_hash
14
13
  params.symbolize_keys!
15
14
  params.reverse_merge!(:reqtype => 'NOA', :useAlias => 'yes', :hiddenMode => 'yes')
@@ -17,11 +16,11 @@ module Datatrans::Web
17
16
  end
18
17
 
19
18
  def signature
20
- sign(Datatrans.merchant_id, params[:amount], params[:currency], params[:refno])
19
+ sign(self.datatrans.merchant_id, params[:amount], params[:currency], params[:refno])
21
20
  end
22
21
 
23
22
  def authorize
24
- @response = AuthorizeResponse.new(params)
23
+ @response = AuthorizeResponse.new(datatrans, params)
25
24
  @response.successful?
26
25
  end
27
26
 
@@ -33,30 +32,6 @@ module Datatrans::Web
33
32
  end
34
33
  end
35
34
  end
36
-
37
- module ViewHelper
38
- def datatrans_notification_request_hidden_fields(transaction)
39
- fields = [
40
- hidden_field_tag(:merchantId, Datatrans.merchant_id),
41
- hidden_field_tag(:hiddenMode, transaction.params[:hiddenMode]),
42
- hidden_field_tag(:reqtype, transaction.params[:reqtype]),
43
- hidden_field_tag(:amount, transaction.params[:amount]),
44
- hidden_field_tag(:currency, transaction.params[:currency]),
45
- hidden_field_tag(:useAlias, transaction.params[:useAlias]),
46
- hidden_field_tag(:sign, transaction.signature),
47
- hidden_field_tag(:refno, transaction.params[:refno]),
48
- hidden_field_tag(:uppCustomerDetails, transaction.params[:uppCustomerDetails]),
49
- ]
50
-
51
- [:uppCustomerName, :uppCustomerEmail].each do |field_name|
52
- if transaction.params[field_name].present?
53
- fields << hidden_field_tag(field_name, transaction.params[field_name])
54
- end
55
- end
56
-
57
- fields.join.html_safe
58
- end
59
- end
60
35
  end
61
36
 
62
37
  require 'datatrans/web/transaction/authorize'
@@ -1,41 +1,43 @@
1
1
  class Datatrans::Web::Transaction
2
2
  class AuthorizeResponse
3
- attr_accessor :params
4
-
5
- def initialize(params)
3
+ attr_accessor :params, :datatrans
4
+
5
+ def initialize(datatrans, params)
6
+ @datatrans = datatrans
6
7
  @params = params
7
8
  end
8
-
9
+
9
10
  def successful?
10
11
  raise Datatrans::InvalidSignatureError unless valid_signature?
11
12
  response_code == '01' && response_message == 'Authorized' && !errors_occurred?
12
13
  end
13
-
14
+
14
15
  def valid_signature?
16
+ # TODO: does not make sense... true if errors?
15
17
  return true if errors_occurred? # no sign2 sent on error
16
- sign(Datatrans.merchant_id, params[:amount], params[:currency], params[:uppTransactionId]) == params[:sign2]
18
+ sign(self.datatrans.merchant_id, params[:amount], params[:currency], params[:uppTransactionId]) == params[:sign2]
17
19
  end
18
-
20
+
19
21
  def response_code
20
22
  params[:responseCode] rescue nil
21
23
  end
22
-
24
+
23
25
  def response_message
24
26
  params[:responseMessage] rescue nil
25
27
  end
26
-
28
+
27
29
  def transaction_id
28
- params[:uppTransactionId] rescue nil
30
+ params[:uppTransactionId] rescue nil
29
31
  end
30
-
32
+
31
33
  def reference_number
32
- params[:refno] rescue nil
34
+ params[:refno] rescue nil
33
35
  end
34
-
36
+
35
37
  def authorization_code
36
38
  params[:authorizationCode] rescue nil
37
39
  end
38
-
40
+
39
41
  def payment_method
40
42
  params[:pmethod] rescue nil
41
43
  end
@@ -43,38 +45,38 @@ class Datatrans::Web::Transaction
43
45
  def masked_cc
44
46
  params[:maskedCC] rescue nil
45
47
  end
46
-
48
+
47
49
  def exp_year
48
50
  params[:expy] rescue nil
49
51
  end
50
-
52
+
51
53
  def exp_month
52
54
  params[:expm] rescue nil
53
55
  end
54
-
56
+
55
57
  def creditcard_alias
56
58
  params[:aliasCC] rescue nil
57
59
  end
58
-
60
+
59
61
  def error_code
60
62
  params[:errorCode] rescue nil
61
63
  end
62
-
64
+
63
65
  def error_message
64
66
  params[:errorMessage] rescue nil
65
67
  end
66
-
68
+
67
69
  def error_detail
68
70
  params[:errorDetail] rescue nil
69
71
  end
70
-
71
-
72
+
73
+
72
74
  private
73
-
75
+
74
76
  def errors_occurred?
75
77
  error_code || error_message || error_detail
76
78
  end
77
-
79
+
78
80
  include Datatrans::Common
79
81
  end
80
82
  end