Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom fields for TrustCommerce #3313

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* eWAY Rapid: Support both `phone` and `phone_number` fields under the `shipping_address` option [jasonxp] #3306
* PayU Latam: Add support for the `merchant_buyer_id` field in the `options` and `buyer` hashes [jasonxp] #3308
* Fat Zebra: Send metadata for purchase and authorize [montdidier] #3101
* TrustCommerce: Add support for custom fields [jasonxp] #3313

== Version 1.97.0 (Aug 15, 2019)
* CyberSource: Add issuer `additionalData` gateway-specific field [jasonxp] #3296
Expand Down
24 changes: 22 additions & 2 deletions lib/active_merchant/billing/gateways/trust_commerce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ def authorize(money, creditcard_or_billing_id, options = {})
add_customer_data(parameters, options)
add_payment_source(parameters, creditcard_or_billing_id)
add_addresses(parameters, options)
add_custom_fields(parameters, options)

commit('preauth', parameters)
end

Expand All @@ -174,6 +176,8 @@ def purchase(money, creditcard_or_billing_id, options = {})
add_customer_data(parameters, options)
add_payment_source(parameters, creditcard_or_billing_id)
add_addresses(parameters, options)
add_custom_fields(parameters, options)

commit('sale', parameters)
end

Expand All @@ -187,6 +191,7 @@ def capture(money, authorization, options = {})
:transid => transaction_id,
}
add_aggregator(parameters, options)
add_custom_fields(parameters, options)

commit('postauth', parameters)
end
Expand All @@ -195,11 +200,14 @@ def capture(money, authorization, options = {})
# that you want to refund, and a TC transid for the transaction that you are refunding.
def refund(money, identification, options = {})
transaction_id, _ = split_authorization(identification)

parameters = {
:amount => amount(money),
:transid => transaction_id
}

add_aggregator(parameters, options)
add_custom_fields(parameters, options)

commit('credit', parameters)
end
Expand Down Expand Up @@ -233,7 +241,9 @@ def void(authorization, options = {})
parameters = {
:transid => transaction_id,
}

add_aggregator(parameters, options)
add_custom_fields(parameters, options)

commit(action, parameters)
end
Expand Down Expand Up @@ -294,6 +304,8 @@ def store(creditcard, options = {})

add_creditcard(parameters, creditcard)
add_addresses(parameters, options)
add_custom_fields(parameters, options)

commit('store', parameters)
end

Expand All @@ -304,6 +316,8 @@ def unstore(identification, options = {})
:billingid => identification,
}

add_custom_fields(parameters, options)

commit('unstore', parameters)
end

Expand All @@ -321,6 +335,12 @@ def scrub(transcript)

private

def add_custom_fields(params, options)
options[:custom_fields]&.each do |key, value|
params[key.to_sym] = value
end
end

def add_aggregator(params, options)
if @options[:aggregator_id] || application_id != Gateway.application_id
params[:aggregators] = 1
Expand Down Expand Up @@ -419,7 +439,7 @@ def commit(action, parameters)
TCLink.send(parameters)
else
parse(ssl_post(self.live_url, post_data(parameters)))
end
end

# to be considered successful, transaction status must be either "approved" or "accepted"
success = SUCCESS_TYPES.include?(data['status'])
Expand Down Expand Up @@ -463,7 +483,7 @@ def authorization_from(action, data)
end

def split_authorization(authorization)
authorization.split('|')
authorization&.split('|')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a null safety check that fixed an error that occurred when the authorization was nil.

end
end
end
Expand Down
48 changes: 39 additions & 9 deletions test/remote/gateways/remote_trust_commerce_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ def setup
@gateway = TrustCommerceGateway.new(fixtures(:trust_commerce))

@credit_card = credit_card('4111111111111111')
@declined_credit_card = credit_card('4111111111111112')
@check = check({account_number: 55544433221, routing_number: 789456124})

@amount = 100
Expand All @@ -28,12 +29,21 @@ def setup
:zip => '94062'
}

# The Trust Commerce API does not return anything different when custom fields are present.
# To confirm that the field values are being stored with the transactions, add a custom
# field in your account in the Vault UI, then examine the transactions after running the
# test suite.
custom_fields = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💙the clarifying comments!

'customfield1' => 'test1'
}

@options = {
:ip => '10.10.10.10',
:order_id => '#1000.1',
:email => '[email protected]',
:billing_address => @valid_address,
:shipping_address => @valid_address
:shipping_address => @valid_address,
:custom_fields => custom_fields
}
end

Expand Down Expand Up @@ -158,26 +168,38 @@ def test_successful_check_refund
assert_success response
end

def test_store_failure
def test_successful_store
assert response = @gateway.store(@credit_card)

