Skip to content

Commit

Permalink
CyberSource, CyberSource Rest: Add the MCC field
Browse files Browse the repository at this point in the history
  • Loading branch information
yunnydang committed Oct 9, 2024
1 parent b317b8c commit 576a2e5
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 2 deletions.
10 changes: 10 additions & 0 deletions lib/active_merchant/billing/gateways/cyber_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ def build_auth_request(money, creditcard_or_reference, options)
add_threeds_services(xml, options)
add_business_rules_data(xml, creditcard_or_reference, options)
add_airline_data(xml, options)
add_merchant_category_code(xml, options)
add_sales_slip_number(xml, options)
add_payment_network_token(xml, creditcard_or_reference, options)
add_payment_solution(xml, creditcard_or_reference)
Expand Down Expand Up @@ -413,6 +414,7 @@ def build_capture_request(money, authorization, options)
add_mdd_fields(xml, options)
add_capture_service(xml, request_id, request_token, options)
add_business_rules_data(xml, authorization, options)
add_merchant_category_code(xml, options)
add_tax_management_indicator(xml, options)
add_issuer_additional_data(xml, options)
add_merchant_description(xml, options)
Expand All @@ -433,6 +435,7 @@ def build_purchase_request(money, payment_method_or_reference, options)
if (!payment_method_or_reference.is_a?(String) && card_brand(payment_method_or_reference) == 'check') || reference_is_a_check?(payment_method_or_reference)
add_check_service(xml)
add_airline_data(xml, options)
add_merchant_category_code(xml, options)
add_sales_slip_number(xml, options)
add_tax_management_indicator(xml, options)
add_issuer_additional_data(xml, options)
Expand All @@ -443,6 +446,7 @@ def build_purchase_request(money, payment_method_or_reference, options)
add_threeds_services(xml, options)
add_business_rules_data(xml, payment_method_or_reference, options)
add_airline_data(xml, options)
add_merchant_category_code(xml, options)
add_sales_slip_number(xml, options)
add_payment_network_token(xml, payment_method_or_reference, options)
add_payment_solution(xml, payment_method_or_reference)
Expand Down Expand Up @@ -477,6 +481,7 @@ def build_void_request(identification, options)
add_mdd_fields(xml, options)
add_auth_reversal_service(xml, request_id, request_token)
end
add_merchant_category_code(xml, options)
add_issuer_additional_data(xml, options)
add_partner_solution_id(xml)

Expand All @@ -492,6 +497,7 @@ def build_refund_request(money, identification, options)
add_credit_service(xml, request_id: request_id,
request_token: request_token,
use_check_service: reference_is_a_check?(identification))
add_merchant_category_code(xml, options)
add_partner_solution_id(xml)

xml.target!
Expand Down Expand Up @@ -1035,6 +1041,10 @@ def add_subscription_retrieve_service(xml, options)
xml.tag! 'paySubscriptionRetrieveService', { 'run' => 'true' }
end

def add_merchant_category_code(xml, options)
xml.tag! 'merchantCategoryCode', options[:merchant_category_code] if options[:merchant_category_code]
end

def add_subscription(xml, options, reference = nil)
options[:subscription] ||= {}

Expand Down
12 changes: 10 additions & 2 deletions lib/active_merchant/billing/gateways/cyber_source_rest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def credit(money, payment, options = {})

def void(authorization, options = {})
payment, amount = authorization.split('|')
post = build_void_request(amount)
post = build_void_request(options, amount)
commit("payments/#{payment}/reversals", post)
end

Expand Down Expand Up @@ -148,7 +148,7 @@ def add_three_ds(post, payment_method, options)
post
end

def build_void_request(amount = nil)
def build_void_request(options, amount = nil)
{ reversalInformation: { amountDetails: { totalAmount: nil } } }.tap do |post|
add_reversal_amount(post, amount.to_i) if amount.present?
end.compact
Expand All @@ -164,6 +164,7 @@ def build_auth_request(amount, payment, options)
add_address(post, payment, options[:billing_address], options, :billTo)
add_address(post, payment, options[:shipping_address], options, :shipTo)
add_business_rules_data(post, payment, options)
add_merchant_category_code(post, options)
add_partner_solution_id(post)
add_stored_credentials(post, payment, options)
add_three_ds(post, payment, options)
Expand All @@ -177,6 +178,7 @@ def build_reference_request(amount, options)
add_code(post, options)
add_mdd_fields(post, options)
add_amount(post, amount, options)
add_merchant_category_code(post, options)
add_partner_solution_id(post)
end.compact
end
Expand All @@ -187,6 +189,7 @@ def build_credit_request(amount, payment, options)
add_credit_card(post, payment)
add_mdd_fields(post, options)
add_amount(post, amount, options)
add_merchant_category_code(post, options)
add_address(post, payment, options[:billing_address], options, :billTo)
add_merchant_description(post, options)
end.compact
Expand Down Expand Up @@ -330,6 +333,11 @@ def add_merchant_description(post, options)
merchant[:locality] = options[:merchant_descriptor_locality] if options[:merchant_descriptor_locality]
end

