datatrans 4.0.1 → 5.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0b065ed93895deb3f8b801fe1060246a21e597bf2b5d3373b502ea6ce6f1ead
4
- data.tar.gz: 94f5cd63b06ee0af246adf8dd30a16790fde64e68d22ca53cf005852cfaa4263
3
+ metadata.gz: 6749673b2125a6a645cef06bd13d1a9d3f6f58276bd9e6abe18c287e0b821637
4
+ data.tar.gz: 26912c6b041d37f4af6872b5bfb138e0b9b90545058335c1f58407aa874125b9
5
5
  SHA512:
6
- metadata.gz: 11c4e5483bbcc2d9833348934fc6b54c7af958a6c41d3cae7a183c4614df56c2e09bfd06b23746ade55e4482c5aa3493edd6d5a3c5eb8fa9fd0680f196f101d4
7
- data.tar.gz: c286baa29ea0d26186a864fdd6b5a133a36ebb8c780bfe4d1484db83f5c36aa715ce434b247e93baa80964e3e9612522308f81ede13f7954da6c2e953970c93d
6
+ metadata.gz: 1f4ab534d4b3b8a684c42489c300fa6c7da8b442a4ec8faf168408712b8eb8318950dcfa25685f755826bb7270cf93adbdda7bc7a05778d8c4be4913437db439
7
+ data.tar.gz: d595075292ae69128eaf4f56f9c99eff69a736c91300fd2ced3baa2f4b918a5a15aa6b52ecfd0987a23e6ebf508c88239ba9075482b1dc6988540632c0f172bb
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: CI
3
- on: [push, pull_request]
3
+ on: [ push, pull_request ]
4
4
  jobs:
5
5
  tests:
6
6
  runs-on: ubuntu-latest
7
7
  strategy:
8
8
  fail-fast: false
9
9
  matrix:
10
- ruby: [ '2.6', '2.7', '3.0', '3.1' ]
10
+ ruby: [ '2.6', '2.7', '3.0', '3.1', '3.2' ]
11
11
  rails: [ '5-2', '6-0', '6-1', '7-0' ]
12
12
  exclude:
13
13
  - ruby: 2.6 # Rails 7 requires 2.7 minimum
@@ -20,6 +20,12 @@ jobs:
20
20
  rails: 6-0
21
21
  - ruby: 3.1
22
22
  rails: 6-1
23
+ - ruby: 3.2 # Ruby 3.2 only works on the latest Rails 7 version
24
+ rails: 5-2
25
+ - ruby: 3.2
26
+ rails: 6-0
27
+ - ruby: 3.2
28
+ rails: 6-1
23
29
 
24
30
  steps:
25
31
  - uses: actions/checkout@v2
