From 767608df79ccc4a4b83a62bdfc06580711df8efa Mon Sep 17 00:00:00 2001 From: Gustavo Sanmartin Date: Tue, 22 Oct 2024 10:07:26 -0500 Subject: [PATCH] Versapay: Void, Refund, Credit This includes the support for extra operations, Void, Refund and Credit with the necesary unit and remote tests. [SER-1334](https://spreedly.atlassian.net/browse/SER-1334) Unit Tests ---------------- Finished in 0.070284 seconds. 24 tests, 124 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications 100% passed Remote Tests ---------------- Finished in 72.628972 seconds. 22 tests, 104 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications 100% passed Rubocop ---------------- 804 files inspected, no offenses detected --- CHANGELOG | 2 +- .../billing/gateways/versa_pay.rb | 18 ++++- test/remote/gateways/remote_versa_pay_test.rb | 69 +++++++++++++++++++ test/unit/gateways/versa_pay_test.rb | 36 +++++++++- 4 files changed, 120 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 11cf633d747..6996cab811d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -58,7 +58,7 @@ * Worldpay: Add support for Worldpay decrypted apple pay and google pay [dustinhaefele] #5271 * Orbital: Update alternate_ucaf_flow [almalee24] #5282 * Adyen: Remove cryptogram flag [almalee24] #5300 -* Cecabank: Include Apple Pay and Google Pay for recurring payments [gasn150] #5295 +* Cecabank: Include Apple Pay and Google Pay for recurring payments [gasb150] #5295 * DLocal: Add X-Dlocal-Payment-Source to header [almalee24] #5281 * StripePI: Update to retrieve_setup_intent and headers [almalee24] #5283 * Upgrade rexml to 3.3.8 [raymzag] #5245 diff --git a/lib/active_merchant/billing/gateways/versa_pay.rb b/lib/active_merchant/billing/gateways/versa_pay.rb index 440e97442d4..10089458d97 100644 --- a/lib/active_merchant/billing/gateways/versa_pay.rb +++ b/lib/active_merchant/billing/gateways/versa_pay.rb @@ -39,6 +39,22 @@ def verify(credit_card, options = {}) transact(0, credit_card, options, 'verify') end + def void(authorization, options = {}) + commit('void', { transaction: authorization }) + end + + def refund(money, authorization, options = {}) + post = { + amount_cents: money, + transaction: authorization + } + commit('refund', post) + end + + def credit(money, payment_method, options = {}) + transact(money, payment_method, options, 'credit') + end + def supports_scrubbing? true end @@ -253,7 +269,7 @@ def handle_response(response) when 200..412 response.body else - raise ResponseError.new(response) + response.body || raise(ResponseError.new(response)) # some errors 500 has the error message end end end diff --git a/test/remote/gateways/remote_versa_pay_test.rb b/test/remote/gateways/remote_versa_pay_test.rb index 8842d38e65f..e57c13627d2 100644 --- a/test/remote/gateways/remote_versa_pay_test.rb +++ b/test/remote/gateways/remote_versa_pay_test.rb @@ -124,6 +124,20 @@ def test_successful_capture assert_equal response.params['transactions'][0]['action'], 'capture' end + def test_successful_partial_capture + authorize = @gateway.authorize(@amount, @credit_card, @options) + + assert_success authorize + response = @gateway.capture(@amount - 100, authorize.authorization, @options) + assert_success response + + assert_equal 'Succeeded', response.message + assert_equal authorize.params['order'], response.params['order'] + assert_equal @options[:order_id], response.params['order'] + assert_equal response.authorization, response.params['transaction'] + assert_equal response.params['transactions'][0]['action'], 'capture' + end + def test_successful_verify response = @gateway.verify(@credit_card, @options) @@ -171,6 +185,61 @@ def test_avs_no_match_cvv_not_match assert_equal response.cvv_result, { 'code' => 'M', 'message' => 'CVV matches' } end + def test_successful_void + authorize = @gateway.authorize(@amount, @credit_card, @options) + + assert_success authorize + response = @gateway.void(authorize.authorization, @options) + assert_success response + assert_equal 'Succeeded', response.message + assert_equal authorize.params['order'], response.params['order'] + assert_equal @options[:order_id], response.params['order'] + assert_equal response.authorization, response.params['transaction'] + assert_equal response.params['transactions'][0]['action'], 'void' + end + + def test_failed_void + response = @gateway.void('123456', @options) + assert_failure response + assert_equal response.message, 'errors: order_not_found' # come from a 500 HTTP error + assert_equal response.error_code, 'response_code: 250' + end + + def test_successful_refund + purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_success purchase + response = @gateway.refund(@amount, purchase.authorization, @options) + assert_success response + assert_equal 'Succeeded', response.message + assert_equal purchase.params['order'], response.params['order'] + assert_equal @options[:order_id], response.params['order'] + assert_equal response.authorization, response.params['transaction'] + assert_equal response.params['transactions'][0]['action'], 'refund' + end + + def test_failed_refund + response = @gateway.refund(@amount, '123456', @options) + assert_failure response + assert_equal response.message, 'errors: order_not_found' # come from a 500 HTTP error + assert_equal response.error_code, 'response_code: 250' + end + + def test_successful_credit + response = @gateway.credit(@amount, @credit_card, @options) + assert_success response + assert_equal 'Succeeded', response.message + assert_equal @options[:order_id], response.params['order'] + assert_equal response.authorization, response.params['transaction'] + assert_equal response.params['transactions'][0]['action'], 'credit' + end + + def test_failed_credit + response = @gateway.credit(@amount, @no_valid_date_credit_card, @options) + assert_failure response + assert_equal response.message, 'gateway_response_errors: [credit_card - token: Not found.]' + assert_equal response.error_code, 'response_code: 999' + end + def test_transcript_scrubbing transcript = capture_transcript(@gateway) do @gateway.purchase(@amount, @credit_card, @options) diff --git a/test/unit/gateways/versa_pay_test.rb b/test/unit/gateways/versa_pay_test.rb index bf73f24a6b2..09ed9d466bc 100644 --- a/test/unit/gateways/versa_pay_test.rb +++ b/test/unit/gateways/versa_pay_test.rb @@ -74,7 +74,7 @@ def test_successful_authorize @gateway.authorize(@amount, @credit_card, @options) end.check_request do |endpoint, data, _headers| assert_match 'auth', endpoint - auth_purchase_assertions(data) + auth_purchase_credit_assertions(data) end.respond_with(successful_authorize_response) @gateway.authorize(@amount, @credit_card, @options) end @@ -84,7 +84,7 @@ def test_successful_purchase @gateway.purchase(@amount, @credit_card, @options) end.check_request do |endpoint, data, _headers| assert_match 'sale', endpoint - auth_purchase_assertions(data) + auth_purchase_credit_assertions(data) end.respond_with(successful_purchase_response) end @@ -158,6 +158,36 @@ def test_dig_avs_code_nil_transaction assert_nil @gateway.send(:dig_cvv_code, first_transaction) end + def test_successful_void + stub_comms do + @gateway.void('transaction_ID') + end.check_request do |endpoint, data, _headers| + assert_match 'void', endpoint + data = JSON.parse(data) + assert_equal 'transaction_ID', data['transaction'] + end.respond_with('{"success": true}') + end + + def test_successful_refund + stub_comms do + @gateway.refund(@amount, 'transaction_ID') + end.check_request do |endpoint, data, _headers| + assert_match 'refund', endpoint + data = JSON.parse(data) + assert_equal @amount, data['amount_cents'] + assert_equal 'transaction_ID', data['transaction'] + end.respond_with('{"success": true}') + end + + def test_successful_credit + stub_comms do + @gateway.credit(@amount, @credit_card, @options) + end.check_request do |endpoint, data, _headers| + assert_match 'credit', endpoint + auth_purchase_credit_assertions(data) + end.respond_with('{"success": true}') + end + def test_scrub assert @gateway.supports_scrubbing? assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed @@ -165,7 +195,7 @@ def test_scrub private - def auth_purchase_assertions(data) + def auth_purchase_credit_assertions(data) billing_address = @options[:billing_address] data = JSON.parse(data) assert_equal @amount.to_s, data['order']['amount_cents']