Skip to content

Commit

Permalink
Adds ELO card type
Browse files Browse the repository at this point in the history
This adds ELO bin ranges and ELO brand logic in general. ELO is in a
partnership with Discover and is part of the Discover Global Network.
Using the ELO BIN ranges before the Discover regex allows those cards
to be identified correctly.

It also adds `elo` as a supported cardtype for the Adyen gateway.

Unit Tests
27 tests, 132 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions,
0 notifications 100% passed

Remote Tests
45 tests, 122 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions,
0 notifications 100% passed
  • Loading branch information
deedeelavinder committed Mar 4, 2019
1 parent d8b15aa commit e705238
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 1 deletion.
2 changes: 2 additions & 0 deletions lib/active_merchant/billing/credit_card.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module Billing #:nodoc:
# * Dankort
# * Maestro
# * Forbrugsforeningen
# * Elo
#
# For testing purposes, use the 'bogus' credit card brand. This skips the vast majority of
# validations, allowing you to focus on your core concerns until you're ready to be more concerned
Expand Down Expand Up @@ -88,6 +89,7 @@ def number=(value)
# * +'dankort'+
# * +'maestro'+
# * +'forbrugsforeningen'+
# * +'elo'+
#
# Or, if you wish to test your implementation, +'bogus'+.
#
Expand Down
13 changes: 13 additions & 0 deletions lib/active_merchant/billing/credit_card_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module CreditCardMethods
CARD_COMPANY_DETECTORS = {
'visa' => ->(num) { num =~ /^4\d{12}(\d{3})?(\d{3})?$/ },
'master' => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), MASTERCARD_RANGES) },
'elo' => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), ELO_RANGES) },
'discover' => ->(num) { num =~ /^(6011|65\d{2}|64[4-9]\d)\d{12,15}|(62\d{14,17})$/ },
'american_express' => ->(num) { num =~ /^3[47]\d{13}$/ },
'diners_club' => ->(num) { num =~ /^3(0[0-5]|[68]\d)\d{11}$/ },
Expand Down Expand Up @@ -66,6 +67,18 @@ module CreditCardMethods
(670000..679999),
]

# https://dev.elo.com.br/apis/tabela-de-bins, download csv from left sidebar
ELO_RANGES = [
506707..506708, 506715..506715, 506718..506722, 506724..506724, 506726..506736, 506739..506739, 506741..506743,
506745..506747, 506753..506753, 506774..506776, 506778..506778, 509000..509001, 509003..509003, 509007..509007,
509020..509022, 509035..509035, 509039..509042, 509045..509045, 509048..509048, 509051..509071, 509073..509074,
509077..509080, 509084..509084, 509091..509094, 509098..509098, 509100..509100, 509104..509104, 509106..509109,
627780..627780, 636368..636368, 650031..650033, 650035..650045, 650047..650047, 650406..650410, 650434..650436,
650439..650439, 650485..650504, 650506..650530, 650577..650580, 650582..650591, 650721..650727, 650901..650922,
650928..650928, 650938..650939, 650946..650948, 650954..650955, 650962..650963, 650967..650967, 650971..650971,
651652..651667, 651675..651678, 655000..655010, 655012..655015, 655051..655052, 655056..655057
]

def self.included(base)
base.extend(ClassMethods)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/active_merchant/billing/gateways/adyen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class AdyenGateway < Gateway

self.supported_countries = ['AT', 'AU', 'BE', 'BG', 'BR', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'GI', 'GR', 'HK', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'MX', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SG', 'SK', 'SI', 'US']
self.default_currency = 'USD'
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb, :dankort, :maestro, :discover]
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb, :dankort, :maestro, :discover, :elo]

self.money_format = :cents

Expand Down
59 changes: 59 additions & 0 deletions test/remote/gateways/remote_adyen_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ def setup
:brand => 'visa'
)

@elo_credit_card = credit_card('5066 9911 1111 1118',
:month => 10,
:year => 2020,
:first_name => 'John',
:last_name => 'Smith',
:verification_value => '737',
:brand => 'elo'
)

@three_ds_enrolled_card = credit_card('4212345678901237', brand: :visa)

@declined_card = credit_card('4000300011112220')
Expand Down Expand Up @@ -158,6 +167,12 @@ def test_successful_purchase_with_google_pay
assert_equal '[capture-received]', response.message
end

def test_successful_purchase_with_elo_card
response = @gateway.purchase(@amount, @elo_credit_card, @options.merge(currency: 'BRL'))
assert_success response
assert_equal '[capture-received]', response.message
end

def test_failed_purchase
response = @gateway.purchase(@amount, @declined_card, @options)
assert_failure response
Expand All @@ -173,6 +188,15 @@ def test_successful_authorize_and_capture
assert_equal '[capture-received]', capture.message
end

