Skip to content

Commit

Permalink
Plexo: update verify implementation.
Browse files Browse the repository at this point in the history
Updated `verify` implementation to send request on plexo API endpoint along with test cases.

[SER-106](https://spreedly.atlassian.net/browse/SER-106)

Unit:
5213 tests, 75902 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed

Rubocop:
743 files inspected, no offenses detected

Remote:
18 tests, 100 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed

Closes activemerchant#4462
  • Loading branch information
ajawadmirza authored and drkjc committed Jun 17, 2022
1 parent 3f843d4 commit 8a10533
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
* Airwallex: Update `referrer_data` field [drkjc] #4455
* Simetrik: Update `order_id` and `description` to be top level fields [simetrik-frank] #4451
* Plexo: Update `ip`, `description`, and `email` fields request format and scrub method to not filter cardholder name and reference id [ajawadmirza] #4457
* Plexo: Update `verify` implementation and add `verify_amount` field [ajawadmirza] #4462

== Version 1.126.0 (April 15th, 2022)
* Moneris: Add 3DS MPI field support [esmitperez] #4373
Expand Down
26 changes: 18 additions & 8 deletions lib/active_merchant/billing/gateways/plexo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class PlexoGateway < Gateway
self.homepage_url = 'https://www.plexo.com.uy'
self.display_name = 'Plexo'

APPENDED_URLS = %w(captures refunds cancellations)
APPENDED_URLS = %w(captures refunds cancellations verify)
AMOUNT_IN_RESPONSE = %w(authonly /verify)

def initialize(options = {})
requires!(options, :client_id, :api_key)
Expand All @@ -38,7 +39,7 @@ def authorize(money, payment, options = {})
add_payment_method(post, payment, options)
add_items(post, options[:items])
add_metadata(post, options[:metadata])
add_amount(money, post, options[:amount_details])
add_amount(money, post, options)
add_browser_details(post, options)
add_capture_type(post, options)

Expand Down Expand Up @@ -74,10 +75,19 @@ def void(authorization, options = {})
end

def verify(credit_card, options = {})
MultiResponse.run(:use_first_response) do |r|
r.process { authorize(100, credit_card, options) }
r.process(:ignore_result) { void(r.authorization, options) }
end
post = {}
post[:ReferenceId] = options[:reference_id] || generate_unique_id
post[:MerchantId] = options[:merchant_id] || @credentials[:merchant_id]
post[:StatementDescriptor] = options[:statement_descriptor] if options[:statement_descriptor]
post[:CustomerId] = options[:customer_id] if options[:customer_id]
money = options[:verify_amount].to_i || 100

add_payment_method(post, credit_card, options)
add_metadata(post, options[:metadata])
add_amount(money, post, options)
add_browser_details(post, options)

commit('/verify', post)
end

def supports_scrubbing?
Expand Down Expand Up @@ -144,7 +154,7 @@ def add_amount(money, post, amount_options)
post[:Amount][:Currency] = amount_options[:currency] || self.default_currency
post[:Amount][:Total] = amount(money)
post[:Amount][:Details] = {}
add_amount_details(post[:Amount][:Details], amount_options)
add_amount_details(post[:Amount][:Details], amount_options[:amount_details]) if amount_options[:amount_details]
end

def add_amount_details(amount_details, options)
Expand Down Expand Up @@ -229,7 +239,7 @@ def commit(action, parameters)
base_url = (test? ? test_url : live_url)
url = build_url(action, base_url)
response = parse(ssl_post(url, parameters.to_json, header(parameters)))
response = reorder_amount_fields(response) if action == 'authonly'
response = reorder_amount_fields(response) if AMOUNT_IN_RESPONSE.include?(action)

Response.new(
success_from(response),
Expand Down
13 changes: 9 additions & 4 deletions test/remote/gateways/remote_plexo_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,22 @@ def test_failed_void
end

def test_successful_verify
response = @gateway.verify(@credit_card, @options.merge(@cancel_options))
response = @gateway.verify(@credit_card, @options)
assert_success response
assert_equal 'You have been mocked.', response.message
end

def test_successful_verify_with_custom_amount
response = @gateway.verify(@credit_card, @options.merge({ verify_amount: '400' }))
assert_success response
assert_equal 'You have been mocked.', response.message
end

def test_failed_verify
response = @gateway.verify(@declined_card, @options)
assert_failure response
assert_equal 'You have been mocked.', response.message
assert_equal '96', response.error_code
assert_equal 'denied', response.params['status']
assert_equal 'The selected payment state is not valid.', response.message
assert_equal 400, response.error_code
end

def test_invalid_login
Expand Down
176 changes: 166 additions & 10 deletions test/unit/gateways/plexo_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ def test_successful_authorize_with_extra_options

def test_successful_authorize_with_amount_fields
amount_fields = {
currency: 'USD',
taxed_amount: '100',
tip_amount: '32',
discount_amount: '10',
Expand All @@ -142,10 +141,10 @@ def test_successful_authorize_with_amount_fields
}
}
response = stub_comms do
@gateway.authorize(@amount, @credit_card, @options.merge({ amount_details: amount_fields }))
@gateway.authorize(@amount, @credit_card, @options.merge({ amount_details: amount_fields, currency: 'USD' }))
end.check_request do |_endpoint, data, _headers|
request = JSON.parse(data)
assert_equal request['Amount']['Currency'], amount_fields[:currency]
assert_equal request['Amount']['Currency'], 'USD'
assert_equal request['Amount']['Details']['TaxedAmount'], amount_fields[:taxed_amount]
assert_equal request['Amount']['Details']['TipAmount'], amount_fields[:tip_amount]
assert_equal request['Amount']['Details']['DiscountAmount'], amount_fields[:discount_amount]
Expand Down Expand Up @@ -243,22 +242,24 @@ def test_failed_void
end

def test_successful_verify
@gateway.expects(:ssl_post).times(2).returns(successful_authorize_response, successful_capture_response)
@gateway.expects(:ssl_post).returns(successful_verify_response)

response = @gateway.verify(@credit_card, @options)
assert_success response
assert_equal 'You have been mocked.', response.message
end

def test_successful_verify_with_failed_void
@gateway.expects(:ssl_post).times(2).returns(successful_authorize_response, failed_void_response)

response = @gateway.verify(@credit_card, @options)
assert_success response
def test_successful_verify_with_custom_amount
stub_comms do
@gateway.verify(@credit_card, @options.merge({ verify_amount: '900' }))
end.check_request do |_endpoint, data, _headers|
request = JSON.parse(data)
assert_equal request['Amount']['Total'], '9.00'
end.respond_with(successful_verify_response)
end

def test_failed_verify
@gateway.expects(:ssl_post).returns(failed_authorize_response)
@gateway.expects(:ssl_post).returns(failed_verify_response)

response = @gateway.verify(@credit_card, @options)
assert_failure response
Expand Down Expand Up @@ -610,4 +611,159 @@ def failed_void_response
}
RESPONSE
end