def add_merchant_category_code(post, options)
merchant_mcc = post[:merchantInformation] ||= {}
merchant_mcc[:categoryCode] = options[:merchant_category_code] if options[:merchant_category_code]
end

def add_stored_credentials(post, payment, options)
return unless options[:stored_credential]

Expand Down
38 changes: 38 additions & 0 deletions test/remote/gateways/remote_cyber_source_rest_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,17 @@ def test_successful_refund
assert response.params['_links']['void'].present?
end

def test_successful_refund_with_merchant_category_code
purchase = @gateway.purchase(@amount, @visa_card, @options)
response = @gateway.refund(@amount, purchase.authorization, @options.merge(merchant_category_code: '1111'))

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)
Expand Down Expand Up @@ -293,6 +304,16 @@ def test_successful_credit
assert_nil response.params['_links']['capture']
end

def test_successful_credit_with_merchant_category_code
response = @gateway.credit(@amount, @visa_card, @options.merge(merchant_category_code: '1111'))

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)

Expand All @@ -311,6 +332,15 @@ def test_successful_void
assert_nil response.params['_links']['capture']
end

def test_successful_void_with_merchant_category_code
authorize = @gateway.authorize(@amount, @visa_card, @options)
response = @gateway.void(authorize.authorization, @options.merge(merchant_category_code: '1111'))
assert_success response
assert response.params['id'].present?
assert_equal 'REVERSED', response.message
assert_nil response.params['_links']['capture']
end

def test_failure_void_using_card_without_funds
authorize = @gateway.authorize(@amount, @card_without_funds, @options)
response = @gateway.void(authorize.authorization, @options)
Expand Down Expand Up @@ -599,6 +629,14 @@ def test_successful_purchase_with_level_2_data
assert_nil response.params['_links']['capture']
end

def test_successful_purchase_with_merchant_catefory_code
response = @gateway.purchase(@amount, @visa_card, @options.merge(merchant_category_code: '1111'))
assert_success response
assert response.test?
assert_equal 'AUTHORIZED', response.message
assert_nil response.params['_links']['capture']
end

