active_merchant-epsilon 0.13.0 → 0.14.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: c43c4d71a9719ec55be94aa1f66222eac8bead4b16db6a31611269aee844afcf
4
- data.tar.gz: 6bb0b39a5598d3cb8718037df3fd00ff42a53cded61bc98529a4ad00aa9f4259
3
+ metadata.gz: 8fe0b19a8605e29e5c3a2a310e3b9684767a21fb2f93957342ffd41b9135657e
4
+ data.tar.gz: b8eb1a2b4d150c0696d26a52e58f5069a60542739bc6461d61f864ad20a470db
5
5
  SHA512:
6
- metadata.gz: 164e39f8d0e343f0172e5371fc99d1c46d8d04346c8e0c135ac7478cbe507be36d6182913df016e510eb75073559ad9d59b042718f3c26fa5fb6a37c20e940f6
7
- data.tar.gz: 1b5e435a9342d69b78e032d466fb3f930805912bb2c4ac24eb7e7d9ce2bcf652a5b15f050ab38ad3526929cda5cc00ac32d0f540828226d97a0ca69ab986f845
6
+ metadata.gz: 87d7533d96fd6591a2b4ffeb78c7cfe2de4ad987e41c58be72083672f346178be6fa593e3aad6a5f3b66b0dde708e883d6d82a8c864a05006589d33a2978b41c
7
+ data.tar.gz: '0782a6f4c48fcc0e905a7b72205d5511bea0ffa95ca285dceee5058d97ae0d63e25fc2e2b009910b800c398b2cb07451cb525f8d0ee1f58696228c487f2f4106'
@@ -1,6 +1,9 @@
1
1
  name: test
2
- on: push
3
-
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+ pull_request:
4
7
  jobs:
5
8
  test-all:
