Skip to content

Commit

Permalink
CybersourceREST - Refund | Credit
Browse files Browse the repository at this point in the history
Description
-------------------------
This integration support the following payment operations:
- Refund
- Credit

Unit test
-------------------------
Finished in 40.91494 seconds.
5454 tests, 77134 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed

Remote test
-------------------------
133.30 tests/s, 1885.23 assertions/s

Rubocop
-------------------------
760 files inspected, no offenses detected

GWI-471
  • Loading branch information
Luis committed Feb 28, 2023
1 parent 0b8c197 commit 8498d23
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 5 deletions.
44 changes: 40 additions & 4 deletions lib/active_merchant/billing/gateways/cyber_source_rest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,17 @@ def authorize(money, payment, options = {}, capture = false)
post = build_auth_request(money, payment, options)
post[:processingInformation] = { capture: true } if capture

commit('/pts/v2/payments/', post)
commit('payments', post)
end

def refund(money, authorization, options = {})
post = build_refund_request(money, options)
commit("payments/#{authorization}/refunds", post)
end

def credit(money, payment, options = {})
post = build_credit_request(money, payment, options)
commit('credits', post)
end

def supports_scrubbing?
Expand Down Expand Up @@ -73,6 +83,23 @@ def build_auth_request(amount, payment, options)
end.compact
end

def build_refund_request(amount, options)
{ clientReferenceInformation: {}, orderInformation: {} }.tap do |post|
add_code(post, options)
add_amount(post, amount)
end.compact
end

def build_credit_request(amount, payment, options)
{ clientReferenceInformation: {}, paymentInformation: {}, orderInformation: {} }.tap do |post|
add_code(post, options)
add_credit_card(post, payment)
add_amount(post, amount)
add_address(post, payment, options[:billing_address], options, :billTo)
add_merchant_description(post, options)
end.compact
end

def add_code(post, options)
return unless options[:order_id].present?

Expand Down Expand Up @@ -129,8 +156,17 @@ def add_address(post, payment_method, address, options, address_type)
}.compact
end

def add_merchant_description(post, options)
return unless options[:merchant_descriptor_name] || options[:merchant_descriptor_address1] || options[:merchant_descriptor_locality]

merchant = post[:merchantInformation][:merchantDescriptor] = {}
merchant[:name] = options[:merchant_descriptor_name] if options[:merchant_descriptor_name]
merchant[:address1] = options[:merchant_descriptor_address1] if options[:merchant_descriptor_address1]
merchant[:locality] = options[:merchant_descriptor_locality] if options[:merchant_descriptor_locality]
end

def url(action)
"#{(test? ? test_url : live_url)}#{action}"
"#{(test? ? test_url : live_url)}/pts/v2/#{action}"
end

def host
Expand Down Expand Up @@ -160,7 +196,7 @@ def commit(action, post)
end

def success_from(response)
response['status'] == 'AUTHORIZED'
%w(AUTHORIZED PENDING).include?(response['status'])
end

def message_from(response)
Expand All @@ -183,7 +219,7 @@ def get_http_signature(resource, digest, http_method = 'post', gmtdatetime = Tim
string_to_sign = {
host: host,
date: gmtdatetime,
"(request-target)": "#{http_method} #{resource}",
"(request-target)": "#{http_method} /pts/v2/#{resource}",
digest: digest,
"v-c-merchant-id": @options[:merchant_id]
}.map { |k, v| "#{k}: #{v}" }.join("\n").force_encoding(Encoding::UTF_8)
Expand Down
71 changes: 71 additions & 0 deletions test/remote/gateways/remote_cyber_source_rest_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,77 @@ def test_successful_purchase
assert_nil response.params['_links']['capture']
end

def test_successful_refund
purchase = @gateway.purchase(@amount, @visa_card, @options)
response = @gateway.refund(@amount, purchase.authorization, @options)

assert_success response
assert response.test?
assert_equal 'PENDING', response.message
assert response.params['id'].present?
assert response.params['_links']['void'].present?
end

def test_failure_refund
purchase = @gateway.purchase(@amount, @card_without_funds, @options)
response = @gateway.refund(@amount, purchase.authorization, @options)

assert_failure response
assert response.test?
assert_match %r{Declined - One or more fields in the request contains invalid data}, response.params['message']
assert_equal 'INVALID_DATA', response.params['reason']
end

def test_successful_partial_refund
purchase = @gateway.purchase(@amount, @visa_card, @options)
response = @gateway.refund(@amount / 2, purchase.authorization, @options)

assert_success response
assert response.test?
assert_equal 'PENDING', response.message
assert response.params['id'].present?
assert response.params['_links']['void'].present?
end

def test_successful_repeat_refund_transaction
purchase = @gateway.purchase(@amount, @visa_card, @options)
response1 = @gateway.refund(@amount, purchase.authorization, @options)

assert_success response1
assert response1.test?
assert_equal 'PENDING', response1.message
assert response1.params['id'].present?
assert response1.params['_links']['void']

response2 = @gateway.refund(@amount, purchase.authorization, @options)
assert_success response2
assert response2.test?
assert_equal 'PENDING', response2.message
assert response2.params['id'].present?
assert response2.params['_links']['void']

assert_not_equal response1.params['_links']['void'], response2.params['_links']['void']
end

def test_successful_credit
response = @gateway.credit(@amount, @visa_card, @options)

assert_success response
assert response.test?
assert_equal 'PENDING', response.message
assert response.params['id'].present?
assert_nil response.params['_links']['capture']
end

def test_failure_credit
response = @gateway.credit(@amount, @card_without_funds, @options)

assert_failure response
assert response.test?
assert_match %r{Decline - Invalid account number}, response.message
assert_equal 'INVALID_ACCOUNT', response.error_code
end

def test_transcript_scrubbing
transcript = capture_transcript(@gateway) do
@gateway.authorize(@amount, @visa_card, @options)
Expand Down
2 changes: 1 addition & 1 deletion test/unit/gateways/cyber_source_rest_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def test_add_shipping_address
end

def test_url_building
assert_equal "#{@gateway.class.test_url}/action", @gateway.send(:url, '/action')
assert_equal "#{@gateway.class.test_url}/pts/v2/action", @gateway.send(:url, 'action')
end

private
Expand Down

0 comments on commit 8498d23

Please sign in to comment.