def test_successful_purchase_with_level_2_and_3_data
options = {
purchase_order_number: '6789',
Expand Down
42 changes: 42 additions & 0 deletions test/remote/gateways/remote_cyber_source_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@ def test_successful_authorization
assert !response.authorization.blank?
end

def test_successful_authorization_with_merchant_catefory_code
options = @options.merge(merchant_category_code: '1111')
assert response = @gateway.authorize(@amount, @credit_card, options)
assert_successful_response(response)
assert !response.authorization.blank?
end

def test_successful_authorization_with_reconciliation_id
options = @options.merge(reconciliation_id: '1936831')
assert response = @gateway.authorize(@amount, @credit_card, options)
Expand Down Expand Up @@ -316,6 +323,13 @@ def test_successful_purchase_with_single_element_from_other_tax
assert !response.authorization.blank?
end

def test_successful_purchase_with_merchant_catefory_code
options = @options.merge(merchant_category_code: '1111')
assert response = @gateway.purchase(@amount, @credit_card, options)
assert_successful_response(response)
assert !response.authorization.blank?
end

def test_successful_auth_with_gratuity_amount
options = @options.merge(gratuity_amount: '7.50')

Expand Down Expand Up @@ -371,6 +385,15 @@ def test_purchase_and_void
assert_successful_response(void)
end

def test_purchase_and_void_with_merchant_category_code
assert purchase = @gateway.purchase(@amount, @credit_card, @options)
assert_successful_response(purchase)

void_options = @options.merge(merchant_category_code: '1111')
assert void = @gateway.void(purchase.authorization, void_options)
assert_successful_response(void)
end

# Note: This test will only pass with test account credentials which
# have asynchronous adjustments enabled.
def test_successful_asynchronous_adjust
Expand Down Expand Up @@ -694,6 +717,16 @@ def test_successful_capture_with_issuer_additional_data
assert !response.authorization.blank?
end

def test_successful_capture_with_merchant_category_code
assert auth = @gateway.authorize(@amount, @credit_card, @options)
assert_successful_response(auth)

capture_options = @options.merge(merchant_category_code: '1111')
assert response = @gateway.capture(@amount, auth.authorization, capture_options)
assert_successful_response(response)
assert !response.authorization.blank?
end

def test_successful_capture_with_solution_id
ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000'
assert auth = @gateway.authorize(@amount, @credit_card, @options)
Expand Down Expand Up @@ -752,6 +785,15 @@ def test_successful_refund_with_solution_id
ActiveMerchant::Billing::CyberSourceGateway.application_id = nil
end

def test_successful_refund_with_merchant_category_code
assert response = @gateway.purchase(@amount, @credit_card, @options)
assert_successful_response(response)

refund_options = @options.merge(merchant_category_code: '1111')
assert response = @gateway.refund(@amount, response.authorization, refund_options)
assert_successful_response(response)
end

def test_successful_refund_with_bank_account_follow_on
bank_account = check({ account_number: '4100', routing_number: '011000015' })
assert response = @gateway.purchase(10000, bank_account, @options)
Expand Down
18 changes: 18 additions & 0 deletions test/unit/gateways/cyber_source_rest_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,15 @@ def test_credit_includes_mdd_fields
end.respond_with(successful_credit_response)
end

def test_successful_credit_with_merchant_category_code
stub_comms do
@gateway.credit(@amount, @credit_card, @options.merge(merchant_category_code: '1111'))
end.check_request do |_endpoint, data, _headers|
json_data = JSON.parse(data)
assert_equal json_data['merchantInformation']['categoryCode'], '1111'
end.respond_with(successful_credit_response)
end

def test_authorize_includes_reconciliation_id
stub_comms do
@gateway.authorize(100, @credit_card, order_id: '1', reconciliation_id: '181537')
Expand Down Expand Up @@ -490,6 +499,15 @@ def test_purchase_includes_invoice_number
end.respond_with(successful_purchase_response)
end

def test_successful_purchase_with_merchant_category_code
stub_comms do
@gateway.purchase(100, @credit_card, @options.merge(merchant_category_code: '1111'))
end.check_request do |_endpoint, data, _headers|
json_data = JSON.parse(data)
assert_equal json_data['merchantInformation']['categoryCode'], '1111'
end.respond_with(successful_purchase_response)
end

def test_mastercard_purchase_with_3ds2
@options[:three_d_secure] = {
version: '2.2.0',
Expand Down
32 changes: 32 additions & 0 deletions test/unit/gateways/cyber_source_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ def test_successful_purchase_with_other_tax_fields
end.respond_with(successful_purchase_response)
end

def test_successful_purchase_with_merchant_category_code
stub_comms do
@gateway.purchase(100, @credit_card, @options.merge!(merchant_category_code: '1111'))
end.check_request do |_endpoint, data, _headers|
assert_match(/<merchantCategoryCode>1111<\/merchantCategoryCode>/, data)
end.respond_with(successful_purchase_response)
end

def test_successful_purchase_with_purchase_totals_data
stub_comms do
@gateway.purchase(100, @credit_card, @options.merge(discount_management_indicator: 'T', purchase_tax_amount: 7.89, original_amount: 1.23, invoice_amount: 1.23))
Expand All @@ -122,6 +130,14 @@ def test_successful_authorize_with_national_tax_indicator
end.respond_with(successful_authorization_response)
end

def test_successful_authorize_with_merchant_category_code
stub_comms do
@gateway.authorize(100, @credit_card, @options.merge(merchant_category_code: '1111'))
end.check_request do |_endpoint, data, _headers|
assert_match(/<merchantCategoryCode>1111<\/merchantCategoryCode>/, data)
end.respond_with(successful_authorization_response)
end

def test_successful_authorize_with_cc_auth_service_fields
stub_comms do
@gateway.authorize(100, @credit_card, @options.merge(mobile_remote_payment_type: 'T'))
Expand Down Expand Up @@ -739,6 +755,14 @@ def test_capture_includes_mdd_fields
end.respond_with(successful_capture_response)
end

def test_successful_capture_with_merchant_category_code
stub_comms do
@gateway.capture(100, '1846925324700976124593', @options.merge!(merchant_category_code: '1111'))
end.check_request do |_endpoint, data, _headers|
assert_match(/<merchantCategoryCode>1111<\/merchantCategoryCode>/, data)
end.respond_with(successful_capture_response)
end

def test_successful_credit_card_purchase_request
@gateway.stubs(:ssl_post).returns(successful_capture_response)
assert response = @gateway.purchase(@amount, @credit_card, @options)
Expand Down Expand Up @@ -846,6 +870,14 @@ def test_successful_refund_with_elo_request
assert_success(@gateway.refund(@amount, response.authorization))
end

def test_successful_refund_with_merchant_category_code
stub_comms do
@gateway.refund(100, 'test;12345', @options.merge!(merchant_category_code: '1111'))
end.check_request do |_endpoint, data, _headers|
assert_match(/<merchantCategoryCode>1111<\/merchantCategoryCode>/, data)
end.respond_with(successful_refund_response)
end

def test_successful_credit_to_card_request
@gateway.stubs(:ssl_post).returns(successful_card_credit_response)

Expand Down

0 comments on commit 576a2e5

Please sign in to comment.