6
9
  runs-on: ubuntu-latest
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ### 0.14.0
4
+
5
+ - [Support 3D Secure 2.0 for credit card payments](https://github.com/pepabo/active_merchant-epsilon/pull/121)
6
+
3
7
  ### 0.13.0
4
8
 
5
9
  - [Add `last-update` to OrderResponse](https://github.com/pepabo/active_merchant-epsilon/pull/118)
data/README.md CHANGED
@@ -159,6 +159,57 @@ purchase_detail = {
159
159
  # (snip)
160
160
  ```
161
161
 
162
+ ### CreditCard Payment with 3D secure 2.0(with token)
163
+
164
+ ```ruby
165
+ # 3D secure 2.0 does not have a test environment for epsilon
166
+ ActiveMerchant::Billing::Base.mode = :production
167
+
168
+ amount = 1000
169
+ purchase_detail = {
170
+ user_id: 'YOUR_APP_USER_IDENTIFIER',
171
+ user_name: '山田 太郎',
172
+ user_email: 'yamada-taro@example.com',
173
+ item_code: 'ITEM001',
174
+ item_name: 'Greate Product',
175
+ order_number: 'UNIQUE ORDER NUMBER',
176
+ three_d_secure_check_code: 1,
177
+ token: 'CREDIT CARD TOKEN'
178
+ tds_flag: 21 # 21 or 22
179
+ # optional:
180
+ # add params for risk-based certification(billAddrCity etc...)
181
+ }
182
+
183
+ response = gateway.purchase(amount, ActiveMerchant::Billing::CreditCard.new, purchase_detail)
184
+
185
+ if response.success?
186
+ if response.params['three_d_secure']
187
+ puts response.params['tds2_url']
188
+ puts response.params['pa_req']
189
+ else
190
+ # NOT 3D SECURE
191
+ puts "Successfully charged #{amount} yen as credit card payment(not 3D secure)"
192
+ end
193
+ else
194
+ raise StandardError, response.message
195
+ end
196
+
197
+ # (The card holder identifies himself on credit card's page and comes back here)
198
+
199
+ # AND SECOND REQUEST
200
+
201
+ response = gateway.authenticate(
202
+ order_number: 'ORDER NUMBER',
203
+ three_d_secure_pares: 'PAYMENT AUTHENTICATION RESPONSE',
204
+ )
205
+
206
+ if response.success?
207
+ puts 'Successfully charged as credit card payment(3D secure 2.0)'
208
+ else
209
+ raise StandardError, response.message
210
+ end
211
+ ```
212
+
162
213
  ### CreditCard Revolving Payment
163
214
 
164
215
  ```ruby
@@ -48,6 +48,7 @@ module ActiveMerchant #:nodoc:
48
48
  :three_d_secure,
49
49
  :acs_url,
50
50
  :pa_req,
51
+ :tds2_url,
51
52
  :receipt_number,
52
53
  :receipt_date,
53
54
  :captured,
@@ -22,6 +22,20 @@ module ActiveMerchant #:nodoc:
22
22
  capture: 'sales_payment.cgi',
23
23
  }.freeze
24
24
 
25
+ RISK_BASE_AUTH_PARAMS_KEYS = %i[
26
+ tds_flag billAddrCity billAddrCountry billAddrLine1 billAddrLine2 billAddrLine3
27
+ billAddrPostCode billAddrState shipAddrCity shipAddrCountry shipAddrLine1 shipAddrLine2
28
+ shipAddrLine3 shipAddrPostCode shipAddrState chAccAgeInd chAccChange
29
+ chAccChangeIndchAccDate chAccPwdChange chAccPwChangeInd nbPurchaseAccount paymentAccAge
30
+ paymentAccInd provisionAttemptsDay shipAddressUsage shipAddressUsageInd shipNameIndicator
31
+ suspiciousAccActivity txnActivityDay txnActivityYear threeDSReqAuthData threeDSReqAuthMethod
32
+ threeDSReqAuthTimestamp addrMatch cardholderName homePhone mobilePhone
33
+ workPhone challengeInd deliveryEmailAddress deliveryTimeframe giftCardAmount
34
+ giftCardCount preOrderDate preOrderPurchaseInd reorderItemsInd shipIndicator
35
+ ].freeze
36
+
37
+ THREE_D_SECURE_2_INDICATORS = [21, 22].freeze
38
+
25
39
  self.supported_cardtypes = [:visa, :master, :american_express, :discover]
26
40
 
27
41
  def purchase(amount, credit_card, detail = {})
@@ -29,6 +43,10 @@ module ActiveMerchant #:nodoc:
29
43
 
30
44
  params = billing_params(amount, credit_card, detail)
31
45
 
46
+ if three_d_secure_2?(detail)
47
+ params.merge!(detail.slice(*RISK_BASE_AUTH_PARAMS_KEYS).compact)
48
+ end
49
+
32
50
  commit(PATHS[:purchase], params)
33
51
  end
34
52
 
@@ -54,6 +72,10 @@ module ActiveMerchant #:nodoc:
54
72
  params[:memo2] = detail[:memo2] if detail.has_key?(:memo2)
55
73
  params[:kari_flag] = detail[:capture] ? 2 : 1 if detail.has_key?(:capture)
56
74
 
75
+ if three_d_secure_2?(detail)
76
+ params.merge!(detail.slice(*RISK_BASE_AUTH_PARAMS_KEYS).compact)
77
+ end
78
+
57
79
  commit(PATHS[:registered_purchase], params)
58
80
  end
59
81
 
@@ -239,6 +261,10 @@ module ActiveMerchant #:nodoc:
239
261
 
240
262
  params
241
263
  end
264
+
265
+ def three_d_secure_2?(detail)
266
+ THREE_D_SECURE_2_INDICATORS.include?(detail[:tds_flag])
267
+ end
242
268
  end
243
269
  end
244
270
  end
@@ -10,7 +10,7 @@ module ActiveMerchant #:nodoc:
10
10
  @result = @xml.xpath(ResponseXpath::RESULT).to_s
11
11
 
12
12
  response = {
13
- success: [ResultCode::SUCCESS, ResultCode::THREE_D_SECURE].include?(@result) || !state.empty?,
13
+ success: [ResultCode::SUCCESS, ResultCode::THREE_D_SECURE_1, ResultCode::THREE_D_SECURE_2].include?(@result) || !state.empty?,
14
14
  message: "#{error_code}: #{error_detail}"
15
15
  }
16
16
 
@@ -48,7 +48,7 @@ module ActiveMerchant #:nodoc:
48
48
  end
49
49
 
50
50
  def three_d_secure
51
- @result == ResultCode::THREE_D_SECURE
51
+ [ResultCode::THREE_D_SECURE_1, ResultCode::THREE_D_SECURE_2].include?(@result)
52
52
  end
53
53
 
54
54
  def acs_url
@@ -59,6 +59,10 @@ module ActiveMerchant #:nodoc:
59
59
  uri_decode(@xml.xpath(ResponseXpath::PA_REQ).to_s)
60
60
  end
61
61
 
62
+ def tds2_url
63
+ uri_decode(@xml.xpath(ResponseXpath::TDS2_URL).to_s)
64
+ end
65
+
62
66
  def receipt_number
63
67
  @xml.xpath(ResponseXpath::RECEIPT_NUMBER).to_s
64
68
  end
@@ -145,6 +149,7 @@ module ActiveMerchant #:nodoc:
145
149
  CARD_EXPIRE = '//Epsilon_result/result[@card_expire]/@card_expire'
146
150
  ACS_URL = '//Epsilon_result/result[@acsurl]/@acsurl' # ACS (Access Control Server)
147
151
  PA_REQ = '//Epsilon_result/result[@pareq]/@pareq' # PAReq (payer authentication request)
152
+ TDS2_URL = '//Epsilon_result/result[@tds2_url]/@tds2_url'
148
153
  RECEIPT_NUMBER = '//Epsilon_result/result[@receipt_no][1]/@receipt_no'
149
154
  RECEIPT_DATE = '//Epsilon_result/result[@receipt_date][1]/@receipt_date'
150
155
  CONVENIENCE_STORE_LIMIT_DATE = '//Epsilon_result/result[@conveni_limit][1]/@conveni_limit'
@@ -166,10 +171,11 @@ module ActiveMerchant #:nodoc:
166
171
  end
167
172
 
168
173
  module ResultCode
169
- FAILURE = '0'
170
- SUCCESS = '1'
171
- THREE_D_SECURE = '5'
172
- SYSTEM_ERROR = '9'
174
+ FAILURE = '0'
175
+ SUCCESS = '1'
176
+ THREE_D_SECURE_1 = '5'
177
+ THREE_D_SECURE_2 = '6'
178
+ SYSTEM_ERROR = '9'
173
179
  end
174
180
  end
175
181
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveMerchant
2
2
  module Epsilon
3
- VERSION = "0.13.0"
3
+ VERSION = "0.14.0"
4
4
  end
5
5
  end
@@ -0,0 +1,51 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://secure.epsilon.jp/cgi-bin/order/direct_card_payment.cgi
6
+ body:
7
+ encoding: UTF-8
8
+ string: contract_code=[CONTRACT_CODE]&order_number=O30189731&tds_check_code=2&tds_pares=dummy+pa_res
9
+ headers:
10
+ Content-Type:
11
+ - application/x-www-form-urlencoded
12
+ Connection:
13
+ - close
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ Accept:
17
+ - "*/*"
18
+ User-Agent:
19
+ - Ruby
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Thu, 15 Sep 2022 08:09:38 GMT
27
+ Server:
28
+ - Apache
29
+ Vary:
30
+ - Accept-Encoding
31
+ Content-Length:
32
+ - '161'
33
+ Connection:
34
+ - close
35
+ Content-Type:
36
+ - text/xml; charset=CP932
37
+ body:
38
+ encoding: ASCII-8BIT
39
+ string: |-
40
+ <?xml version="1.0" encoding="x-sjis-cp932"?>
41
+ <Epsilon_result>
42
+ <result acsurl="" />
43
+ <result err_code="" />
44
+ <result err_detail="" />
45
+ <result kari_flag="0" />
46
+ <result pareq="" />
47
+ <result result="1" />
48
+ <result trans_code="257072796" />
49
+ </Epsilon_result>
50
+ recorded_at: Thu, 15 Sep 2022 08:09:38 GMT
51
+ recorded_with: VCR 6.1.0
@@ -0,0 +1,51 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://secure.epsilon.jp/cgi-bin/order/direct_card_payment.cgi
6
+ body:
7
+ encoding: UTF-8
8
+ string: contract_code=[CONTRACT_CODE]&user_id=124014051&user_name=YAMADA+TARO&user_mail_add=yamada-taro%40example.com&item_code=ITEM001&item_name=Greate+Product&order_number=O1663728963&st_code=10000-0000-0000&mission_code=1&item_price=1000&process_code=2&card_st_code=&pay_time=&xml=1&tds_flag=21
9
+ headers:
10
+ Content-Type:
11
+ - application/x-www-form-urlencoded
12
+ Connection:
13
+ - close
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ Accept:
17
+ - "*/*"
18
+ User-Agent:
19
+ - Ruby
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Wed, 21 Sep 2022 02:56:03 GMT
27
+ Server:
28
+ - Apache
29
+ Vary:
30
+ - Accept-Encoding
31
+ Content-Length:
32
+ - '234'
33
+ Connection:
34
+ - close
35
+ Content-Type:
36
+ - text/xml; charset=CP932
37
+ body:
38
+ encoding: ASCII-8BIT
39
+ string: |-
40
+ <?xml version="1.0" encoding="x-sjis-cp932"?>
41
+ <Epsilon_result>
42
+ <result acsurl="" />
43
+ <result err_code="" />
44
+ <result err_detail="" />
45
+ <result pareq="sOuxTX%252BZHCDBJKRdKkN2Iw53" />
46
+ <result result="6" />
47
+ <result tds2_url="https%3A%2F%2Fsecure.epsilon.jp%2Fcgi-bin%2Forder%2Ftds2.cgi" />
48
+ <result trans_code="257810878" />
49
+ </Epsilon_result>
50
+ recorded_at: Wed, 21 Sep 2022 02:56:04 GMT
51
+ recorded_with: VCR 6.1.0
@@ -75,6 +75,34 @@ class RemoteEpsilonGatewayTest < MiniTest::Test
75
75
  end
76
76
  end
77
77
 
78
+ def test_purchase_with_three_d_secure_2_successful
79
+ # 3DS2.0はテスト環境がないので mode を :production にする
80
+ ActiveMerchant::Billing::Base.stub(:mode, :production) do
81
+ VCR.use_cassette(:purchase_with_three_d_secure_2_successful) do
82
+ response = gateway.purchase(
83
+ 1000,
84
+ ActiveMerchant::Billing::CreditCard.new,
85
+ purchase_detail_for_three_d_secure_2
86
+ )
87
+
88
+ assert_equal true, response.success?
89
+ assert_equal true, response.params['three_d_secure']
90
+ assert_equal true, response.params['tds2_url'].present?
91
+ assert_equal true, response.params['pa_req'].present?
92
+ assert_empty response.params['acs_url']
93
+ end
94
+
95
+ VCR.use_cassette(:authenticate_with_three_d_secure_2_successful) do
96
+ response = gateway.authenticate(
97
+ order_number: purchase_detail_for_three_d_secure_2[:order_number],
98
+ three_d_secure_pa_res: 'dummy pa_res'
99
+ )
100
+
101
+ assert_equal true, response.success?
102
+ end
103
+ end
104
+ end
105
+
78
106
  def test_purchase_with_capture_true_successful
79
107
  VCR.use_cassette(:purchase_with_capture_true_successful) do
80
108
  response = gateway.purchase(1000, valid_credit_card, purchase_detail.merge(capture: true))
@@ -256,6 +284,30 @@ class RemoteEpsilonGatewayTest < MiniTest::Test
256
284
  end
257
285
  end
258
286
 
287
+ def test_registered_purchase_with_three_d_secure_2_successful
288
+ # 3DS2.0はテスト環境がないので mode を :production にする
289
+ ActiveMerchant::Billing::Base.stub(:mode, :production) do
290
+ VCR.use_cassette(:purchase_with_three_d_secure_2_successful) do
291
+ response = gateway.registered_purchase(1000, purchase_detail_for_registered_and_three_d_secure_2)
292
+
293
+ assert_equal true, response.success?
294
+ assert_equal true, response.params['three_d_secure']
295
+ assert_equal true, response.params['tds2_url'].present?
296
+ assert_equal true, response.params['pa_req'].present?
297
+ assert_empty response.params['acs_url']
298
+ end
299
+
300
+ VCR.use_cassette(:authenticate_with_three_d_secure_2_successful) do
301
+ response = gateway.authenticate(
302
+ order_number: purchase_detail_for_three_d_secure_2[:order_number],
303
+ three_d_secure_pa_res: 'dummy pa_res'
304
+ )
305
+
306
+ assert_equal true, response.success?
307
+ end
308
+ end
309
+ end
310
+
259
311
  def test_registered_purchase_fail
260
312
  VCR.use_cassette(:registered_purchase_fail) do
261
313
  invalid_purchase_detail = purchase_detail_for_registered
data/test/test_helper.rb CHANGED
@@ -156,6 +156,33 @@ module SamplePaymentMethods
156
156
  }
157
157
  end
158
158
 
159
+ def purchase_detail_for_three_d_secure_2
160
+ now = Time.now
161
+ {
162
+ user_id: "U#{now.to_i}",
163
+ user_name: 'YAMADA Taro',
164
+ user_email: 'yamada-taro@example.com',
165
+ item_code: 'ITEM001',
166
+ item_name: 'Greate Product',
167
+ order_number: "O#{now.sec}#{now.usec}",
168
+ token: '03d4a2ce2f747c9223a4ead24888d0293ad26c06273e296f9faa0675f99a1ff7',
169
+ three_d_secure_check_code: 1,
170
+ tds_flag: 21,
171
+ }
172
+ end
173
+
174
+ def purchase_detail_for_registered_and_three_d_secure_2
175
+ {
176
+ user_id: '124014051',
177
+ user_email: 'yamada-taro@example.com',
178
+ user_name: 'YAMADA TARO',
179
+ item_code: 'ITEM001',
180
+ item_name: 'Greate Product',
181
+ order_number: "O#{Time.now.to_i}",
182
+ tds_flag: 21,
183
+ }
184
+ end
185
+
159
186
  def valid_three_d_secure_pa_res
160
187
  now = Time.now
161
188
  {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_merchant-epsilon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenichi TAKAHASHI
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-25 00:00:00.000000000 Z
11
+ date: 2022-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemerchant
@@ -178,6 +178,7 @@ files:
178
178
  - lib/active_merchant/billing/gateways/response_parser.rb
179
179
  - lib/active_merchant/epsilon.rb
180
180
  - lib/active_merchant/epsilon/version.rb
181
+ - test/fixtures/vcr_cassettes/authenticate_with_three_d_secure_2_successful.yml
181
182
  - test/fixtures/vcr_cassettes/autheticate_three_d_secure_card_successful.yml
182
183
  - test/fixtures/vcr_cassettes/cancel_recurring_fail.yml
183
184
  - test/fixtures/vcr_cassettes/cancel_recurring_successful.yml
@@ -208,6 +209,7 @@ files:
208
209
  - test/fixtures/vcr_cassettes/purchase_successful.yml
209
210
  - test/fixtures/vcr_cassettes/purchase_with_capture_false_successful.yml
210
211
  - test/fixtures/vcr_cassettes/purchase_with_capture_true_successful.yml
212
+ - test/fixtures/vcr_cassettes/purchase_with_three_d_secure_2_successful.yml
211
213
  - test/fixtures/vcr_cassettes/purchase_with_three_d_secure_card_successful.yml
212
214
  - test/fixtures/vcr_cassettes/purchase_with_verification_value.yml
213
215
  - test/fixtures/vcr_cassettes/recurring_fail.yml
@@ -239,7 +241,7 @@ homepage: http://github.com/pepabo/active_merchant-epsilon
239
241
  licenses:
240
242
  - MIT
241
243
  metadata: {}
242
- post_install_message:
244
+ post_install_message:
243
245
  rdoc_options: []
244
246
  require_paths:
245
247
  - lib
@@ -254,11 +256,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
256
  - !ruby/object:Gem::Version
255
257
  version: '0'
256
258
  requirements: []
257
- rubygems_version: 3.2.3
258
- signing_key:
259
+ rubygems_version: 3.0.3
260
+ signing_key:
259
261
  specification_version: 4
260
262
  summary: Epsilon integration for ActiveMerchant.
261
263
  test_files:
264
+ - test/fixtures/vcr_cassettes/authenticate_with_three_d_secure_2_successful.yml
262
265
  - test/fixtures/vcr_cassettes/autheticate_three_d_secure_card_successful.yml
263
266
  - test/fixtures/vcr_cassettes/cancel_recurring_fail.yml
264
267
  - test/fixtures/vcr_cassettes/cancel_recurring_successful.yml
@@ -289,6 +292,7 @@ test_files:
289
292
  - test/fixtures/vcr_cassettes/purchase_successful.yml
290
293
  - test/fixtures/vcr_cassettes/purchase_with_capture_false_successful.yml
291
294
  - test/fixtures/vcr_cassettes/purchase_with_capture_true_successful.yml
295
+ - test/fixtures/vcr_cassettes/purchase_with_three_d_secure_2_successful.yml
292
296
  - test/fixtures/vcr_cassettes/purchase_with_three_d_secure_card_successful.yml
293
297
  - test/fixtures/vcr_cassettes/purchase_with_verification_value.yml
294
298
  - test/fixtures/vcr_cassettes/recurring_fail.yml