assert_equal Response, response.class
assert_match %r{The merchant can't accept data passed in this field}, response.message
assert_failure response
assert_equal 'approved', response.params['status']
assert_match %r{The transaction was successful}, response.message
end

def test_failed_store
assert response = @gateway.store(@declined_credit_card)

assert_bad_data_response(response)
end

def test_unstore_failure
assert response = @gateway.unstore('testme')
assert response = @gateway.unstore('does-not-exist')

assert_match %r{The merchant can't accept data passed in this field}, response.message
assert_match %r{A field was longer or shorter than the server allows}, response.message
assert_failure response
end

def test_recurring_failure
def test_successful_recurring
assert response = @gateway.recurring(@amount, @credit_card, :periodicity => :weekly)

assert_match %r{The merchant can't accept data passed in this field}, response.message
assert_failure response
assert_match %r{The transaction was successful}, response.message
assert_success response
end

def test_failed_recurring
assert response = @gateway.recurring(@amount, @declined_credit_card, :periodicity => :weekly)

assert_bad_data_response(response)
end

def test_transcript_scrubbing
Expand All @@ -190,4 +212,12 @@ def test_transcript_scrubbing
assert_scrubbed(@credit_card.number, clean_transcript)
assert_scrubbed(@credit_card.verification_value.to_s, clean_transcript)
end

private

def assert_bad_data_response(response)
assert_equal Response, response.class
assert_equal 'A field was improperly formatted, such as non-digit characters in a number field', response.message
assert_equal 'baddata', response.params['status']
end
end
103 changes: 103 additions & 0 deletions test/unit/gateways/trust_commerce_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ def setup
@amount = 100
@check = check
@credit_card = credit_card('4111111111111111')

@options_with_custom_fields = {
custom_fields: {
'customfield1' => 'test1'
}
}
end

def test_successful_purchase
Expand Down Expand Up @@ -41,6 +47,22 @@ def test_succesful_purchase_with_check
end.respond_with(successful_purchase_response)
end

def test_succesful_purchase_with_custom_fields
stub_comms do
@gateway.purchase(@amount, @credit_card, @options_with_custom_fields)
end.check_request do |endpoint, data, headers|
assert_match(%r{customfield1=test1}, data)
end.respond_with(successful_purchase_response)
end

def test_succesful_authorize_with_custom_fields
stub_comms do
@gateway.authorize(@amount, @check, @options_with_custom_fields)
end.check_request do |endpoint, data, headers|
assert_match(%r{customfield1=test1}, data)
end.respond_with(successful_authorize_response)
end

def test_successful_void_from_purchase
stub_comms do
@gateway.void('1235|sale')
Expand All @@ -57,6 +79,46 @@ def test_successful_void_from_authorize
end.respond_with(successful_void_response)
end

def test_succesful_capture_with_custom_fields
stub_comms do
@gateway.capture(@amount, 'auth', @options_with_custom_fields)
end.check_request do |endpoint, data, headers|
assert_match(%r{customfield1=test1}, data)
end.respond_with(successful_capture_response)
end

def test_succesful_refund_with_custom_fields
stub_comms do
@gateway.refund(@amount, 'auth|100', @options_with_custom_fields)
end.check_request do |endpoint, data, headers|
assert_match(%r{customfield1=test1}, data)
end.respond_with(successful_refund_response)
end

def test_succesful_void_with_custom_fields
stub_comms do
@gateway.void('1235|sale', @options_with_custom_fields)
end.check_request do |endpoint, data, headers|
assert_match(%r{customfield1=test1}, data)
end.respond_with(successful_void_response)
end

def test_succesful_store_with_custom_fields
stub_comms do
@gateway.store(@credit_card, @options_with_custom_fields)
end.check_request do |endpoint, data, headers|
assert_match(%r{customfield1=test1}, data)
end.respond_with(successful_store_response)
end

def test_succesful_unstore_with_custom_fields
stub_comms do
@gateway.unstore('test', @options_with_custom_fields)
end.check_request do |endpoint, data, headers|
assert_match(%r{customfield1=test1}, data)
end.respond_with(successful_unstore_response)
end

def test_amount_style
assert_equal '1034', @gateway.send(:amount, 1034)

Expand Down Expand Up @@ -103,6 +165,16 @@ def test_transcript_scrubbing

private

def successful_authorize_response
<<-RESPONSE
authcode=123456
transid=026-0193338367,
status=approved
avs=Y
cvv=M
RESPONSE
end

def successful_purchase_response
<<-RESPONSE
transid=025-0007423614
Expand All @@ -112,6 +184,13 @@ def successful_purchase_response
RESPONSE
end

def successful_capture_response
<<-RESPONSE
transid=026-0193338993
status=accepted
RESPONSE
end

def unsuccessful_purchase_response
<<-RESPONSE
transid=025-0007423827
Expand All @@ -128,6 +207,30 @@ def successful_void_response
RESPONSE
end

def successful_refund_response
<<-RESPONSE
transid=026-0193345407
status=accepted
RESPONSE
end

def successful_store_response
<<-RESPONSE
transid=026-0193346109
status=approved,
cvv=M,
avs=0
billingid=Q5T7PT
RESPONSE
end

def successful_unstore_response
<<-RESPONSE
transid=026-0193346231
status=rejected
RESPONSE
end

def transcript
<<-TRANSCRIPT
action=sale&demo=y&password=password&custid=TestMerchant&shipto_zip=90001&shipto_state=CA&shipto_city=Somewhere&shipto_address1=123+Test+St.&avs=n&zip=90001&state=CA&city=Somewhere&address1=123+Test+St.&cvv=1234&exp=0916&cc=4111111111111111&name=Longbob+Longsen&media=cc&ip=10.10.10.10&email=cody%40example.com&ticket=%231000.1&amount=100
Expand Down