def test_successful_authorize_and_capture_with_elo_card
auth = @gateway.authorize(@amount, @elo_credit_card, @options)
assert_success auth

assert capture = @gateway.capture(@amount, auth.authorization)
assert_success capture
assert_equal '[capture-received]', capture.message
end

def test_partial_capture
auth = @gateway.authorize(@amount, @credit_card, @options)
assert_success auth
Expand All @@ -196,6 +220,15 @@ def test_successful_refund
assert_equal '[refund-received]', refund.message
end

def test_successful_refund_with_elo_card
purchase = @gateway.purchase(@amount, @elo_credit_card, @options)
assert_success purchase

assert refund = @gateway.refund(@amount, purchase.authorization)
assert_success refund
assert_equal '[refund-received]', refund.message
end

def test_partial_refund
purchase = @gateway.purchase(@amount, @credit_card, @options)
assert_success purchase
Expand All @@ -219,6 +252,15 @@ def test_successful_void
assert_equal '[cancel-received]', void.message
end

def test_successful_void_with_elo_card
auth = @gateway.authorize(@amount, @elo_credit_card, @options)
assert_success auth

assert void = @gateway.void(auth.authorization)
assert_success void
assert_equal '[cancel-received]', void.message
end

def test_failed_void
response = @gateway.void('')
assert_failure response
Expand All @@ -233,6 +275,14 @@ def test_successful_store
assert_equal 'Authorised', response.message
end

def test_successful_store_with_elo_card
assert response = @gateway.store(@elo_credit_card, @options)

assert_success response
assert !response.authorization.split('#')[2].nil?
assert_equal 'Authorised', response.message
end

def test_failed_store
assert response = @gateway.store(@declined_card, @options)

Expand All @@ -249,6 +299,15 @@ def test_successful_purchase_using_stored_card
assert_equal '[capture-received]', response.message
end

def test_successful_purchase_using_stored_elo_card
assert store_response = @gateway.store(@elo_credit_card, @options)
assert_success store_response

response = @gateway.purchase(@amount, store_response.authorization, @options)
assert_success response
assert_equal '[capture-received]', response.message
end

def test_successful_authorize_using_stored_card
assert store_response = @gateway.store(@credit_card, @options)
assert_success store_response
Expand Down
6 changes: 6 additions & 0 deletions test/unit/credit_card_methods_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ def test_should_detect_vr_card
assert_equal 'vr', CreditCard.brand?('63703644957644')
end

def test_should_detect_elo_card
assert_equal 'elo', CreditCard.brand?('5090510000000000')
assert_equal 'elo', CreditCard.brand?('5067530000000000')
assert_equal 'elo', CreditCard.brand?('6509550000000000')
end

def test_should_detect_when_an_argument_brand_does_not_match_calculated_brand
assert CreditCard.matching_brand?('4175001000000000', 'visa')
assert_false CreditCard.matching_brand?('4175001000000000', 'master')
Expand Down
37 changes: 37 additions & 0 deletions test/unit/gateways/adyen_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ def setup
:brand => 'visa'
)

@elo_credit_card = credit_card('5066 9911 1111 1118',
:month => 10,
:year => 2020,
:first_name => 'John',
:last_name => 'Smith',
:verification_value => '737',
:brand => 'elo'
)

@three_ds_enrolled_card = credit_card('4212345678901237', brand: :visa)

@apple_pay_card = network_tokenization_credit_card('4111111111111111',
Expand Down Expand Up @@ -117,6 +126,15 @@ def test_successful_purchase
assert response.test?
end

def test_successful_purchase_with_elo_card
response = stub_comms do
@gateway.purchase(@amount, @elo_credit_card, @options)
end.respond_with(successful_authorize_with_elo_response, successful_capture_with_elo_repsonse)
assert_success response
assert_equal '8835511210681145#8835511210689965#', response.authorization
assert response.test?
end

def test_successful_maestro_purchase
response = stub_comms do
@gateway.purchase(@amount, @credit_card, @options.merge({selected_brand: 'maestro', overwrite_brand: 'true'}))
Expand Down Expand Up @@ -448,6 +466,25 @@ def failed_purchase_response
RESPONSE
end

def successful_authorize_with_elo_response
<<-RESPONSE
{
"pspReference":"8835511210681145",
"resultCode":"Authorised",
"authCode":"98696"
}
RESPONSE
end

def successful_capture_with_elo_repsonse
<<-RESPONSE
{
"pspReference":"8835511210689965",
"response":"[capture-received]"
}
RESPONSE
end

def successful_authorize_response
<<-RESPONSE
{
Expand Down

0 comments on commit e705238

Please sign in to comment.