def successful_verify_response
<<~RESPONSE
{
"id": "62ac2c5eaf353be57867f977",
"token": "7220c5cc-4b57-43e6-ae91-3fd3f3e8d49f",
"referenceId": "e7dbc06224f646ad8e63ec1c6e670a39",
"status": "approved",
"processingMethod": "api",
"browserDetails": {
"DeviceFingerprint": "12345",
"IpAddress": "127.0.0.1"
},
"createdAt": "2022-06-17T07:25:18.1421498Z",
"merchant": {
"id": 3243,
"name": "spreedly",
"settings": {
"id": 41363,
"issuerId": 4,
"issuer": {
"id": 4,
"code": "mastercard",
"name": "MASTERCARD",
"type": "online"
},
"metadata": {
"ProviderCommerceNumber": "153289",
"TerminalNumber": "1K153289",
"SoftDescriptor": "VTEX-Testing",
"PaymentProcessorId": "oca"
},
"paymentProcessor": {
"acquirer": "oca",
"settings": {
"commerce": {
"fields": [
{
"name": "ProviderCommerceNumber",
"type": 2049
},
{
"name": "TerminalNumber",
"type": 2051
}
]
},
"fingerprint": {
"name": "cybersource-oca"
},
"fields": [
{
"name": "Email",
"type": 261
},
{
"name": "FirstName",
"type": 271
},
{
"name": "LastName",
"type": 272
},
{
"name": "CVC",
"type": 33154
}
]
}
}
},
"clientId": 221
},
"client": {
"id": 221,
"name": "Spreedly",
"tier": 2,
"sessionTimeInSeconds": 36000
},
"paymentMethod": {
"type": "card",
"card": {
"name": "555555XXXXXX4444",
"bin": "555555",
"last4": "4444",
"expMonth": 12,
"expYear": 24,
"cardholder": {
"firstName": "Santiago",
"lastName": "Navatta",
"email": "[email protected]"
},
"fingerprint": "36e2219cc4734a61af258905c1c59ba4"
},
"issuer": {
"id": "mastercard",
"name": "MasterCard",
"pictureUrl": "https://static.plexo.com.uy/issuers/4.svg",
"type": "online"
},
"processor": {
"acquirer": "oca"
}
},
"installments": 1,
"amount": {
"currency": "UYU",
"total": 20
},
"items": [
{
"referenceId": "997d4aafe29b4421ac52a3ddf5b28dfd",
"name": "card-verification",
"quantity": 1,
"price": 20
}
],
"capture": {
"method": "manual",
"delay": 0
},
"metadata": {
"One": "abc"
},
"transactions": [
{
"id": "62ac2c5eaf353be57867f97b",
"uniqueId": "987256610059481088",
"parentId": "7220c5cc-4b57-43e6-ae91-3fd3f3e8d49f",
"referenceId": "e7dbc06224f646ad8e63ec1c6e670a39",
"type": "authorization",
"status": "approved",
"createdAt": "2022-06-17T07:25:18.1796516Z",
"processedAt": "2022-06-17T07:25:18.1796366Z",
"resultCode": "0",
"resultMessage": "You have been mocked.",
"authorization": "12133",
"ticket": "111111",
"amount": 20
}
]
}
RESPONSE
end

def failed_verify_response
<<~RESPONSE
{
"code": "invalid-transaction-state",
"message": "The selected payment state is not valid.",
"type": "api-error",
"status": 400
}
RESPONSE
end
end

0 comments on commit 8a10533

Please sign in to comment.