data/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## 5.1.0 - 2023-07-06
9
+
10
+ ### Added
11
+
12
+ * Test against Ruby 3.2 (@andyundso [#43](https://github.com/simplificator/datatrans/pull/43))
13
+ * Add support for Datatrans JSON API (@TatianaPan [#45](https://github.com/simplificator/datatrans/pull/45)). Check Readme for details on how to use it.
14
+
15
+ XML API is [deprecated](https://mailchi.mp/datatrans/basic-authdynamic-sign_reminder) by Datatrans and will not be supported by them after June 3rd, 2024. Consider to moving to a [new JSON API](https://api-reference.datatrans.ch/).
16
+
17
+ ## 5.0.0 - 2022-09-21
18
+
19
+ ### Changed
20
+
21
+ * [BREAKING CHANGE] Authenticate requests with HTTP Basic Auth (@crackofdusk [#41](https://github.com/simplificator/datatrans/pull/41))
22
+
23
+ Datatrans requires [HTTP Basic Auth for XML API calls](https://api-reference.datatrans.ch/xml/#authentication-tls) since 2022-09-14 ([announcement](https://mailchi.mp/datatrans/basic-authsign2_1-email_en))
24
+
8
25
  ## 4.0.1 - 2022-03-18
9
26
  ### Fixed
10
27
  * Check for successful transaction depends on `status` and not on `response_message` that can be diferent for different payment methods (@schmijos [#8](https://github.com/simplificator/datatrans/pull/8) and @TatianaPan [#39](https://github.com/simplificator/datatrans/pull/39))
data/README.markdown CHANGED
@@ -8,9 +8,11 @@ Configuration
8
8
 
9
9
  Build your Datatrans Configuration like so:
10
10
 
11
+ ```ruby
11
12
  datatrans = Datatrans::Config.new(
12
13
  :merchant_id => '1234567',
13
14
  :sign_key => 'ab739fd5b7c2a1...',
15
+ :password => 'server to server request password',
14
16
  :environment => :production,
15
17
  :proxy => {
16
18
  :http_proxyaddr => "proxy.com",
@@ -19,7 +21,7 @@ Build your Datatrans Configuration like so:
19
21
  :http_proxpass => "xxx",
20
22
  }
21
23
  )
22
-
24
+ ```
23
25
 
24
26
  If you don't want to use signed requests (disabled in datatrans web console), you can set `config.sign_key` to `false`.
25
27
  The configuration is then used as parameter to all the constructors and helpers, see examples below.
@@ -32,6 +34,7 @@ Web Authorization
32
34
  If you want to process a credit card the first time a web authorization is
33
35
  necessary. Add the following code to a controller action that shows the form.
34
36
  You need to pass at least `amount`, `currency` and `refno` (order number).
37
+ ```ruby
35
38
  @transaction = datatrans.web_transaction(
36
39
  :amount => 1000, # in cents!
37
40
  :currency => 'CHF',
@@ -39,9 +42,11 @@ You need to pass at least `amount`, `currency` and `refno` (order number).
39
42
  :uppCustomerEmail => 'customer@email.com',
40
43
  # feel free to add more upp infos here ...
41
44
  )
45
+ ```
42
46
 
43
47
  In your View your show the credit card form with a convenient helper:
44
48
 
49
+ ```ruby
45
50
  = form_tag Datatrans.web_authorize_url do
46
51
 
47
52
  = text_field_tag :paymentmethod, 'ECA'
@@ -57,6 +62,7 @@ In your View your show the credit card form with a convenient helper:
57
62
  = datatrans_notification_request_hidden_fields(datatrans, @transaction)
58
63
 
59
64
  = submit_tag "send"
65
+ ```
60
66
 
61
67
  In this example we use just ECA (Mastercard) as paymentmethod. Feel free to
62
68
  provide an appropriate select field to offer more payment methods. Don't forget
@@ -65,7 +71,7 @@ to the same value.
65
71
 
66
72
  After you submit the request to Datatrans they redirect back to your application.
67
73
  Now you can process the transaction like this:
68
-
74
+ ```ruby
69
75
  begin
70
76
  transaction = datatrans.web_transaction(params)
71
77
 
@@ -85,16 +91,124 @@ Now you can process the transaction like this:
85
91
  rescue Datatrans::InvalidSignatureError => exception
86
92
  # the signature was wrong, the request may have been compromised...
87
93
  end
94
+ ```
95
+
96
+ JSON Transactions
97
+ =================
98
+
99
+ More information about Datatrans JSON API can be found [here](https://api-reference.datatrans.ch/). Our gem uses endpoints from `/v1/transactions` section.
100
+
101
+ We implemented support for [Redirect mode](https://docs.datatrans.ch/docs/redirect-lightbox) (since Lightbox mode may not work correctly on mobile, whereas Redirect works well on all devises).
102
+
103
+ Authorize
104
+ ---------
105
+
106
+ Authorize JSON transaction:
107
+
108
+ ```ruby
109
+ transaction = datatrans.json_transaction(
110
+ refno: 'ABCDEF',
111
+ amount: 1000, # in cents!
112
+ currency: "CHF",
113
+ payment_methods: ["ECA", "VIS"],
114
+ success_url: <your_application_return_url>,
115
+ cancel_url: <your_application_return_url>,
116
+ error_url: <your_application_return_url>
117
+ )
118
+
119
+ # call to init endpoint to initialize a transaction
120
+ # returns true or false depending if response was successful or not
121
+ init = transaction.authorize
122
+
123
+ # successful authorization call returns in response a transaction id
124
+ if init
125
+ transaction_id = transaction.response.params["transactionId"]
126
+ end
127
+ ```
128
+
129
+ Start a transaction
130
+ -------------------
131
+
132
+ Once you have a transaction id, you can start a transaction. Users of your application will be redirected to the datatrans payment pages: `https://pay.sandbox.datatrans.com/v1/start/{{transactionId}}`.
133
+
134
+ ```ruby
135
+ path = datatrans.json_transaction(transaction_id: transaction_id).transaction_path
136
+
137
+ redirect_to path
138
+ # or if you redirect after AJAX request:
139
+ render js: "window.location='#{path}'"
140
+ ```
141
+
142
+ You do not have to [settle a transaction](https://api-reference.datatrans.ch/#tag/v1transactions/operation/settle) by yourself: we set `"autoSettle": true` by default when authorizing a transaction, which means the transaction will be settled automatically.
143
+
144
+ Transaction status
145
+ ------------------
146
+
147
+ You can check the trasaction [status](https://api-reference.datatrans.ch/#tag/v1transactions/operation/status), see its history and retrieve the card information.
148
+
149
+ ```ruby
150
+ transaction = datatrans.json_transaction(transaction_id: transaction_id)
151
+
152
+ # status method returns true or false depending if response was successfull
153
+ if transaction.status
154
+ data = transaction.response.params
155
+ # this will return following hash (may vary dependong on your payment method):
156
+ {
157
+ "transactionId"=>"230223022302230223",
158
+ "merchantId"=>"1100000000",
159
+ "type"=>"payment",
160
+ "status"=>"settled",
161
+ "currency"=>"CHF",
162
+ "refno"=>"123456abc",
163
+ "paymentMethod"=>"VIS",
164
+ "detail"=>
165
+ {"authorize"=>{"amount"=>1000, "acquirerAuthorizationCode"=>"100000"}, "settle"=>{"amount"=>1000}},
166
+ "language"=>"en",
167
+ "card"=>
168
+ {"masked"=>"400000xxxxxx0018",
169
+ "expiryMonth"=>"06",
170
+ "expiryYear"=>"25",
171
+ "info"=>
172
+ {"brand"=>"VISA",
173
+ "type"=>"debit",
174
+ "usage"=>"consumer",
175
+ "country"=>"SE",
176
+ "issuer"=>"SVENSKA HANDELSBANKEN AB"},
177
+ "3D"=>{"authenticationResponse"=>"Y"}},
178
+ "history"=>
179
+ [{"action"=>"init",
180
+ "amount"=>1000,
181
+ "source"=>"api",
182
+ "date"=>"2023-06-06T08:37:23Z",
183
+ "success"=>true,
184
+ "ip"=>"8.8.8.8"},
185
+ {"action"=>"authorize",
186
+ "autoSettle"=>true,
187
+ "amount"=>1000,
188
+ "source"=>"redirect",
189
+ "date"=>"2023-06-06T08:37:42Z",
190
+ "success"=>true,
191
+ "ip"=>"8.8.8.8"}]
192
+ }
193
+ else
194
+ transaction.response.error_code
195
+ transaction.response.error_message
196
+ end
197
+ ```
198
+
88
199
 
89
200
  XML Transactions
90
201
  ================
91
202
 
203
+ XML API is [deprecated](https://mailchi.mp/datatrans/basic-authdynamic-sign_reminder) by Datatrans. After June 3rd, 2024 all merchants will have to use JSON API.
204
+
92
205
  If you have already a credit card alias or an authorized transaction you can
93
206
  use the convenient XML methods to process payments.
94
207
 
95
208
  Authorize
96
209
  ---------
97
210
 
211
+ ```ruby
98
212
  transaction = datatrans.xml_transaction(
99
213
  :refno => 'ABCDEF',
100
214
  :amount => 1000, # in cents!
@@ -110,6 +224,7 @@ Authorize
110
224
  else
111
225
  # transaction.error_code, transaction.error_message, transaction.error_detail
112
226
  end
227
+ ```
113
228
 
114
229
 
115
230
  Capture
@@ -117,6 +232,7 @@ Capture
117
232
 
118
233
  To capture an authorized transaction you use the following code:
119
234
 
235
+ ```ruby
120
236
  transaction = datatrans.xml_transaction(
121
237
  :refno => 'ABCDEF',
122
238
  :amount => 1000, # in cents!
@@ -129,13 +245,14 @@ To capture an authorized transaction you use the following code:
129
245
  else
130
246
  # transaction.error_code, transaction.error_message, transaction.error_detail
131
247
  end
132
-
248
+ ```
133
249
 
134
250
  Void
135
251
  ----
136
252
 
137
253
  To make an authorized transaction invalid use void.
138
254
 
255
+ ```ruby
139
256
  transaction = datatrans.xml_transaction(
140
257
  :refno => 'ABCDEF',
141
258
  :amount => 1000, # in cents!
@@ -148,6 +265,7 @@ To make an authorized transaction invalid use void.
148
265
  else
149
266
  # transaction.error_code, transaction.error_message, transaction.error_detail
150
267
  end
268
+ ```
151
269
 
152
270
  Todo
153
271
  ====
@@ -11,10 +11,11 @@ module Datatrans
11
11
  }
12
12
  DOMAIN = 'datatrans.com'
13
13
 
14
- attr_reader :environment, :merchant_id, :sign_key, :proxy
14
+ attr_reader :environment, :merchant_id, :sign_key, :password, :proxy
15
15
 
16
16
  # Configure with following options
17
17
  # * :merchant_id (required)
18
+ # * :password (required)
18
19
  # * :sign_key (defaults to false)
19
20
  # * :environment (defaults to :development, available environments are defined in ENVIRONMENTS)
20
21
  # * :proxy (a hash containing :http_proxyaddr, :http_proxyport, :http_proxyuser, :http_proxypass)
@@ -22,6 +23,8 @@ module Datatrans
22
23
  @merchant_id = options[:merchant_id]
23
24
  raise ArgumentError.new(":merchant_id is required") unless self.merchant_id
24
25
  self.environment = options[:environment] || DEFAULT_ENVIRONMENT
26
+ @password = options[:password]
27
+ raise ArgumentError.new(":password is required") unless self.password
25
28
  @sign_key = options[:sign_key] || DEFAULT_SIGN_KEY
26
29
  @proxy = options[:proxy] || {}
27
30
  end
@@ -36,7 +39,7 @@ module Datatrans
36
39
  end
37
40
 
38
41
  # Access a url, is automatically scoped to environment
39
- def url(what)
42
+ def url(what, options = {})
40
43
  case what
41
44
  when :web_authorize_url
42
45
  subdomain = SUBDOMAINS[:payment_page]
@@ -50,6 +53,16 @@ module Datatrans
50
53
  when :xml_status_url
51
54
  subdomain = SUBDOMAINS[:server_to_server_api]
52
55
  path = '/upp/jsp/XML_status.jsp'
56
+ when :init_transaction
57
+ subdomain = SUBDOMAINS[:server_to_server_api]
58
+ path = "/v1/transactions"
59
+ when :start_json_transaction
60
+ subdomain = SUBDOMAINS[:payment_page]
61
+ path = "/v1/start/#{options[:transaction_id]}"
62
+ when :json_status_url
63
+ # https://api.sandbox.datatrans.com/v1/transactions/{transactionId}
64
+ subdomain = SUBDOMAINS[:server_to_server_api]
65
+ path = "/v1/transactions/#{options[:transaction_id]}"
53
66
  else
54
67
  raise "Unknown wanted action '#{what}'."
55
68
  end
@@ -64,5 +77,9 @@ module Datatrans
64
77
  def xml_transaction(*args)
65
78
  XML::Transaction.new(self, *args)
66
79
  end
80
+
81
+ def json_transaction(*args)
82
+ JSON::Transaction.new(self, *args)
83
+ end
67
84
  end
68
85
  end
@@ -0,0 +1,48 @@
1
+ require 'httparty'
2
+ require 'datatrans/json/transaction/response'
3
+
4
+ class Datatrans::JSON::Transaction
5
+ class Authorize
6
+ # class to initialize a new transaction https://api-reference.datatrans.ch/#tag/v1transactions/operation/init
7
+ attr_accessor :params, :datatrans
8
+
9
+ def initialize(datatrans, params)
10
+ @datatrans = datatrans
11
+ @params = params
12
+ end
13
+
14
+ def post(url, options = {})
15
+ options = options
16
+ .merge(self.datatrans.proxy)
17
+ .merge(:basic_auth => { :username => self.datatrans.merchant_id, :password => self.datatrans.password })
18
+ HTTParty.post(url, **options)
19
+ end
20
+
21
+ def process
22
+ post(self.datatrans.url(:init_transaction),
23
+ :headers => { 'Content-Type' => 'application/json' },
24
+ :body => request_body.to_json).parsed_response
25
+ end
26
+
27
+ def request_body
28
+ {
29
+ "currency": params[:currency],
30
+ "refno": params[:refno],
31
+ "amount": params[:amount],
32
+ "autoSettle": true,
33
+ "paymentMethods": params[:payment_methods],
34
+ "redirect": {
35
+ "successUrl": params[:success_url],
36
+ "cancelUrl": params[:cancel_url],
37
+ "errorUrl": params[:error_url]
38
+ }
39
+ }
40
+ end
41
+ end
42
+
43
+ class AuthorizeResponse < Response
44
+ def successful?
45
+ params["error"].blank? && params["transactionId"].present?
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,22 @@
1
+ class Datatrans::JSON::Transaction
2
+ class Response
3
+ attr_accessor :params, :datatrans
4
+
5
+ def initialize(datatrans, params)
6
+ @datatrans = datatrans
7
+ @params = params
8
+ end
9
+
10
+ def successful?
11
+ raise 'overwrite in subclass!'
12
+ end
13
+
14
+ def error_code
15
+ params["error"]["code"] rescue nil
16
+ end
17
+
18
+ def error_message
19
+ params["error"]["message"] rescue nil
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,44 @@
1
+ require 'httparty'
2
+ require 'datatrans/json/transaction/response'
3
+
4
+ class Datatrans::JSON::Transaction
5
+ class Status
6
+ # class to check a transaction status and get a transaction info: https://api-reference.datatrans.ch/#tag/v1transactions/operation/status
7
+ attr_accessor :params, :datatrans
8
+
9
+ def initialize(datatrans, params)
10
+ @datatrans = datatrans
11
+ @params = params
12
+ end
13
+
14
+ def get(url, options = {})
15
+ options = options
16
+ .merge(self.datatrans.proxy)
17
+ .merge(:basic_auth => { :username => self.datatrans.merchant_id, :password => self.datatrans.password })
18
+ HTTParty.get(url, **options)
19
+ end
20
+
21
+ def process
22
+ get(self.datatrans.url(:json_status_url, transaction_id: params[:transaction_id]),
23
+ :headers => { 'Content-Type' => 'application/json' }).parsed_response
24
+ end
25
+ end
26
+
27
+ class StatusResponse < Response
28
+ def successful?
29
+ params["error"].blank? && ["settled", "transmitted"].include?(response_code)
30
+ end
31
+
32
+ def response_code
33
+ params["status"] rescue nil
34
+ end
35
+
36
+ def reference_number
37
+ params["refno"] rescue nil
38
+ end
39
+
40
+ def amount
41
+ params["detail"]["settle"]["amount"] rescue nil
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,32 @@
1
+ require 'active_support/core_ext/hash'
2
+
3
+ module Datatrans::JSON
4
+ class Transaction
5
+ attr_accessor :request
6
+ attr_reader :response, :params, :datatrans
7
+
8
+ def initialize(datatrans, params)
9
+ @datatrans = datatrans
10
+ @params = params
11
+ end
12
+
13
+ def authorize
14
+ self.request = Authorize.new(self.datatrans, params)
15
+ @response = AuthorizeResponse.new(self.datatrans, request.process)
16
+ @response.successful?
17
+ end
18
+
19
+ def status
20
+ self.request = Status.new(self.datatrans, params)
21
+ @response = StatusResponse.new(self.datatrans, request.process)
22
+ @response.successful?
23
+ end
24
+
25
+ def transaction_path
26
+ self.datatrans.url(:start_json_transaction, transaction_id: params[:transaction_id])
27
+ end
28
+ end
29
+ end
30
+
31
+ require 'datatrans/json/transaction/authorize'
32
+ require 'datatrans/json/transaction/status'
@@ -1,3 +1,3 @@
1
1
  module Datatrans
2
- VERSION = "4.0.1"
2
+ VERSION = "5.1.0"
3
3
  end
@@ -7,7 +7,9 @@ class Datatrans::XML::Transaction
7
7
  attr_accessor :params, :datatrans
8
8
 
9
9
  def post(url, options = {})
10
- options = options.merge(self.datatrans.proxy)
10
+ options = options
11
+ .merge(self.datatrans.proxy)
12
+ .merge(:basic_auth => { :username => self.datatrans.merchant_id, :password => self.datatrans.password })
11
13
  HTTParty.post(url, **options)
12
14
  end
13
15
 
@@ -39,4 +41,4 @@ class Datatrans::XML::Transaction
39
41
  xml.target!
40
42
  end
41
43
  end
42
- end
44
+ end
data/lib/datatrans.rb CHANGED
@@ -9,6 +9,7 @@ require 'datatrans/common'
9
9
  require 'datatrans/config'
10
10
  require 'datatrans/xml/transaction'
11
11
  require 'datatrans/web/transaction'
12
+ require 'datatrans/json/transaction'
12
13
 
13
14
  begin
14
15
  require 'action_view'
data/spec/config_spec.rb CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Datatrans::Config do
4
4
  describe "Instance Methods" do
5
5
  before do
6
- @datatrans = Datatrans::Config.new(:merchant_id => "xxx")
6
+ @datatrans = Datatrans::Config.new(:merchant_id => "xxx", :password => "yyy")
7
7
  end
8
8
 
9
9
  describe "web_transaction" do
@@ -17,5 +17,11 @@ describe Datatrans::Config do
17
17
  expect(@datatrans.xml_transaction({}).class).to eq(Datatrans::XML::Transaction)
18
18
  end
19
19
  end
20
+
21
+ describe "json_transaction" do
22
+ it "builds a new json transaction object" do
23
+ expect(@datatrans.json_transaction({}).class).to eq(Datatrans::JSON::Transaction)
24
+ end
25
+ end
20
26
  end
21
27
  end
@@ -0,0 +1,79 @@
1
+ require "spec_helper"
2
+
3
+ describe Datatrans::JSON::Transaction::Authorize do
4
+ before do
5
+ @successful_response = {
6
+ "transactionId" => "230223022302230223"
7
+ }
8
+
9
+ @failed_response = {
10
+ "error" => {
11
+ "code" => "INVALID_PROPERTY",
12
+ "message" => "init.refno must not be null"
13
+ }
14
+ }
15
+
16
+ @valid_params = {
17
+ currency: "CHF",
18
+ refno: "B4B4B4B4B",
19
+ amount: 1337,
20
+ payment_methods: ["ECA", "VIS"],
21
+ success_url: "https://pay.sandbox.datatrans.com/upp/merchant/successPage.jsp",
22
+ cancel_url: "https://pay.sandbox.datatrans.com/upp/merchant/cancelPage.jsp",
23
+ error_url: "https://pay.sandbox.datatrans.com/upp/merchant/errorPage.jsp"
24
+ }
25
+
26
+ @invalid_params = {
27
+ currency: "CHF",
28
+ refno: nil,
29
+ amount: 1337,
30
+ payment_methods: ["ECA", "VIS"],
31
+ }
32
+ end
33
+
34
+ context "successful response" do
35
+ before do
36
+ allow_any_instance_of(Datatrans::JSON::Transaction::Authorize).to receive(:process).and_return(@successful_response)
37
+ end
38
+
39
+ it "generates correct request_body" do
40
+ expected = {
41
+ "currency": "CHF",
42
+ "refno": "B4B4B4B4B",
43
+ "amount": 1337,
44
+ "autoSettle": true,
45
+ "paymentMethods": ["ECA", "VIS"],
46
+ "redirect": {
47
+ "successUrl": "https://pay.sandbox.datatrans.com/upp/merchant/successPage.jsp",
48
+ "cancelUrl": "https://pay.sandbox.datatrans.com/upp/merchant/cancelPage.jsp",
49
+ "errorUrl": "https://pay.sandbox.datatrans.com/upp/merchant/errorPage.jsp"
50
+ }
51
+ }
52
+ request = Datatrans::JSON::Transaction::Authorize.new(@datatrans, @valid_params)
53
+
54
+ expect(request.request_body).to eq(expected)
55
+ end
56
+
57
+ it "#process handles a valid datatrans authorize response" do
58
+ @transaction = Datatrans::JSON::Transaction.new(@datatrans, @valid_params)
59
+ expect(@transaction.authorize).to be true
60
+ end
61
+ end
62
+
63
+ context "failed response" do
64
+ before do
65
+ allow_any_instance_of(Datatrans::JSON::Transaction::Authorize).to receive(:process).and_return(@failed_response)
66
+ @transaction = Datatrans::JSON::Transaction.new(@datatrans, @invalid_params)
67
+ end
68
+
69
+ it "#process handles a failed datatrans authorize response" do
70
+ expect(@transaction.authorize).to be false
71
+ end
72
+
73
+ it "returns error details" do
74
+ @transaction.authorize
75
+ expect(@transaction.response.error_code).to eq "INVALID_PROPERTY"
76
+ expect(@transaction.response.error_message).to eq "init.refno must not be null"
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ describe Datatrans::JSON::Transaction::Status do
4
+ before do
5
+ @successful_response = {
6
+ "transactionId" => "230223022302230223",
7
+ "merchantId" => "1100000000",
8
+ "type" => "payment",
9
+ "status" => "settled",
10
+ "currency" => "CHF",
11
+ "refno" => "B4B4B4B4B",
12
+ "paymentMethod" => "VIS",
13
+ "detail" => {
14
+ "authorize" => {}
15
+ },
16
+ "card" => {
17
+ "masked" => "424242xxxxxx4242",
18
+ "expiryMonth" => "06",
19
+ "expiryYear" => "25",
20
+ "info" => {}
21
+ },
22
+ "history" => [
23
+ {
24
+ "action" => "authorize",
25
+ "amount" => 1000,
26
+ "source" => "api",
27
+ "date" => "2023-02-08T14:25:24Z",
28
+ "success" => true,
29
+ "ip" => "8.8.8.8"
30
+ }
31
+ ]
32
+ }
33
+
34
+ @failed_response = {
35
+ "error" => {
36
+ "code" => "INVALID_PROPERTY",
37
+ "message" => "status transactionId length must be 18 digits"
38
+ }
39
+ }
40
+
41
+ @valid_params = {
42
+ transaction_id: '230223022302230223',
43
+ }
44
+
45
+ @invalid_params = {
46
+ transaction_id: '0208020802080208', # wrong number of digits in ID
47
+ }
48
+ end
49
+
50
+ context "successful response" do
51
+ before do
52
+ allow_any_instance_of(Datatrans::JSON::Transaction::Status).to receive(:process).and_return(@successful_response)
53
+ end
54
+
55
+ it "#process handles a valid datatrans status response" do
56
+ transaction = Datatrans::JSON::Transaction.new(@datatrans, @valid_params)
57
+ expect(transaction.status).to be true
58
+ expect(transaction.response.params["refno"]).to eq "B4B4B4B4B"
59
+ expect(transaction.response.params["paymentMethod"]).to eq "VIS"
60
+ end
61
+ end
62
+
63
+ context "failed response" do
64
+ before do
65
+ allow_any_instance_of(Datatrans::JSON::Transaction::Status).to receive(:process).and_return(@failed_response)
66
+ @transaction = Datatrans::JSON::Transaction.new(@datatrans, @invalid_params)
67
+ end
68
+
69
+ it "handles a failed datatrans status response" do
70
+ expect(@transaction.status).to be false
71
+ expect(@transaction.response.error_code).to eq "INVALID_PROPERTY"
72
+ expect(@transaction.response.error_message).to eq "status transactionId length must be 18 digits"
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,10 @@
1
+ require "spec_helper"
2
+
3
+ describe Datatrans::JSON::Transaction do
4
+ it "returns correct trasaction_path" do
5
+ params = {transaction_id: "230223022302230223"}
6
+ transaction = Datatrans::JSON::Transaction.new(@datatrans, params)
7
+
8
+ expect(transaction.transaction_path).to eq "https://pay.sandbox.datatrans.com/v1/start/230223022302230223"
9
+ end
10
+ end
data/spec/spec_helper.rb CHANGED
@@ -15,6 +15,7 @@ RSpec.configure do |config|
15
15
  @datatrans = Datatrans::Config.new(
16
16
  :merchant_id => '1100000000',
17
17
  :sign_key => 'd777c17ba2010282c2d2350a68b441ca07a799d294bfaa630b7c8442207c0b69703cc55775b0ca5a4e455b818a9bb10a43669c0c20ce31f4a43f10e0cabb9525',
18
+ :password => 'basic_auth_password',
18
19
  :environment => :development
19
20
  )
20
21
  end
@@ -7,6 +7,7 @@ describe Datatrans::XML::Transaction::Request do
7
7
  @datatrans = Datatrans::Config.new(
8
8
  :merchant_id => '1100000000',
9
9
  :sign_key => 'd777c17ba2010282c2d2350a68b441ca07a799d294bfaa630b7c8442207c0b69703cc55775b0ca5a4e455b818a9bb10a43669c0c20ce31f4a43f10e0cabb9525',
10
+ :password => 'basic_auth_password',
10
11
  :key => "value",
11
12
  :proxy => {
12
13
  :http_proxyaddr => "proxy.com",
@@ -21,6 +22,7 @@ describe Datatrans::XML::Transaction::Request do
21
22
  it "forward those options to HTTParty" do
22
23
  request = Datatrans::XML::Transaction::Request.new(@datatrans, {})
23
24
  expect(HTTParty).to receive(:post).with('lirum',
25
+ :basic_auth => {:password => 'basic_auth_password', :username => '1100000000'},
24
26
  :params => {:foo => :bar},
25
27
  :http_proxpass => 'xxx',
26
28
  :http_proxyuser => 'hans',
@@ -33,7 +35,7 @@ describe Datatrans::XML::Transaction::Request do
33
35
  describe "not configured" do
34
36
  it "should not add any proxy settings" do
35
37
  request = Datatrans::XML::Transaction::Request.new(@datatrans, {})
36
- expect(HTTParty).to receive(:post).with('lirum', :params => {:foo => :bar})
38
+ expect(HTTParty).to receive(:post).with('lirum', :basic_auth => {:password => 'basic_auth_password', :username => '1100000000'}, :params => {:foo => :bar})
37
39
  request.post('lirum', :params => {:foo => :bar})
38
40
  end
39
41
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datatrans
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Miesel
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2022-03-18 00:00:00.000000000 Z
14
+ date: 2023-07-06 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: httparty
@@ -165,6 +165,10 @@ files:
165
165
  - lib/datatrans.rb
166
166
  - lib/datatrans/common.rb
167
167
  - lib/datatrans/config.rb
168
+ - lib/datatrans/json/transaction.rb
169
+ - lib/datatrans/json/transaction/authorize.rb
170
+ - lib/datatrans/json/transaction/response.rb
171
+ - lib/datatrans/json/transaction/status.rb
168
172
  - lib/datatrans/version.rb
169
173
  - lib/datatrans/web/transaction.rb
170
174
  - lib/datatrans/web/transaction/authorize.rb
@@ -178,6 +182,9 @@ files:
178
182
  - lib/datatrans/xml/transaction/void.rb
179
183
  - spec/common_spec.rb
180
184
  - spec/config_spec.rb
185
+ - spec/json/authorize_spec.rb
186
+ - spec/json/status_spec.rb
187
+ - spec/json/transaction_spec.rb
181
188
  - spec/spec_helper.rb
182
189
  - spec/web/authorize_spec.rb
183
190
  - spec/xml/authorize_spec.rb