/, body)
end.respond_with(successful_authorize_response)
@@ -129,8 +129,8 @@ def test_purchase_using_reference_sets_proper_elements
def test_setting_mode_sets_proper_element
stub_comms do
- @gateway.purchase(@amount, 'MY_AUTHORIZE_VALUE', {mode: 'CRAZY_TEST_MODE'})
- end.check_request do |endpoint, body, headers|
+ @gateway.purchase(@amount, 'MY_AUTHORIZE_VALUE', { mode: 'CRAZY_TEST_MODE' })
+ end.check_request do |_endpoint, body, _headers|
assert_xpath_text(body, '//Transaction/@mode', 'CRAZY_TEST_MODE')
end.respond_with(successful_authorize_response)
end
@@ -138,7 +138,7 @@ def test_setting_mode_sets_proper_element
def test_defaults_to_integrator_test
stub_comms do
@gateway.purchase(@amount, 'MY_AUTHORIZE_VALUE', {})
- end.check_request do |endpoint, body, headers|
+ end.check_request do |_endpoint, body, _headers|
assert_xpath_text(body, '//Transaction/@mode', 'INTEGRATOR_TEST')
end.respond_with(successful_authorize_response)
end
diff --git a/test/unit/gateways/balanced_test.rb b/test/unit/gateways/balanced_test.rb
index 68e98b4f0d4..86d16dfc067 100644
--- a/test/unit/gateways/balanced_test.rb
+++ b/test/unit/gateways/balanced_test.rb
@@ -33,7 +33,7 @@ def test_successful_purchase
def test_successful_purchase_with_outside_token
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, '/cards/CCVOX2d7Ar6Ze5TOxHsebeH', @options)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, endpoint, _data, _headers|
assert_equal('https://api.balancedpayments.com/cards/CCVOX2d7Ar6Ze5TOxHsebeH/debits', endpoint)
end.respond_with(debits_response)
@@ -211,7 +211,7 @@ def test_store
new_email_address = '%d@example.org' % Time.now
assert response = @gateway.store(@credit_card, {
- email: new_email_address
+ email: new_email_address
})
assert_instance_of String, response.authorization
end
@@ -221,7 +221,7 @@ def test_successful_purchase_with_legacy_outside_token
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, legacy_outside_token, @options)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, endpoint, _data, _headers|
assert_equal('https://api.balancedpayments.com/cards/CC7m1Mtqk6rVJo5tcD1qitAC/debits', endpoint)
end.respond_with(debits_response)
@@ -237,7 +237,7 @@ def test_capturing_legacy_authorizations
[v1_authorization, v11_authorization].each do |authorization|
stub_comms(@gateway, :ssl_request) do
@gateway.capture(@amount, authorization)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, endpoint, _data, _headers|
assert_equal('https://api.balancedpayments.com/card_holds/HL7dYMhpVBcqAYqxLF5mZtQ5/debits', endpoint)
end.respond_with(authorized_debits_response)
end
@@ -250,7 +250,7 @@ def test_voiding_legacy_authorizations
[v1_authorization, v11_authorization].each do |authorization|
stub_comms(@gateway, :ssl_request) do
@gateway.void(authorization)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |method, endpoint, data, _headers|
assert_equal :put, method
assert_equal('https://api.balancedpayments.com/card_holds/HL7dYMhpVBcqAYqxLF5mZtQ5', endpoint)
assert_match %r{\bis_void=true\b}, data
@@ -265,7 +265,7 @@ def test_refunding_legacy_purchases
[v1_authorization, v11_authorization].each do |authorization|
stub_comms(@gateway, :ssl_request) do
@gateway.refund(nil, authorization)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, endpoint, _data, _headers|
assert_equal('https://api.balancedpayments.com/debits/WD2x6vLS7RzHYEcdymqRyNAO/refunds', endpoint)
end.respond_with(refunds_response)
end
@@ -275,8 +275,9 @@ def test_passing_address
a = address
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card, address: a)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, endpoint, data, _headers|
next if endpoint =~ /debits/
+
clean = proc { |s| Regexp.escape(CGI.escape(s)) }
assert_match(%r{address\[line1\]=#{clean[a[:address1]]}}, data)
assert_match(%r{address\[line2\]=#{clean[a[:address2]]}}, data)
@@ -292,8 +293,9 @@ def test_passing_address
def test_passing_address_without_zip
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card, address: address(zip: nil))
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, endpoint, data, _headers|
next if endpoint =~ /debits/
+
assert_no_match(%r{address}, data)
end.respond_with(cards_response, debits_response)
@@ -303,8 +305,9 @@ def test_passing_address_without_zip
def test_passing_address_with_blank_zip
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card, address: address(zip: ' '))
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, endpoint, data, _headers|
next if endpoint =~ /debits/
+
assert_no_match(%r{address}, data)
end.respond_with(cards_response, debits_response)
@@ -331,539 +334,539 @@ def invalid_login_response
end
def marketplace_response
- <<-RESPONSE
-{
- "meta": {
- "last": "/marketplaces?limit=10&offset=0",
- "next": null,
- "href": "/marketplaces?limit=10&offset=0",
- "limit": 10,
- "offset": 0,
- "previous": null,
- "total": 1,
- "first": "/marketplaces?limit=10&offset=0"
- },
- "marketplaces": [
- {
- "in_escrow": 47202,
- "domain_url": "example.com",
- "name": "Test Marketplace",
- "links": {
- "owner_customer": "AC73SN17anKkjk6Y1sVe2uaq"
- },
- "href": "/marketplaces/TEST-MP73SaFdpQePv9dOaG5wXOGO",
- "created_at": "2012-07-19T17:33:51.974238Z",
- "support_email_address": "support@example.com",
- "updated_at": "2012-07-19T17:33:52.848042Z",
- "support_phone_number": "+16505551234",
- "production": false,
- "meta": {},
- "unsettled_fees": 0,
- "id": "TEST-MP73SaFdpQePv9dOaG5wXOGO"
- }
- ],
- "links": {
- "marketplaces.debits": "/debits",
- "marketplaces.reversals": "/reversals",
- "marketplaces.customers": "/customers",
- "marketplaces.credits": "/credits",
- "marketplaces.cards": "/cards",
- "marketplaces.card_holds": "/card_holds",
- "marketplaces.refunds": "/refunds",
- "marketplaces.owner_customer": "/customers/{marketplaces.owner_customer}",
- "marketplaces.transactions": "/transactions",
- "marketplaces.bank_accounts": "/bank_accounts",
- "marketplaces.callbacks": "/callbacks",
- "marketplaces.events": "/events"
- }
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "meta": {
+ "last": "/marketplaces?limit=10&offset=0",
+ "next": null,
+ "href": "/marketplaces?limit=10&offset=0",
+ "limit": 10,
+ "offset": 0,
+ "previous": null,
+ "total": 1,
+ "first": "/marketplaces?limit=10&offset=0"
+ },
+ "marketplaces": [
+ {
+ "in_escrow": 47202,
+ "domain_url": "example.com",
+ "name": "Test Marketplace",
+ "links": {
+ "owner_customer": "AC73SN17anKkjk6Y1sVe2uaq"
+ },
+ "href": "/marketplaces/TEST-MP73SaFdpQePv9dOaG5wXOGO",
+ "created_at": "2012-07-19T17:33:51.974238Z",
+ "support_email_address": "support@example.com",
+ "updated_at": "2012-07-19T17:33:52.848042Z",
+ "support_phone_number": "+16505551234",
+ "production": false,
+ "meta": {},
+ "unsettled_fees": 0,
+ "id": "TEST-MP73SaFdpQePv9dOaG5wXOGO"
+ }
+ ],
+ "links": {
+ "marketplaces.debits": "/debits",
+ "marketplaces.reversals": "/reversals",
+ "marketplaces.customers": "/customers",
+ "marketplaces.credits": "/credits",
+ "marketplaces.cards": "/cards",
+ "marketplaces.card_holds": "/card_holds",
+ "marketplaces.refunds": "/refunds",
+ "marketplaces.owner_customer": "/customers/{marketplaces.owner_customer}",
+ "marketplaces.transactions": "/transactions",
+ "marketplaces.bank_accounts": "/bank_accounts",
+ "marketplaces.callbacks": "/callbacks",
+ "marketplaces.events": "/events"
+ }
+ }
+ RESPONSE
end
def cards_response
- <<-RESPONSE
-{
- "cards": [
- {
- "cvv_match": null,
- "links": {
- "customer": null
- },
- "name": "Longbob Longsen",
- "expiration_year": 2015,
- "avs_street_match": null,
- "is_verified": true,
- "created_at": "2014-02-06T23:19:27.146436Z",
- "cvv_result": null,
- "brand": "Visa",
- "number": "xxxxxxxxxxxx1111",
- "updated_at": "2014-02-06T23:19:27.146441Z",
- "id": "CCXfdppSxXOGzaMUHp9EQyI",
- "expiration_month": 9,
- "cvv": null,
- "meta": {},
- "href": "/cards/CCXfdppSxXOGzaMUHp9EQyI",
- "address": {
- "city": null,
- "line2": null,
- "line1": null,
- "state": null,
- "postal_code": null,
- "country_code": null
- },
- "fingerprint": "e0928a7fe2233bf6697413f663b3d94114358e6ac027fcd58ceba0bb37f05039",
- "avs_postal_match": null,
- "avs_result": null
- }
- ],
- "links": {
- "cards.card_holds": "/cards/{cards.id}/card_holds",
- "cards.customer": "/customers/{cards.customer}",
- "cards.debits": "/cards/{cards.id}/debits"
- }
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "cards": [
+ {
+ "cvv_match": null,
+ "links": {
+ "customer": null
+ },
+ "name": "Longbob Longsen",
+ "expiration_year": 2015,
+ "avs_street_match": null,
+ "is_verified": true,
+ "created_at": "2014-02-06T23:19:27.146436Z",
+ "cvv_result": null,
+ "brand": "Visa",
+ "number": "xxxxxxxxxxxx1111",
+ "updated_at": "2014-02-06T23:19:27.146441Z",
+ "id": "CCXfdppSxXOGzaMUHp9EQyI",
+ "expiration_month": 9,
+ "cvv": null,
+ "meta": {},
+ "href": "/cards/CCXfdppSxXOGzaMUHp9EQyI",
+ "address": {
+ "city": null,
+ "line2": null,
+ "line1": null,
+ "state": null,
+ "postal_code": null,
+ "country_code": null
+ },
+ "fingerprint": "e0928a7fe2233bf6697413f663b3d94114358e6ac027fcd58ceba0bb37f05039",
+ "avs_postal_match": null,
+ "avs_result": null
+ }
+ ],
+ "links": {
+ "cards.card_holds": "/cards/{cards.id}/card_holds",
+ "cards.customer": "/customers/{cards.customer}",
+ "cards.debits": "/cards/{cards.id}/debits"
+ }
+ }
+ RESPONSE
end
def debits_response
- <<-RESPONSE
-{
- "debits": [
- {
- "status": "succeeded",
- "description": "Shopify Purchase",
- "links": {
- "customer": null,
- "source": "CCXfdppSxXOGzaMUHp9EQyI",
- "order": null,
- "dispute": null
- },
- "updated_at": "2014-02-06T23:19:29.690815Z",
- "created_at": "2014-02-06T23:19:28.709143Z",
- "transaction_number": "W250-112-1883",
- "failure_reason": null,
- "currency": "USD",
- "amount": 100,
- "failure_reason_code": null,
- "meta": {},
- "href": "/debits/WDYZhc3mWCkxvOwIokeUz6M",
- "appears_on_statement_as": "BAL*example.com",
- "id": "WDYZhc3mWCkxvOwIokeUz6M"
- }
- ],
- "links": {
- "debits.customer": "/customers/{debits.customer}",
- "debits.dispute": "/disputes/{debits.dispute}",
- "debits.source": "/resources/{debits.source}",
- "debits.order": "/orders/{debits.order}",
- "debits.refunds": "/debits/{debits.id}/refunds",
- "debits.events": "/debits/{debits.id}/events"
- }
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "debits": [
+ {
+ "status": "succeeded",
+ "description": "Shopify Purchase",
+ "links": {
+ "customer": null,
+ "source": "CCXfdppSxXOGzaMUHp9EQyI",
+ "order": null,
+ "dispute": null
+ },
+ "updated_at": "2014-02-06T23:19:29.690815Z",
+ "created_at": "2014-02-06T23:19:28.709143Z",
+ "transaction_number": "W250-112-1883",
+ "failure_reason": null,
+ "currency": "USD",
+ "amount": 100,
+ "failure_reason_code": null,
+ "meta": {},
+ "href": "/debits/WDYZhc3mWCkxvOwIokeUz6M",
+ "appears_on_statement_as": "BAL*example.com",
+ "id": "WDYZhc3mWCkxvOwIokeUz6M"
+ }
+ ],
+ "links": {
+ "debits.customer": "/customers/{debits.customer}",
+ "debits.dispute": "/disputes/{debits.dispute}",
+ "debits.source": "/resources/{debits.source}",
+ "debits.order": "/orders/{debits.order}",
+ "debits.refunds": "/debits/{debits.id}/refunds",
+ "debits.events": "/debits/{debits.id}/events"
+ }
+ }
+ RESPONSE
end
def authorized_debits_response
- <<-RESPONSE
-{
- "debits": [
- {
- "status": "succeeded",
- "description": "Shopify Purchase",
- "links": {
- "customer": null,
- "source": "CC2uKKcUhaSFRrl2mnGPSbDO",
- "order": null,
- "dispute": null
- },
- "updated_at": "2014-02-06T23:19:29.690815Z",
- "created_at": "2014-02-06T23:19:28.709143Z",
- "transaction_number": "W250-112-1883",
- "failure_reason": null,
- "currency": "USD",
- "amount": 100,
- "failure_reason_code": null,
- "meta": {},
- "href": "/debits/WDYZhc3mWCkxvOwIokeUz6M",
- "appears_on_statement_as": "BAL*example.com",
- "id": "WDYZhc3mWCkxvOwIokeUz6M"
- }
- ],
- "links": {
- "debits.customer": "/customers/{debits.customer}",
- "debits.dispute": "/disputes/{debits.dispute}",
- "debits.source": "/resources/{debits.source}",
- "debits.order": "/orders/{debits.order}",
- "debits.refunds": "/debits/{debits.id}/refunds",
- "debits.events": "/debits/{debits.id}/events"
- }
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "debits": [
+ {
+ "status": "succeeded",
+ "description": "Shopify Purchase",
+ "links": {
+ "customer": null,
+ "source": "CC2uKKcUhaSFRrl2mnGPSbDO",
+ "order": null,
+ "dispute": null
+ },
+ "updated_at": "2014-02-06T23:19:29.690815Z",
+ "created_at": "2014-02-06T23:19:28.709143Z",
+ "transaction_number": "W250-112-1883",
+ "failure_reason": null,
+ "currency": "USD",
+ "amount": 100,
+ "failure_reason_code": null,
+ "meta": {},
+ "href": "/debits/WDYZhc3mWCkxvOwIokeUz6M",
+ "appears_on_statement_as": "BAL*example.com",
+ "id": "WDYZhc3mWCkxvOwIokeUz6M"
+ }
+ ],
+ "links": {
+ "debits.customer": "/customers/{debits.customer}",
+ "debits.dispute": "/disputes/{debits.dispute}",
+ "debits.source": "/resources/{debits.source}",
+ "debits.order": "/orders/{debits.order}",
+ "debits.refunds": "/debits/{debits.id}/refunds",
+ "debits.events": "/debits/{debits.id}/events"
+ }
+ }
+ RESPONSE
end
def authorized_partial_debits_response
- <<-RESPONSE
-{
- "debits": [
- {
- "status": "succeeded",
- "description": "Shopify Purchase",
- "links": {
- "customer": null,
- "source": "CC2uKKcUhaSFRrl2mnGPSbDO",
- "order": null,
- "dispute": null
- },
- "updated_at": "2014-02-06T23:19:29.690815Z",
- "created_at": "2014-02-06T23:19:28.709143Z",
- "transaction_number": "W250-112-1883",
- "failure_reason": null,
- "currency": "USD",
- "amount": 50,
- "failure_reason_code": null,
- "meta": {},
- "href": "/debits/WDYZhc3mWCkxvOwIokeUz6M",
- "appears_on_statement_as": "BAL*example.com",
- "id": "WDYZhc3mWCkxvOwIokeUz6M"
- }
- ],
- "links": {
- "debits.customer": "/customers/{debits.customer}",
- "debits.dispute": "/disputes/{debits.dispute}",
- "debits.source": "/resources/{debits.source}",
- "debits.order": "/orders/{debits.order}",
- "debits.refunds": "/debits/{debits.id}/refunds",
- "debits.events": "/debits/{debits.id}/events"
- }
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "debits": [
+ {
+ "status": "succeeded",
+ "description": "Shopify Purchase",
+ "links": {
+ "customer": null,
+ "source": "CC2uKKcUhaSFRrl2mnGPSbDO",
+ "order": null,
+ "dispute": null
+ },
+ "updated_at": "2014-02-06T23:19:29.690815Z",
+ "created_at": "2014-02-06T23:19:28.709143Z",
+ "transaction_number": "W250-112-1883",
+ "failure_reason": null,
+ "currency": "USD",
+ "amount": 50,
+ "failure_reason_code": null,
+ "meta": {},
+ "href": "/debits/WDYZhc3mWCkxvOwIokeUz6M",
+ "appears_on_statement_as": "BAL*example.com",
+ "id": "WDYZhc3mWCkxvOwIokeUz6M"
+ }
+ ],
+ "links": {
+ "debits.customer": "/customers/{debits.customer}",
+ "debits.dispute": "/disputes/{debits.dispute}",
+ "debits.source": "/resources/{debits.source}",
+ "debits.order": "/orders/{debits.order}",
+ "debits.refunds": "/debits/{debits.id}/refunds",
+ "debits.events": "/debits/{debits.id}/events"
+ }
+ }
+ RESPONSE
end
def declined_response
- <<-RESPONSE
-{
- "errors": [
- {
- "status": "Payment Required",
- "category_code": "card-declined",
- "additional": "Customer call bank",
- "status_code": 402,
- "category_type": "banking",
- "extras": {},
- "request_id": "OHMc8d80eb4903011e390c002a1fe53e539",
- "description": "R530: Customer call bank. Your request id is OHMc8d80eb4903011e390c002a1fe53e539."
- }
- ]
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "errors": [
+ {
+ "status": "Payment Required",
+ "category_code": "card-declined",
+ "additional": "Customer call bank",
+ "status_code": 402,
+ "category_type": "banking",
+ "extras": {},
+ "request_id": "OHMc8d80eb4903011e390c002a1fe53e539",
+ "description": "R530: Customer call bank. Your request id is OHMc8d80eb4903011e390c002a1fe53e539."
+ }
+ ]
+ }
+ RESPONSE
end
def bad_email_response
- <<-'RESPONSE'
-{
- "errors": [
- {
- "status": "Bad Request",
- "category_code": "request",
- "additional": null,
- "status_code": 400,
- "category_type": "request",
- "extras": {
- "email": "\"invalid_email\" must be a valid email address as specified by RFC-2822"
- },
- "request_id": "OHM9107a4bc903111e390c002a1fe53e539",
- "description": "Invalid field [email] - \"invalid_email\" must be a valid email address as specified by RFC-2822 Your request id is OHM9107a4bc903111e390c002a1fe53e539."
- }
- ]
-}
-RESPONSE
+ <<~'RESPONSE'
+ {
+ "errors": [
+ {
+ "status": "Bad Request",
+ "category_code": "request",
+ "additional": null,
+ "status_code": 400,
+ "category_type": "request",
+ "extras": {
+ "email": "\"invalid_email\" must be a valid email address as specified by RFC-2822"
+ },
+ "request_id": "OHM9107a4bc903111e390c002a1fe53e539",
+ "description": "Invalid field [email] - \"invalid_email\" must be a valid email address as specified by RFC-2822 Your request id is OHM9107a4bc903111e390c002a1fe53e539."
+ }
+ ]
+ }
+ RESPONSE
end
def account_frozen_response
- <<-RESPONSE
-{
- "errors": [
- {
- "status": "Payment Required",
- "category_code": "card-declined",
- "additional": "Account Frozen",
- "status_code": 402,
- "category_type": "banking",
- "extras": {},
- "request_id": "OHMec50b6be903c11e387cb026ba7cac9da",
- "description": "R758: Account Frozen. Your request id is OHMec50b6be903c11e387cb026ba7cac9da."
- }
- ],
- "links": {
- "debits.customer": "/customers/{debits.customer}",
- "debits.dispute": "/disputes/{debits.dispute}",
- "debits.source": "/resources/{debits.source}",
- "debits.order": "/orders/{debits.order}",
- "debits.refunds": "/debits/{debits.id}/refunds",
- "debits.events": "/debits/{debits.id}/events"
- },
- "debits": [
- {
- "status": "failed",
- "description": "Shopify Purchase",
- "links": {
- "customer": null,
- "source": "CC7a41DYIaSSyGoau6rZ8VcG",
- "order": null,
- "dispute": null
- },
- "updated_at": "2014-02-07T21:15:10.107464Z",
- "created_at": "2014-02-07T21:15:09.206335Z",
- "transaction_number": "W202-883-1157",
- "failure_reason": "R758: Account Frozen.",
- "currency": "USD",
- "amount": 100,
- "failure_reason_code": "card-declined",
- "meta": {},
- "href": "/debits/WD7cjQ5gizGWMDWbxDndgm7w",
- "appears_on_statement_as": "BAL*example.com",
- "id": "WD7cjQ5gizGWMDWbxDndgm7w"
- }
- ]
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "errors": [
+ {
+ "status": "Payment Required",
+ "category_code": "card-declined",
+ "additional": "Account Frozen",
+ "status_code": 402,
+ "category_type": "banking",
+ "extras": {},
+ "request_id": "OHMec50b6be903c11e387cb026ba7cac9da",
+ "description": "R758: Account Frozen. Your request id is OHMec50b6be903c11e387cb026ba7cac9da."
+ }
+ ],
+ "links": {
+ "debits.customer": "/customers/{debits.customer}",
+ "debits.dispute": "/disputes/{debits.dispute}",
+ "debits.source": "/resources/{debits.source}",
+ "debits.order": "/orders/{debits.order}",
+ "debits.refunds": "/debits/{debits.id}/refunds",
+ "debits.events": "/debits/{debits.id}/events"
+ },
+ "debits": [
+ {
+ "status": "failed",
+ "description": "Shopify Purchase",
+ "links": {
+ "customer": null,
+ "source": "CC7a41DYIaSSyGoau6rZ8VcG",
+ "order": null,
+ "dispute": null
+ },
+ "updated_at": "2014-02-07T21:15:10.107464Z",
+ "created_at": "2014-02-07T21:15:09.206335Z",
+ "transaction_number": "W202-883-1157",
+ "failure_reason": "R758: Account Frozen.",
+ "currency": "USD",
+ "amount": 100,
+ "failure_reason_code": "card-declined",
+ "meta": {},
+ "href": "/debits/WD7cjQ5gizGWMDWbxDndgm7w",
+ "appears_on_statement_as": "BAL*example.com",
+ "id": "WD7cjQ5gizGWMDWbxDndgm7w"
+ }
+ ]
+ }
+ RESPONSE
end
def appears_on_response
- <<-RESPONSE
-{
- "debits": [
- {
- "status": "succeeded",
- "description": "Shopify Purchase",
- "links": {
- "customer": null,
- "source": "CC4SKo0WY3lhfWc6CgMyPo34",
- "order": null,
- "dispute": null
- },
- "updated_at": "2014-02-07T21:20:13.950392Z",
- "created_at": "2014-02-07T21:20:12.737821Z",
- "transaction_number": "W337-477-3752",
- "failure_reason": null,
- "currency": "USD",
- "amount": 100,
- "failure_reason_code": null,
- "meta": {},
- "href": "/debits/WD4UDDm6iqtYMEd21UBaa50H",
- "appears_on_statement_as": "BAL*Homer Electric",
- "id": "WD4UDDm6iqtYMEd21UBaa50H"
- }
- ],
- "links": {
- "debits.customer": "/customers/{debits.customer}",
- "debits.dispute": "/disputes/{debits.dispute}",
- "debits.source": "/resources/{debits.source}",
- "debits.order": "/orders/{debits.order}",
- "debits.refunds": "/debits/{debits.id}/refunds",
- "debits.events": "/debits/{debits.id}/events"
- }
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "debits": [
+ {
+ "status": "succeeded",
+ "description": "Shopify Purchase",
+ "links": {
+ "customer": null,
+ "source": "CC4SKo0WY3lhfWc6CgMyPo34",
+ "order": null,
+ "dispute": null
+ },
+ "updated_at": "2014-02-07T21:20:13.950392Z",
+ "created_at": "2014-02-07T21:20:12.737821Z",
+ "transaction_number": "W337-477-3752",
+ "failure_reason": null,
+ "currency": "USD",
+ "amount": 100,
+ "failure_reason_code": null,
+ "meta": {},
+ "href": "/debits/WD4UDDm6iqtYMEd21UBaa50H",
+ "appears_on_statement_as": "BAL*Homer Electric",
+ "id": "WD4UDDm6iqtYMEd21UBaa50H"
+ }
+ ],
+ "links": {
+ "debits.customer": "/customers/{debits.customer}",
+ "debits.dispute": "/disputes/{debits.dispute}",
+ "debits.source": "/resources/{debits.source}",
+ "debits.order": "/orders/{debits.order}",
+ "debits.refunds": "/debits/{debits.id}/refunds",
+ "debits.events": "/debits/{debits.id}/events"
+ }
+ }
+ RESPONSE
end
def holds_response
- <<-RESPONSE
-{
- "card_holds": [
- {
- "status": "succeeded",
- "description": "Shopify Purchase",
- "links": {
- "card": "CC2uKKcUhaSFRrl2mnGPSbDO",
- "debit": null
- },
- "updated_at": "2014-02-07T21:46:39.678439Z",
- "created_at": "2014-02-07T21:46:39.303526Z",
- "transaction_number": "HL343-028-3032",
- "expires_at": "2014-02-14T21:46:39.532363Z",
- "failure_reason": null,
- "currency": "USD",
- "amount": 100,
- "meta": {},
- "href": "/card_holds/HL2wPXf6ByqkLMiWGab7QRsq",
- "failure_reason_code": null,
- "voided_at": null,
- "id": "HL2wPXf6ByqkLMiWGab7QRsq"
- }
- ],
- "links": {
- "card_holds.events": "/card_holds/{card_holds.id}/events",
- "card_holds.card": "/resources/{card_holds.card}",
- "card_holds.debits": "/card_holds/{card_holds.id}/debits",
- "card_holds.debit": "/debits/{card_holds.debit}"
- }
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "card_holds": [
+ {
+ "status": "succeeded",
+ "description": "Shopify Purchase",
+ "links": {
+ "card": "CC2uKKcUhaSFRrl2mnGPSbDO",
+ "debit": null
+ },
+ "updated_at": "2014-02-07T21:46:39.678439Z",
+ "created_at": "2014-02-07T21:46:39.303526Z",
+ "transaction_number": "HL343-028-3032",
+ "expires_at": "2014-02-14T21:46:39.532363Z",
+ "failure_reason": null,
+ "currency": "USD",
+ "amount": 100,
+ "meta": {},
+ "href": "/card_holds/HL2wPXf6ByqkLMiWGab7QRsq",
+ "failure_reason_code": null,
+ "voided_at": null,
+ "id": "HL2wPXf6ByqkLMiWGab7QRsq"
+ }
+ ],
+ "links": {
+ "card_holds.events": "/card_holds/{card_holds.id}/events",
+ "card_holds.card": "/resources/{card_holds.card}",
+ "card_holds.debits": "/card_holds/{card_holds.id}/debits",
+ "card_holds.debit": "/debits/{card_holds.debit}"
+ }
+ }
+ RESPONSE
end
def method_not_allowed_response
- <<-RESPONSE
-{
- "errors": [
- {
- "status": "Method Not Allowed",
- "category_code": "method-not-allowed",
- "description": "Your request id is OHMfaf5570a904211e3bcab026ba7f8ec28.",
- "status_code": 405,
- "category_type": "request",
- "request_id": "OHMfaf5570a904211e3bcab026ba7f8ec28"
- }
- ]
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "errors": [
+ {
+ "status": "Method Not Allowed",
+ "category_code": "method-not-allowed",
+ "description": "Your request id is OHMfaf5570a904211e3bcab026ba7f8ec28.",
+ "status_code": 405,
+ "category_type": "request",
+ "request_id": "OHMfaf5570a904211e3bcab026ba7f8ec28"
+ }
+ ]
+ }
+ RESPONSE
end
def unauthorized_response
- <<-RESPONSE
-{
- "errors": [
- {
- "status": "Unauthorized",
- "category_code": "authentication-required",
- "description": "The server could not verify that you are authorized to access the URL requested. You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.
In case you are allowed to request the document, please check your user-id and password and try again.
Your request id is OHM56702560904311e3988c026ba7cd33d0.",
- "status_code": 401,
- "category_type": "permission",
- "request_id": "OHM56702560904311e3988c026ba7cd33d0"
- }
- ]
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "errors": [
+ {
+ "status": "Unauthorized",
+ "category_code": "authentication-required",
+ "description": "The server could not verify that you are authorized to access the URL requested. You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.
In case you are allowed to request the document, please check your user-id and password and try again.
Your request id is OHM56702560904311e3988c026ba7cd33d0.",
+ "status_code": 401,
+ "category_type": "permission",
+ "request_id": "OHM56702560904311e3988c026ba7cd33d0"
+ }
+ ]
+ }
+ RESPONSE
end
def voided_hold_response
- <<-RESPONSE
-{
- "card_holds": [
- {
- "status": "succeeded",
- "description": "Shopify Purchase",
- "links": {
- "card": "CC52ACcRnrG5eupOERKK4OAq",
- "debit": null
- },
- "updated_at": "2014-02-07T22:10:28.923304Z",
- "created_at": "2014-02-07T22:10:27.904233Z",
- "transaction_number": "HL728-165-8425",
- "expires_at": "2014-02-14T22:10:28.045745Z",
- "failure_reason": null,
- "currency": "USD",
- "amount": 100,
- "meta": {},
- "href": "/card_holds/HL54qindwhlErSujLo5IcP5J",
- "failure_reason_code": null,
- "voided_at": "2014-02-07T22:10:28.923308Z",
- "id": "HL54qindwhlErSujLo5IcP5J"
- }
- ],
- "links": {
- "card_holds.events": "/card_holds/{card_holds.id}/events",
- "card_holds.card": "/resources/{card_holds.card}",
- "card_holds.debits": "/card_holds/{card_holds.id}/debits",
- "card_holds.debit": "/debits/{card_holds.debit}"
- }
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "card_holds": [
+ {
+ "status": "succeeded",
+ "description": "Shopify Purchase",
+ "links": {
+ "card": "CC52ACcRnrG5eupOERKK4OAq",
+ "debit": null
+ },
+ "updated_at": "2014-02-07T22:10:28.923304Z",
+ "created_at": "2014-02-07T22:10:27.904233Z",
+ "transaction_number": "HL728-165-8425",
+ "expires_at": "2014-02-14T22:10:28.045745Z",
+ "failure_reason": null,
+ "currency": "USD",
+ "amount": 100,
+ "meta": {},
+ "href": "/card_holds/HL54qindwhlErSujLo5IcP5J",
+ "failure_reason_code": null,
+ "voided_at": "2014-02-07T22:10:28.923308Z",
+ "id": "HL54qindwhlErSujLo5IcP5J"
+ }
+ ],
+ "links": {
+ "card_holds.events": "/card_holds/{card_holds.id}/events",
+ "card_holds.card": "/resources/{card_holds.card}",
+ "card_holds.debits": "/card_holds/{card_holds.id}/debits",
+ "card_holds.debit": "/debits/{card_holds.debit}"
+ }
+ }
+ RESPONSE
end
def refunds_response
- <<-RESPONSE
-{
- "links": {
- "refunds.dispute": "/disputes/{refunds.dispute}",
- "refunds.events": "/refunds/{refunds.id}/events",
- "refunds.debit": "/debits/{refunds.debit}",
- "refunds.order": "/orders/{refunds.order}"
- },
- "refunds": [
- {
- "status": "succeeded",
- "description": "Shopify Purchase",
- "links": {
- "debit": "WDAtJcbjh3EJLW0tp7CUxAk",
- "order": null,
- "dispute": null
- },
- "href": "/refunds/RFJ4N00zLaQFrfBkC8cbN68",
- "created_at": "2014-02-07T22:35:06.424855Z",
- "transaction_number": "RF424-240-3258",
- "updated_at": "2014-02-07T22:35:07.655276Z",
- "currency": "USD",
- "amount": 100,
- "meta": {},
- "id": "RFJ4N00zLaQFrfBkC8cbN68"
- }
- ]
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "links": {
+ "refunds.dispute": "/disputes/{refunds.dispute}",
+ "refunds.events": "/refunds/{refunds.id}/events",
+ "refunds.debit": "/debits/{refunds.debit}",
+ "refunds.order": "/orders/{refunds.order}"
+ },
+ "refunds": [
+ {
+ "status": "succeeded",
+ "description": "Shopify Purchase",
+ "links": {
+ "debit": "WDAtJcbjh3EJLW0tp7CUxAk",
+ "order": null,
+ "dispute": null
+ },
+ "href": "/refunds/RFJ4N00zLaQFrfBkC8cbN68",
+ "created_at": "2014-02-07T22:35:06.424855Z",
+ "transaction_number": "RF424-240-3258",
+ "updated_at": "2014-02-07T22:35:07.655276Z",
+ "currency": "USD",
+ "amount": 100,
+ "meta": {},
+ "id": "RFJ4N00zLaQFrfBkC8cbN68"
+ }
+ ]
+ }
+ RESPONSE
end
def partial_refunds_response
- <<-RESPONSE
-{
- "links": {
- "refunds.dispute": "/disputes/{refunds.dispute}",
- "refunds.events": "/refunds/{refunds.id}/events",
- "refunds.debit": "/debits/{refunds.debit}",
- "refunds.order": "/orders/{refunds.order}"
- },
- "refunds": [
- {
- "status": "succeeded",
- "description": "Shopify Purchase",
- "links": {
- "debit": "WDAtJcbjh3EJLW0tp7CUxAk",
- "order": null,
- "dispute": null
- },
- "href": "/refunds/RFJ4N00zLaQFrfBkC8cbN68",
- "created_at": "2014-02-07T22:35:06.424855Z",
- "transaction_number": "RF424-240-3258",
- "updated_at": "2014-02-07T22:35:07.655276Z",
- "currency": "USD",
- "amount": 50,
- "meta": {},
- "id": "RFJ4N00zLaQFrfBkC8cbN68"
- }
- ]
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "links": {
+ "refunds.dispute": "/disputes/{refunds.dispute}",
+ "refunds.events": "/refunds/{refunds.id}/events",
+ "refunds.debit": "/debits/{refunds.debit}",
+ "refunds.order": "/orders/{refunds.order}"
+ },
+ "refunds": [
+ {
+ "status": "succeeded",
+ "description": "Shopify Purchase",
+ "links": {
+ "debit": "WDAtJcbjh3EJLW0tp7CUxAk",
+ "order": null,
+ "dispute": null
+ },
+ "href": "/refunds/RFJ4N00zLaQFrfBkC8cbN68",
+ "created_at": "2014-02-07T22:35:06.424855Z",
+ "transaction_number": "RF424-240-3258",
+ "updated_at": "2014-02-07T22:35:07.655276Z",
+ "currency": "USD",
+ "amount": 50,
+ "meta": {},
+ "id": "RFJ4N00zLaQFrfBkC8cbN68"
+ }
+ ]
+ }
+ RESPONSE
end
def refunds_pending_response
- <<-RESPONSE
-{
- "links": {
- "refunds.dispute": "/disputes/{refunds.dispute}",
- "refunds.events": "/refunds/{refunds.id}/events",
- "refunds.debit": "/debits/{refunds.debit}",
- "refunds.order": "/orders/{refunds.order}"
- },
- "refunds": [
- {
- "status": "pending",
- "description": null,
- "links": {
- "debit": "WD7AT5AGKI0jccoElAEEqiuL",
- "order": null,
- "dispute": null
- },
- "href": "/refunds/RF46a5p6ZVMK4qVIeCJ8u2LE",
- "created_at": "2014-05-22T20:20:32.956467Z",
- "transaction_number": "RF485-302-2551",
- "updated_at": "2014-05-22T20:20:35.991553Z",
- "currency": "USD",
- "amount": 100,
- "meta": {},
- "id": "RF46a5p6ZVMK4qVIeCJ8u2LE"
- }
- ]
-}
-RESPONSE
+ <<~RESPONSE
+ {
+ "links": {
+ "refunds.dispute": "/disputes/{refunds.dispute}",
+ "refunds.events": "/refunds/{refunds.id}/events",
+ "refunds.debit": "/debits/{refunds.debit}",
+ "refunds.order": "/orders/{refunds.order}"
+ },
+ "refunds": [
+ {
+ "status": "pending",
+ "description": null,
+ "links": {
+ "debit": "WD7AT5AGKI0jccoElAEEqiuL",
+ "order": null,
+ "dispute": null
+ },
+ "href": "/refunds/RF46a5p6ZVMK4qVIeCJ8u2LE",
+ "created_at": "2014-05-22T20:20:32.956467Z",
+ "transaction_number": "RF485-302-2551",
+ "updated_at": "2014-05-22T20:20:35.991553Z",
+ "currency": "USD",
+ "amount": 100,
+ "meta": {},
+ "id": "RF46a5p6ZVMK4qVIeCJ8u2LE"
+ }
+ ]
+ }
+ RESPONSE
end
end
diff --git a/test/unit/gateways/bambora_apac_test.rb b/test/unit/gateways/bambora_apac_test.rb
index 3b4e62c2977..c31335dfdc4 100644
--- a/test/unit/gateways/bambora_apac_test.rb
+++ b/test/unit/gateways/bambora_apac_test.rb
@@ -16,7 +16,7 @@ def setup
def test_successful_purchase
response = stub_comms do
@gateway.purchase(@amount, @credit_card, order_id: 1)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(%r{username<}, data)
assert_match(%r{password<}, data)
@@ -48,7 +48,7 @@ def test_failed_purchase
def test_successful_authorize
response = stub_comms do
@gateway.authorize(@amount, @credit_card, order_id: 1)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(%r{1<}, data)
assert_match(%r{2<}, data)
@@ -61,7 +61,7 @@ def test_successful_authorize
def test_successful_capture
response = stub_comms do
@gateway.capture(@amount, 'receipt')
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(%r{receipt<}, data)
assert_match(%r{100<}, data)
@@ -73,7 +73,7 @@ def test_successful_capture
def test_successful_refund
response = stub_comms do
@gateway.refund(@amount, 'receipt')
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(%r{receipt<}, data)
assert_match(%r{100<}, data)
@@ -84,9 +84,10 @@ def test_successful_refund
def test_successful_void
response = stub_comms do
- @gateway.void(@amount, 'receipt')
- end.check_request do |endpoint, data, headers|
+ @gateway.void('receipt', amount: 200)
+ end.check_request do |_endpoint, data, _headers|
assert_match(%r{200<}, data)
end.respond_with(successful_void_response)
assert_success response
@@ -100,133 +101,133 @@ def test_scrub
private
def pre_scrubbed
- <<-'PRE_SCRUBBED'
-opening connection to demo.ippayments.com.au:443...
-opened
-starting SSL for demo.ippayments.com.au:443...
-SSL established
-<- "POST /interface/api/dts.asmx HTTP/1.1\r\nContent-Type: text/xml; charset=utf-8\r\nSoapaction: http://www.ippayments.com.au/interface/api/dts/SubmitSinglePayment\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: demo.ippayments.com.au\r\nContent-Length: 822\r\n\r\n"
-<- "\n\n \n \n \n \n 1\n \n 1\n \n 4005550000000001\n 09\n 2015\n 123\n Longbob Longsen\n \n \n nmi.api\n qwerty123\n \n \n\n]]>\n \n \n \n\n"
--> "HTTP/1.1 200 OK\r\n"
--> "Server: Microsoft-IIS/6.0\r\n"
--> "X-Robots-Tag: noindex\r\n"
--> "X-Powered-By: ASP.NET\r\n"
--> "Cache-Control: private, max-age=0\r\n"
--> "Content-Type: text/xml; charset=utf-8\r\n"
--> "Content-Length: 767\r\n"
--> "Date: Fri, 19 Dec 2014 19:55:13 GMT\r\n"
--> "Connection: close\r\n"
--> "\r\n"
-reading 767 bytes...
--> "<Response>\r\n\t<ResponseCode>1</ResponseCode>\r\n\t<Timestamp>20-Dec-2014 06:55:17</Timestamp>\r\n\t<Receipt></Receipt>\r\n\t<SettlementDate></SettlementDate>\r\n\t<DeclinedCode>183</DeclinedCode>\r\n\t<DeclinedMessage>Exception parsing transaction XML</DeclinedMessage>\r\n</Response>\r\n"
-read 767 bytes
-Conn close
+ <<~'PRE_SCRUBBED'
+ opening connection to demo.ippayments.com.au:443...
+ opened
+ starting SSL for demo.ippayments.com.au:443...
+ SSL established
+ <- "POST /interface/api/dts.asmx HTTP/1.1\r\nContent-Type: text/xml; charset=utf-8\r\nSoapaction: http://www.ippayments.com.au/interface/api/dts/SubmitSinglePayment\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: demo.ippayments.com.au\r\nContent-Length: 822\r\n\r\n"
+ <- "\n\n \n \n \n \n 1\n \n 1\n \n 4005550000000001\n 09\n 2015\n 123\n Longbob Longsen\n \n \n nmi.api\n qwerty123\n \n \n\n]]>\n \n \n \n\n"
+ -> "HTTP/1.1 200 OK\r\n"
+ -> "Server: Microsoft-IIS/6.0\r\n"
+ -> "X-Robots-Tag: noindex\r\n"
+ -> "X-Powered-By: ASP.NET\r\n"
+ -> "Cache-Control: private, max-age=0\r\n"
+ -> "Content-Type: text/xml; charset=utf-8\r\n"
+ -> "Content-Length: 767\r\n"
+ -> "Date: Fri, 19 Dec 2014 19:55:13 GMT\r\n"
+ -> "Connection: close\r\n"
+ -> "\r\n"
+ reading 767 bytes...
+ -> "<Response>\r\n\t<ResponseCode>1</ResponseCode>\r\n\t<Timestamp>20-Dec-2014 06:55:17</Timestamp>\r\n\t<Receipt></Receipt>\r\n\t<SettlementDate></SettlementDate>\r\n\t<DeclinedCode>183</DeclinedCode>\r\n\t<DeclinedMessage>Exception parsing transaction XML</DeclinedMessage>\r\n</Response>\r\n"
+ read 767 bytes
+ Conn close
PRE_SCRUBBED
end
def post_scrubbed
- <<-'POST_SCRUBBED'
-opening connection to demo.ippayments.com.au:443...
-opened
-starting SSL for demo.ippayments.com.au:443...
-SSL established
-<- "POST /interface/api/dts.asmx HTTP/1.1\r\nContent-Type: text/xml; charset=utf-8\r\nSoapaction: http://www.ippayments.com.au/interface/api/dts/SubmitSinglePayment\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: demo.ippayments.com.au\r\nContent-Length: 822\r\n\r\n"
-<- "\n\n \n \n \n \n 1\n \n 1\n \n [FILTERED]\n 09\n 2015\n [FILTERED]\n Longbob Longsen\n \n \n nmi.api\n [FILTERED]\n \n \n\n]]>\n \n \n \n\n"
--> "HTTP/1.1 200 OK\r\n"
--> "Server: Microsoft-IIS/6.0\r\n"
--> "X-Robots-Tag: noindex\r\n"
--> "X-Powered-By: ASP.NET\r\n"
--> "Cache-Control: private, max-age=0\r\n"
--> "Content-Type: text/xml; charset=utf-8\r\n"
--> "Content-Length: 767\r\n"
--> "Date: Fri, 19 Dec 2014 19:55:13 GMT\r\n"
--> "Connection: close\r\n"
--> "\r\n"
-reading 767 bytes...
--> "<Response>\r\n\t<ResponseCode>1</ResponseCode>\r\n\t<Timestamp>20-Dec-2014 06:55:17</Timestamp>\r\n\t<Receipt></Receipt>\r\n\t<SettlementDate></SettlementDate>\r\n\t<DeclinedCode>183</DeclinedCode>\r\n\t<DeclinedMessage>Exception parsing transaction XML</DeclinedMessage>\r\n</Response>\r\n"
-read 767 bytes
-Conn close
+ <<~'POST_SCRUBBED'
+ opening connection to demo.ippayments.com.au:443...
+ opened
+ starting SSL for demo.ippayments.com.au:443...
+ SSL established
+ <- "POST /interface/api/dts.asmx HTTP/1.1\r\nContent-Type: text/xml; charset=utf-8\r\nSoapaction: http://www.ippayments.com.au/interface/api/dts/SubmitSinglePayment\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: demo.ippayments.com.au\r\nContent-Length: 822\r\n\r\n"
+ <- "\n\n \n \n \n \n 1\n \n 1\n \n [FILTERED]\n 09\n 2015\n [FILTERED]\n Longbob Longsen\n \n \n nmi.api\n [FILTERED]\n \n \n\n]]>\n \n \n \n\n"
+ -> "HTTP/1.1 200 OK\r\n"
+ -> "Server: Microsoft-IIS/6.0\r\n"
+ -> "X-Robots-Tag: noindex\r\n"
+ -> "X-Powered-By: ASP.NET\r\n"
+ -> "Cache-Control: private, max-age=0\r\n"
+ -> "Content-Type: text/xml; charset=utf-8\r\n"
+ -> "Content-Length: 767\r\n"
+ -> "Date: Fri, 19 Dec 2014 19:55:13 GMT\r\n"
+ -> "Connection: close\r\n"
+ -> "\r\n"
+ reading 767 bytes...
+ -> "<Response>\r\n\t<ResponseCode>1</ResponseCode>\r\n\t<Timestamp>20-Dec-2014 06:55:17</Timestamp>\r\n\t<Receipt></Receipt>\r\n\t<SettlementDate></SettlementDate>\r\n\t<DeclinedCode>183</DeclinedCode>\r\n\t<DeclinedMessage>Exception parsing transaction XML</DeclinedMessage>\r\n</Response>\r\n"
+ read 767 bytes
+ Conn close
POST_SCRUBBED
end
def successful_purchase_response
- <<-XML
-<Response>
- <ResponseCode>0</ResponseCode>
- <Timestamp>20-Dec-2014 04:07:39</Timestamp>
- <Receipt>89435577</Receipt>
- <SettlementDate>22-Dec-2014</SettlementDate>
- <DeclinedCode></DeclinedCode>
- <DeclinedMessage></DeclinedMessage>
-</Response>
-
+ <<~XML
+ <Response>
+ <ResponseCode>0</ResponseCode>
+ <Timestamp>20-Dec-2014 04:07:39</Timestamp>
+ <Receipt>89435577</Receipt>
+ <SettlementDate>22-Dec-2014</SettlementDate>
+ <DeclinedCode></DeclinedCode>
+ <DeclinedMessage></DeclinedMessage>
+ </Response>
+
XML
end
def failed_purchase_response
- <<-XML
-<Response>
- <ResponseCode>1</ResponseCode>
- <Timestamp>20-Dec-2014 04:14:56</Timestamp>
- <Receipt></Receipt>
- <SettlementDate>22-Dec-2014</SettlementDate>
- <DeclinedCode>05</DeclinedCode>
- <DeclinedMessage>Do Not Honour</DeclinedMessage>
-</Response>
-
+ <<~XML
+ <Response>
+ <ResponseCode>1</ResponseCode>
+ <Timestamp>20-Dec-2014 04:14:56</Timestamp>
+ <Receipt></Receipt>
+ <SettlementDate>22-Dec-2014</SettlementDate>
+ <DeclinedCode>05</DeclinedCode>
+ <DeclinedMessage>Do Not Honour</DeclinedMessage>
+ </Response>
+
XML
end
def successful_authorize_response
- <<-XML
-<Response>
- <ResponseCode>0</ResponseCode>
- <Timestamp>20-Dec-2014 04:18:13</Timestamp>
- <Receipt>89435583</Receipt>
- <SettlementDate>22-Dec-2014</SettlementDate>
- <DeclinedCode></DeclinedCode>
- <DeclinedMessage></DeclinedMessage>
-</Response>
-
+ <<~XML
+ <Response>
+ <ResponseCode>0</ResponseCode>
+ <Timestamp>20-Dec-2014 04:18:13</Timestamp>
+ <Receipt>89435583</Receipt>
+ <SettlementDate>22-Dec-2014</SettlementDate>
+ <DeclinedCode></DeclinedCode>
+ <DeclinedMessage></DeclinedMessage>
+ </Response>
+
XML
end
def successful_capture_response
- <<-XML
-<Response>
- <ResponseCode>0</ResponseCode>
- <Timestamp>20-Dec-2014 04:18:15</Timestamp>
- <Receipt>89435584</Receipt>
- <SettlementDate>22-Dec-2014</SettlementDate>
- <DeclinedCode></DeclinedCode>
- <DeclinedMessage></DeclinedMessage>
-</Response>
-
+ <<~XML
+ <Response>
+ <ResponseCode>0</ResponseCode>
+ <Timestamp>20-Dec-2014 04:18:15</Timestamp>
+ <Receipt>89435584</Receipt>
+ <SettlementDate>22-Dec-2014</SettlementDate>
+ <DeclinedCode></DeclinedCode>
+ <DeclinedMessage></DeclinedMessage>
+ </Response>
+
XML
end
def successful_refund_response
- <<-XML
-<Response>
- <ResponseCode>0</ResponseCode>
- <Timestamp>20-Dec-2014 04:24:51</Timestamp>
- <Receipt>89435596</Receipt>
- <SettlementDate>22-Dec-2014</SettlementDate>
- <DeclinedCode></DeclinedCode>
- <DeclinedMessage></DeclinedMessage>
-</Response>
-
+ <<~XML
+ <Response>
+ <ResponseCode>0</ResponseCode>
+ <Timestamp>20-Dec-2014 04:24:51</Timestamp>
+ <Receipt>89435596</Receipt>
+ <SettlementDate>22-Dec-2014</SettlementDate>
+ <DeclinedCode></DeclinedCode>
+ <DeclinedMessage></DeclinedMessage>
+ </Response>
+
XML
end
def successful_void_response
- <<-XML
-<Response>
- <ResponseCode>0</ResponseCode>
- <DeclinedCode></DeclinedCode>
- <DeclinedMessage></DeclinedMessage>
- </Response>
-
+ <<~XML
+ <Response>
+ <ResponseCode>0</ResponseCode>
+ <DeclinedCode></DeclinedCode>
+ <DeclinedMessage></DeclinedMessage>
+ </Response>
+
XML
end
end
diff --git a/test/unit/gateways/banwire_test.rb b/test/unit/gateways/banwire_test.rb
index faa341c1f97..5bbc177913a 100644
--- a/test/unit/gateways/banwire_test.rb
+++ b/test/unit/gateways/banwire_test.rb
@@ -5,32 +5,37 @@ class BanwireTest < Test::Unit::TestCase
def setup
@gateway = BanwireGateway.new(
- :login => 'desarrollo',
- :currency => 'MXN')
-
- @credit_card = credit_card('5204164299999999',
- :month => 11,
- :year => 2012,
- :verification_value => '999')
+ login: 'desarrollo',
+ currency: 'MXN'
+ )
+
+ @credit_card = credit_card(
+ '5204164299999999',
+ month: 11,
+ year: 2012,
+ verification_value: '999'
+ )
@amount = 100
@options = {
- :order_id => '1',
- :email => 'test@email.com',
- :billing_address => address,
- :description => 'Store purchase'
+ order_id: '1',
+ email: 'test@email.com',
+ billing_address: address,
+ description: 'Store purchase'
}
- @amex_credit_card = credit_card('375932134599999',
- :month => 3,
- :year => 2017,
- :first_name => 'Banwire',
- :last_name => 'Test Card')
+ @amex_credit_card = credit_card(
+ '375932134599999',
+ month: 3,
+ year: 2017,
+ first_name: 'Banwire',
+ last_name: 'Test Card'
+ )
@amex_options = {
- :order_id => '2',
- :email => 'test@email.com',
- :billing_address => address(:address1 => 'Horacio', :zip => 11560),
- :description => 'Store purchase amex'
+ order_id: '2',
+ email: 'test@email.com',
+ billing_address: address(address1: 'Horacio', zip: 11560),
+ description: 'Store purchase amex'
}
end
@@ -65,7 +70,7 @@ def test_invalid_json
def test_successful_amex_purchase
response = stub_comms do
@gateway.purchase(@amount, @amex_credit_card, @amex_options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/post_code=11560/, data)
end.respond_with(successful_purchase_amex_response)
diff --git a/test/unit/gateways/barclaycard_smartpay_test.rb b/test/unit/gateways/barclaycard_smartpay_test.rb
index 2bb8443b85d..ee0c11c4da3 100644
--- a/test/unit/gateways/barclaycard_smartpay_test.rb
+++ b/test/unit/gateways/barclaycard_smartpay_test.rb
@@ -46,37 +46,38 @@ def setup
}
@options_with_shipping_house_number_and_shipping_street = {
- order_id: '1',
- street: 'Top Level Drive',
- house_number: '1000',
- billing_address: address,
- shipping_house_number: '999',
- shipping_street: 'Downtown Loop',
- shipping_address: {
- name: 'PU JOI SO',
- address1: '新北市店溪路3579號139樓',
- company: 'Widgets Inc',
- city: '新北市',
- zip: '231509',
- country: 'TW',
- phone: '(555)555-5555',
- fax: '(555)555-6666'
- },
- description: 'Store Purchase'
+ order_id: '1',
+ street: 'Top Level Drive',
+ house_number: '1000',
+ billing_address: address,
+ shipping_house_number: '999',
+ shipping_street: 'Downtown Loop',
+ shipping_address: {
+ name: 'PU JOI SO',
+ address1: '新北市店溪路3579號139樓',
+ company: 'Widgets Inc',
+ city: '新北市',
+ zip: '231509',
+ country: 'TW',
+ phone: '(555)555-5555',
+ fax: '(555)555-6666'
+ },
+ description: 'Store Purchase'
}
@options_with_credit_fields = {
order_id: '1',
- billing_address: {
- name: 'Jim Smith',
- address1: '100 Street',
- company: 'Widgets Inc',
- city: 'Ottawa',
- state: 'ON',
- zip: 'K1C2N6',
- country: 'CA',
- phone: '(555)555-5555',
- fax: '(555)555-6666'},
+ billing_address: {
+ name: 'Jim Smith',
+ address1: '100 Street',
+ company: 'Widgets Inc',
+ city: 'Ottawa',
+ state: 'ON',
+ zip: 'K1C2N6',
+ country: 'CA',
+ phone: '(555)555-5555',
+ fax: '(555)555-6666'
+ },
email: 'long@bob.com',
customer: 'Longbob Longsen',
description: 'Store Purchase',
@@ -92,14 +93,38 @@ def setup
@avs_address = @options.clone
@avs_address.update(billing_address: {
- name: 'Jim Smith',
- street: 'Test AVS result',
- houseNumberOrName: '2',
- city: 'Cupertino',
- state: 'CA',
- zip: '95014',
- country: 'US'
- })
+ name: 'Jim Smith',
+ street: 'Test AVS result',
+ houseNumberOrName: '2',
+ city: 'Cupertino',
+ state: 'CA',
+ zip: '95014',
+ country: 'US'
+ })
+
+ @normalized_3ds_2_options = {
+ reference: '345123',
+ shopper_email: 'john.smith@test.com',
+ shopper_ip: '77.110.174.153',
+ shopper_reference: 'John Smith',
+ billing_address: address(),
+ order_id: '123',
+ stored_credential: { reason_type: 'unscheduled' },
+ three_ds_2: {
+ channel: 'browser',
+ browser_info: {
+ accept_header: 'unknown',
+ depth: 100,
+ java: false,
+ language: 'US',
+ height: 1000,
+ width: 500,
+ timezone: '-120',
+ user_agent: 'unknown'
+ },
+ notification_url: 'https://example.com/notification'
+ }
+ }
end
def test_successful_purchase
@@ -115,7 +140,7 @@ def test_successful_purchase
def test_successful_authorize_with_alternate_address
response = stub_comms do
@gateway.authorize(@amount, @credit_card, @options_with_alternate_address)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/billingAddress.houseNumberOrName=%E6%96%B0%E5%8C%97%E5%B8%82%E5%BA%97%E6%BA%AA%E8%B7%AF3579%E8%99%9F139%E6%A8%93/, data)
assert_match(/billingAddress.street=Not\+Provided/, data)
end.respond_with(successful_authorize_response)
@@ -127,10 +152,8 @@ def test_successful_authorize_with_alternate_address
def test_successful_authorize_with_house_number_and_street
response = stub_comms do
- @gateway.authorize(@amount,
- @credit_card,
- @options_with_house_number_and_street)
- end.check_request do |endpoint, data, headers|
+ @gateway.authorize(@amount, @credit_card, @options_with_house_number_and_street)
+ end.check_request do |_endpoint, data, _headers|
assert_match(/billingAddress.street=Top\+Level\+Drive/, data)
assert_match(/billingAddress.houseNumberOrName=1000/, data)
end.respond_with(successful_authorize_response)
@@ -142,10 +165,8 @@ def test_successful_authorize_with_house_number_and_street
def test_successful_authorize_with_shipping_house_number_and_street
response = stub_comms do
- @gateway.authorize(@amount,
- @credit_card,
- @options_with_shipping_house_number_and_shipping_street)
- end.check_request do |endpoint, data, headers|
+ @gateway.authorize(@amount, @credit_card, @options_with_shipping_house_number_and_shipping_street)
+ end.check_request do |_endpoint, data, _headers|
assert_match(/billingAddress.street=Top\+Level\+Drive/, data)
assert_match(/billingAddress.houseNumberOrName=1000/, data)
assert_match(/deliveryAddress.street=Downtown\+Loop/, data)
@@ -158,11 +179,24 @@ def test_successful_authorize_with_shipping_house_number_and_street
end
def test_successful_authorize_with_extra_options
+ shopper_interaction = 'ContAuth'
+ shopper_statement = 'One-year premium subscription'
+ device_fingerprint = 'abcde123'
+
response = stub_comms do
- @gateway.authorize(@amount, @credit_card, @options.merge(shopper_interaction: 'ContAuth', device_fingerprint: 'abcde123'))
- end.check_request do |endpoint, data, headers|
- assert_match(/shopperInteraction=ContAuth/, data)
- assert_match(/deviceFingerprint=abcde123/, data)
+ @gateway.authorize(
+ @amount,
+ @credit_card,
+ @options.merge(
+ shopper_interaction: shopper_interaction,
+ device_fingerprint: device_fingerprint,
+ shopper_statement: shopper_statement
+ )
+ )
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/shopperInteraction=#{shopper_interaction}/, data)
+ assert_match(/shopperStatement=#{Regexp.quote(CGI.escape(shopper_statement))}/, data)
+ assert_match(/deviceFingerprint=#{device_fingerprint}/, data)
end.respond_with(successful_authorize_response)
assert_success response
@@ -189,6 +223,18 @@ def test_successful_authorize_with_3ds
assert response.test?
end
+ def test_successful_authorize_with_3ds2_browser_client_data
+ @gateway.stubs(:ssl_post).returns(successful_authorize_with_3ds2_response)
+
+ assert response = @gateway.authorize(@amount, @three_ds_enrolled_card, @normalized_3ds_2_options)
+ assert response.test?
+ assert_equal '8815609737078177', response.authorization
+ assert_equal response.params['resultCode'], 'IdentifyShopper'
+ refute response.params['additionalData']['threeds2.threeDS2Token'].blank?
+ refute response.params['additionalData']['threeds2.threeDSServerTransID'].blank?
+ refute response.params['additionalData']['threeds2.threeDSMethodURL'].blank?
+ end
+
def test_failed_authorize
@gateway.stubs(:ssl_post).returns(failed_authorize_response)
@@ -207,7 +253,7 @@ def test_successful_capture
end
def test_failed_capture
- @gateway.stubs(:ssl_post).raises(ActiveMerchant::ResponseError.new(stub(:code => '422', :body => failed_capture_response)))
+ @gateway.stubs(:ssl_post).raises(ActiveMerchant::ResponseError.new(stub(code: '422', body: failed_capture_response)))
response = @gateway.capture(@amount, '0000000000000000', @options)
assert_failure response
@@ -218,7 +264,7 @@ def test_failed_capture
def test_legacy_capture_psp_reference_passed_for_refund
response = stub_comms do
@gateway.refund(@amount, '8814002632606717', @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/originalReference=8814002632606717/, data)
end.respond_with(successful_refund_response)
@@ -229,7 +275,7 @@ def test_legacy_capture_psp_reference_passed_for_refund
def test_successful_refund
response = stub_comms do
@gateway.refund(@amount, '7914002629995504#8814002632606717', @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/originalReference=7914002629995504&/, data)
assert_no_match(/8814002632606717/, data)
end.respond_with(successful_refund_response)
@@ -239,7 +285,7 @@ def test_successful_refund
end
def test_failed_refund
- @gateway.stubs(:ssl_post).raises(ActiveMerchant::ResponseError.new(stub(:code => '422', :body => failed_refund_response)))
+ @gateway.stubs(:ssl_post).raises(ActiveMerchant::ResponseError.new(stub(code: '422', body: failed_refund_response)))
response = @gateway.refund(@amount, '0000000000000000', @options)
assert_failure response
@@ -264,7 +310,7 @@ def test_failed_credit
def test_credit_contains_all_fields
response = stub_comms do
@gateway.credit(@amount, @credit_card, @options_with_credit_fields)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |endpoint, data, _headers|
assert_match(%r{/refundWithData}, endpoint)
assert_match(/dateOfBirth=1990-10-11&/, data)
assert_match(/entityType=NaturalPerson&/, data)
@@ -278,9 +324,9 @@ def test_credit_contains_all_fields
def test_successful_third_party_payout
response = stub_comms do
- @gateway.credit(@amount, @credit_card, @options_with_credit_fields.merge({third_party_payout: true}))
- end.check_request do |endpoint, data, headers|
- if /storeDetailAndSubmitThirdParty/ =~ endpoint
+ @gateway.credit(@amount, @credit_card, @options_with_credit_fields.merge({ third_party_payout: true }))
+ end.check_request do |endpoint, data, _headers|
+ if /storeDetailAndSubmitThirdParty/.match?(endpoint)
assert_match(%r{/storeDetailAndSubmitThirdParty}, endpoint)
assert_match(/dateOfBirth=1990-10-11&/, data)
assert_match(/entityType=NaturalPerson&/, data)
@@ -322,9 +368,9 @@ def test_unsuccessful_verify
def test_authorize_nonfractional_currency
response = stub_comms do
@gateway.authorize(@amount, @credit_card, @options.merge(currency: 'JPY'))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/amount.value=1/, data)
- assert_match(/amount.currency=JPY/, data)
+ assert_match(/amount.currency=JPY/, data)
end.respond_with(successful_authorize_response)
assert_success response
@@ -333,9 +379,9 @@ def test_authorize_nonfractional_currency
def test_authorize_three_decimal_currency
response = stub_comms do
@gateway.authorize(@amount, @credit_card, @options.merge(currency: 'OMR'))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/amount.value=100/, data)
- assert_match(/amount.currency=OMR/, data)
+ assert_match(/amount.currency=OMR/, data)
end.respond_with(successful_authorize_response)
assert_success response
@@ -349,13 +395,67 @@ def test_successful_store
end
def test_failed_store
- @gateway.stubs(:ssl_post).raises(ActiveMerchant::ResponseError.new(stub(:code => '422', :body => failed_store_response)))
+ @gateway.stubs(:ssl_post).raises(ActiveMerchant::ResponseError.new(stub(code: '422', body: failed_store_response)))
response = @gateway.store(@credit_card, @options)
assert_failure response
assert response.test?
end
+ def test_execute_threed_false_sent_3ds2
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @normalized_3ds_2_options.merge({ execute_threed: false }))
+ end.check_request do |_endpoint, data, _headers|
+ refute_match(/additionalData.scaExemption/, data)
+ assert_match(/additionalData.executeThreeD=false/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_sca_exemption_not_sent_if_execute_threed_missing_3ds2
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @normalized_3ds_2_options.merge({ scaExemption: 'lowValue' }))
+ end.check_request do |_endpoint, data, _headers|
+ refute_match(/additionalData.scaExemption/, data)
+ refute_match(/additionalData.executeThreeD=false/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_sca_exemption_and_execute_threed_false_sent_3ds2
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @normalized_3ds_2_options.merge({ sca_exemption: 'lowValue', execute_threed: false }))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/additionalData.scaExemption=lowValue/, data)
+ assert_match(/additionalData.executeThreeD=false/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_sca_exemption_and_execute_threed_true_sent_3ds2
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @normalized_3ds_2_options.merge({ sca_exemption: 'lowValue', execute_threed: true }))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/additionalData.scaExemption=lowValue/, data)
+ assert_match(/additionalData.executeThreeD=true/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_sca_exemption_not_sent_when_execute_threed_true_3ds1
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options.merge({ sca_exemption: 'lowValue', execute_threed: true }))
+ end.check_request do |_endpoint, data, _headers|
+ refute_match(/additionalData.scaExemption/, data)
+ assert_match(/additionalData.executeThreeD=true/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_sca_exemption_not_sent_when_execute_threed_false_3ds1
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options.merge({ sca_exemption: 'lowValue', execute_threed: false }))
+ end.check_request do |_endpoint, data, _headers|
+ refute_match(/additionalData.scaExemption/, data)
+ refute_match(/additionalData.executeThreeD/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
def test_avs_result
@gateway.expects(:ssl_post).returns(failed_avs_response)
@@ -395,6 +495,10 @@ def successful_authorize_with_3ds_response
'pspReference=8815161318854998&resultCode=RedirectShopper&issuerUrl=https%3A%2F%2Ftest.adyen.com%2Fhpp%2F3d%2Fvalidate.shtml&md=WIFa2sF3CuPyN53Txjt3U%2F%2BDuCsddzywiY5NLgEAdUAXPksHUzXL5E%2BsfvdpolkGWR8b1oh%2FNA3jNaUP9UCgfjhXqRslGFy9OGqcZ1ITMz54HHm%2FlsCKN9bTftKnYA4F7GqvOgcIIrinUZjbMvW9doGifwzSqYLo6ASOm6bARL5n7cIFV8IWtA2yPlO%2FztKSTRJt1glN4s8sMcpE57z4soWKMuycbdXdpp6d4ZRSa%2F1TPF0MnJF0zNaSAAkw9JpXqGMOz5sFF2Smpc38HXJzM%2FV%2B1mmoDhhWmXXOb5YQ0QSCS7DXKIcr8ZtuGuGmFp0QOfZiO41%2B2I2N7VhONVx8xSn%2BLu4m6vaDIg5qsnd9saxaWwbJpl9okKm6pB2MJap9ScuBCcvI496BPCrjQ2LHxvDWhk6M3Exemtv942NQIGlsiPaW0KXoC2dQvBsxWh0K&paRequest=eNpVUtuOgjAQ%2FRXj%2B1KKoIWMTVgxWR%2B8RNkPaMpEycrFUlb8%2B20B190%2BnXPm0pnTQnpRiMkJZauQwxabRpxxkmfLacQYDeiczihjgR%2BGbMrhEB%2FxxuEbVZNXJaeO63hAntSUK3kRpeYg5O19s%2BPUm%2FnBHMhIoUC1SXiKjT4URSxvba5QARlkKEWB%2FFSbgbLr41QIpXFVFUB6HWTVllo9OPNMwyeBVl35Reu6iQi53%2B9OM5Y7sipMVqmF1G9tA8QmAnlNeGgtakzjLs%2F4Pjl3u3TtbdNtZzDdJV%2FBPu7PEojNgExo5J5LmUvpfELDyPcjPwDS6yAKOxFffx4nxhXXrDwIUNt74oFQG%2FgrgLFdYSkfPFwws9WTAXZ1VaLJMPb%2BYiCvoVcf1mSpjW%2B%2BN9i8YKFr0MLa3Qdsl9yYREM37NtYAsSWkvElyfjiBv37CT9ySbE1'
end
+ def successful_authorize_with_3ds2_response
+ 'additionalData.threeds2.threeDS2Token=BQABAQB9sBAzFS%2BrvT1fuY78N4P5BA5DO6s9Y6jCIzvMcH%2Bk5%2B0ms8dRPEZZhO8CYx%2Fa5NCl8r4vyJj0nI0HZ9CBl%2FQLxtGLYfVu6sNxZc9xZry%2Bm24pBGTtHsd4vunorPNPAGlYWHBXtf4h0Sj9Qy0bzlau7a%2Feayi1cpjbfV%2B8Eqw%2FAod1B80heU8sX2DKm5SHlR4o0qTu0WQUSJfKRxjdJ1AntgAxjYo3uFUlU%2FyhNpdRiAxgauLImbllfQTGVTcYBQXsY9FSakfAZRW1kT7bNMraCvRUpp4o1Z5ZezJxPcksfCEzFVPyJYcTvcV4odQK4tT6imRLRvG1OgUVNzNAuDBnEJtFOC%2BE5YwAwfKuloCqB9oAAOzL5ZHXOXPASY2ehJ3RaCZjqj5vmAX8L9GY35FV8q49skYZpzIvlMICWjErI2ayKMCiXHFDE54f2GJEhVRKpY9s506740UGQc0%2FMgbKyLyqtU%2BRG30BwA9bSt3NQKchm9xoOL7U%2Bzm6OIeikmw94TBq%2BmBN7SdQi%2BK2W4yfMkqFsl7hc7HHBa%2BOc6At7wxxdxCLg6wksQmDxElXeQfFkWvoBuR96fIHaXILnVHKjWcTbeulXBhVPA5Y47MLEtZL3G8k%2BzKTFUCW7O0MN2WxUoMBT8foan1%2B9QhZejEqiamreIs56PLQkJvhigyRQmiqwnVjXiFOv%2FEcWn0Z6IM2TnAfw3Kd2KwZ9JaePLtZ2Ck7%2FUEsdt1Kj2HYeE86WM4PESystER5oBT12xWXvbp8CEA7Mulmpd3bkiMl5IVRoSBL5pl4qZd1CrnG%2FeuvtXYTsN%2FdA%2BIcWwiLiXpmSwqaRB8DfChwouuNMAAkfKhQ6b3vLAToc3o%2B3Xa1QetsK8GI1pmjkoZRvLd2xfGhVe%2FmCl23wzQsAicwB9ZXXMgWbaS2OwdwsISQGOmsWrajzp7%2FvR0T4aHqJlrFvKnc9BrWEWbDi8g%2BDFZ2E2ifhFYSYhrHVA7yOIIDdTQnH3CIzaevxUAnbIyFsxrhy8USdP6R6CdJZ%2Bg0rIJ5%2FeZ5P8JjDiYJWi5FDJwy%2BNP9PQIFFim6psbELCtnAaW1m7pU1FeNwjYUGIdVD2f%2BVYJe4cWHPCaWAAsARNXTzjrfUEq%2BpEYDcs%2FLyTB8f69qSrmTSDGsCETsNNy27LY%2BtodGDKsxtW35jIqoV8l2Dra3wucman8nIZp3VTNtNvZDCqWetLXxBbFVZN6ecuoMPwhER5MBFUrkkXCSSFBK%2FNGp%2FXaEDP6A2hmUKvXikL3F9S7MIKQCUYC%2FI7K4DFYFBjTBzN4%3D&additionalData.threeds2.threeDSServerTransID=efbf9d05-5e6b-4659-a64e-f1dfa5d846c4&additionalData.threeds2.threeDSMethodURL=https%3A%2F%2Fpal-test.adyen.com%2Fthreeds2simulator%2Facs%2FstartMethod.shtml&pspReference=8815609737078177&resultCode=IdentifyShopper'
+ end
+
def failed_authorize_response
'pspReference=7914002630895750&refusalReason=Refused&resultCode=Refused'
end
@@ -544,5 +648,4 @@ def scrubbed_transcript
Conn close
)
end
-
end
diff --git a/test/unit/gateways/barclays_epdq_extra_plus_test.rb b/test/unit/gateways/barclays_epdq_extra_plus_test.rb
index 330bdf13d4d..194173a69c9 100644
--- a/test/unit/gateways/barclays_epdq_extra_plus_test.rb
+++ b/test/unit/gateways/barclays_epdq_extra_plus_test.rb
@@ -2,21 +2,21 @@
class BarclaysEpdqExtraPlusTest < Test::Unit::TestCase
def setup
- @credentials = { :login => 'pspid',
- :user => 'username',
- :password => 'password',
- :signature => 'mynicesig',
- :signature_encryptor => 'sha512' }
+ @credentials = { login: 'pspid',
+ user: 'username',
+ password: 'password',
+ signature: 'mynicesig',
+ signature_encryptor: 'sha512' }
@gateway = BarclaysEpdqExtraPlusGateway.new(@credentials)
@credit_card = credit_card
- @mastercard = credit_card('5399999999999999', :brand => 'mastercard')
+ @mastercard = credit_card('5399999999999999', brand: 'mastercard')
@amount = 100
@identification = '3014726'
@billing_id = 'myalias'
@options = {
- :order_id => '1',
- :billing_address => address,
- :description => 'Store Purchase'
+ order_id: '1',
+ billing_address: address,
+ description: 'Store Purchase'
}
@parameters = {
'orderID' => '1',
@@ -54,7 +54,7 @@ def test_successful_purchase_with_action_param
@gateway.expects(:add_pair).at_least(1)
@gateway.expects(:add_pair).with(anything, 'ECI', '7')
@gateway.expects(:ssl_post).returns(successful_purchase_response)
- assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:action => 'SAS'))
+ assert response = @gateway.purchase(@amount, @credit_card, @options.merge(action: 'SAS'))
assert_success response
assert_equal '3014726;SAS', response.authorization
assert response.params['HTML_ANSWER'].nil?
@@ -74,7 +74,7 @@ def test_successful_purchase_with_custom_eci
@gateway.expects(:add_pair).at_least(1)
@gateway.expects(:add_pair).with(anything, 'ECI', '4')
@gateway.expects(:ssl_post).returns(successful_purchase_response)
- assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:eci => 4))
+ assert response = @gateway.purchase(@amount, @credit_card, @options.merge(eci: 4))
assert_success response
assert_equal '3014726;SAL', response.authorization
assert response.test?
@@ -82,7 +82,7 @@ def test_successful_purchase_with_custom_eci
def test_successful_purchase_with_3dsecure
@gateway.expects(:ssl_post).returns(successful_3dsecure_purchase_response)
- assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:d3d => true))
+ assert response = @gateway.purchase(@amount, @credit_card, @options.merge(d3d: true))
assert_success response
assert_equal '3014726;SAL', response.authorization
assert response.params['HTML_ANSWER']
@@ -115,7 +115,7 @@ def test_successful_authorize_with_custom_eci
@gateway.expects(:add_pair).at_least(1)
@gateway.expects(:add_pair).with(anything, 'ECI', '4')
@gateway.expects(:ssl_post).returns(successful_purchase_response)
- assert response = @gateway.authorize(@amount, @credit_card, @options.merge(:eci => 4))
+ assert response = @gateway.authorize(@amount, @credit_card, @options.merge(eci: 4))
assert_success response
assert_equal '3014726;RES', response.authorization
assert response.test?
@@ -123,7 +123,7 @@ def test_successful_authorize_with_custom_eci
def test_successful_authorize_with_3dsecure
@gateway.expects(:ssl_post).returns(successful_3dsecure_purchase_response)
- assert response = @gateway.authorize(@amount, @credit_card, @options.merge(:d3d => true))
+ assert response = @gateway.authorize(@amount, @credit_card, @options.merge(d3d: true))
assert_success response
assert_equal '3014726;RES', response.authorization
assert response.params['HTML_ANSWER']
@@ -141,7 +141,7 @@ def test_successful_capture
def test_successful_capture_with_action_option
@gateway.expects(:ssl_post).returns(successful_capture_response)
- assert response = @gateway.capture(@amount, '3048326', :action => 'SAS')
+ assert response = @gateway.capture(@amount, '3048326', action: 'SAS')
assert_success response
assert_equal '3048326;SAS', response.authorization
assert response.test?
@@ -185,7 +185,7 @@ def test_successful_store
@gateway.expects(:add_pair).at_least(1)
@gateway.expects(:add_pair).with(anything, 'ECI', '7')
@gateway.expects(:ssl_post).times(2).returns(successful_purchase_response)
- assert response = @gateway.store(@credit_card, :billing_id => @billing_id)
+ assert response = @gateway.store(@credit_card, billing_id: @billing_id)
assert_success response
assert_equal '3014726;RES', response.authorization
assert_equal '2', response.billing_id
@@ -197,7 +197,7 @@ def test_deprecated_store_option
@gateway.expects(:add_pair).with(anything, 'ECI', '7')
@gateway.expects(:ssl_post).times(2).returns(successful_purchase_response)
assert_deprecation_warning(BarclaysEpdqExtraPlusGateway::OGONE_STORE_OPTION_DEPRECATION_MESSAGE) do
- assert response = @gateway.store(@credit_card, :store => @billing_id)
+ assert response = @gateway.store(@credit_card, store: @billing_id)
assert_success response
assert_equal '3014726;RES', response.authorization
assert response.test?
@@ -225,7 +225,7 @@ def test_supported_countries
end
def test_supported_card_types
- assert_equal [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro], BarclaysEpdqExtraPlusGateway.supported_cardtypes
+ assert_equal %i[visa master american_express diners_club discover jcb maestro], BarclaysEpdqExtraPlusGateway.supported_cardtypes
end
def test_default_currency
@@ -239,7 +239,7 @@ def test_default_currency
end
def test_custom_currency_at_gateway_level
- gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(:currency => 'USD'))
+ gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(currency: 'USD'))
gateway.expects(:add_pair).at_least(1)
gateway.expects(:add_pair).with(anything, 'currency', 'USD')
gateway.expects(:ssl_post).returns(successful_purchase_response)
@@ -247,11 +247,11 @@ def test_custom_currency_at_gateway_level
end
def test_local_custom_currency_overwrite_gateway_level
- gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(:currency => 'USD'))
+ gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(currency: 'USD'))
gateway.expects(:add_pair).at_least(1)
gateway.expects(:add_pair).with(anything, 'currency', 'EUR')
gateway.expects(:ssl_post).returns(successful_purchase_response)
- gateway.purchase(@amount, @credit_card, @options.merge(:currency => 'EUR'))
+ gateway.purchase(@amount, @credit_card, @options.merge(currency: 'EUR'))
end
def test_avs_result
@@ -310,13 +310,13 @@ def test_format_error_message_with_no_separator
end
def test_without_signature
- gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(:signature => nil, :signature_encryptor => nil))
+ gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(signature: nil, signature_encryptor: nil))
gateway.expects(:ssl_post).returns(successful_purchase_response)
assert_deprecation_warning(BarclaysEpdqExtraPlusGateway::OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE) do
gateway.purchase(@amount, @credit_card, @options)
end
- gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(:signature => nil, :signature_encryptor => 'none'))
+ gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(signature: nil, signature_encryptor: 'none'))
gateway.expects(:ssl_post).returns(successful_purchase_response)
assert_no_deprecation_warning do
gateway.purchase(@amount, @credit_card, @options)
@@ -324,27 +324,27 @@ def test_without_signature
end
def test_signature_for_accounts_created_before_10_may_20101
- gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(:signature_encryptor => nil))
+ gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(signature_encryptor: nil))
assert signature = gateway.send(:add_signature, @parameters)
assert_equal Digest::SHA1.hexdigest('1100EUR4111111111111111MrPSPIDRES2mynicesig').upcase, signature
end
def test_signature_for_accounts_with_signature_encryptor_to_sha1
- gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(:signature_encryptor => 'sha1'))
+ gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(signature_encryptor: 'sha1'))
assert signature = gateway.send(:add_signature, @parameters)
assert_equal Digest::SHA1.hexdigest(string_to_digest).upcase, signature
end
def test_signature_for_accounts_with_signature_encryptor_to_sha256
- gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(:signature_encryptor => 'sha256'))
+ gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(signature_encryptor: 'sha256'))
assert signature = gateway.send(:add_signature, @parameters)
assert_equal Digest::SHA256.hexdigest(string_to_digest).upcase, signature
end
def test_signature_for_accounts_with_signature_encryptor_to_sha512
- gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(:signature_encryptor => 'sha512'))
+ gateway = BarclaysEpdqExtraPlusGateway.new(@credentials.merge(signature_encryptor: 'sha512'))
assert signature = gateway.send(:add_signature, @parameters)
assert_equal Digest::SHA512.hexdigest(string_to_digest).upcase, signature
end
@@ -359,13 +359,13 @@ def test_3dsecure_win_3ds_option
post = {}
gateway = BarclaysEpdqExtraPlusGateway.new(@credentials)
- gateway.send(:add_d3d, post, { :win_3ds => :pop_up })
+ gateway.send(:add_d3d, post, { win_3ds: :pop_up })
assert 'POPUP', post['WIN3DS']
- gateway.send(:add_d3d, post, { :win_3ds => :pop_ix })
+ gateway.send(:add_d3d, post, { win_3ds: :pop_ix })
assert 'POPIX', post['WIN3DS']
- gateway.send(:add_d3d, post, { :win_3ds => :invalid })
+ gateway.send(:add_d3d, post, { win_3ds: :invalid })
assert 'MAINW', post['WIN3DS']
end
@@ -374,14 +374,14 @@ def test_3dsecure_additional_options
gateway = BarclaysEpdqExtraPlusGateway.new(@credentials)
gateway.send(:add_d3d, post, {
- :http_accept => 'text/html',
- :http_user_agent => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)',
- :accept_url => 'https://accept_url',
- :decline_url => 'https://decline_url',
- :exception_url => 'https://exception_url',
- :paramsplus => 'params_plus',
- :complus => 'com_plus',
- :language => 'fr_FR'
+ http_accept: 'text/html',
+ http_user_agent: 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)',
+ accept_url: 'https://accept_url',
+ decline_url: 'https://decline_url',
+ exception_url: 'https://exception_url',
+ paramsplus: 'params_plus',
+ complus: 'com_plus',
+ language: 'fr_FR'
})
assert 'HTTP_ACCEPT', 'text/html'
assert 'HTTP_USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)'
@@ -427,7 +427,7 @@ def d3d_string_to_digest
end
def successful_authorize_response
- <<-END
+ <<-XML
- END
+ XML
end
def successful_purchase_response
- <<-END
+ <<-XML
- END
+ XML
end
def successful_3dsecure_purchase_response
- <<-END
+ <<-XML
- END
+ XML
end
def failed_purchase_response
- <<-END
+ <<-XML
- END
+ XML
end
def successful_capture_response
- <<-END
+ <<-XML
- END
+ XML
end
def successful_void_response
- <<-END
+ <<-XML
- END
+ XML
end
def successful_referenced_credit_response
- <<-END
+ <<-XML
- END
+ XML
end
def successful_unreferenced_credit_response
- <<-END
+ <<-XML
- END
+ XML
end
def test_failed_authorization_due_to_unknown_order_number
- <<-END
+ <<-XML
- END
+ XML
end
def transcript
diff --git a/test/unit/gateways/be2bill_test.rb b/test/unit/gateways/be2bill_test.rb
index d83f42e42b5..e4ca81f6381 100644
--- a/test/unit/gateways/be2bill_test.rb
+++ b/test/unit/gateways/be2bill_test.rb
@@ -3,17 +3,17 @@
class Be2billTest < Test::Unit::TestCase
def setup
@gateway = Be2billGateway.new(
- :login => 'login',
- :password => 'password'
- )
+ login: 'login',
+ password: 'password'
+ )
@credit_card = credit_card
@amount = 100
@options = {
- :order_id => '1',
- :billing_address => address,
- :description => 'Store Purchase'
+ order_id: '1',
+ billing_address: address,
+ description: 'Store Purchase'
}
end
@@ -41,11 +41,11 @@ def test_unsuccessful_request
# Place raw successful response from gateway here
def successful_purchase_response
- {'OPERATIONTYPE'=>'payment', 'TRANSACTIONID'=>'A189063', 'EXECCODE'=>'0000', 'MESSAGE'=>'The transaction has been accepted.', 'ALIAS'=>'A189063', 'DESCRIPTOR'=>'RENTABILITEST'}.to_json
+ { 'OPERATIONTYPE' => 'payment', 'TRANSACTIONID' => 'A189063', 'EXECCODE' => '0000', 'MESSAGE' => 'The transaction has been accepted.', 'ALIAS' => 'A189063', 'DESCRIPTOR' => 'RENTABILITEST' }.to_json
end
# Place raw failed response from gateway here
def failed_purchase_response
- {'OPERATIONTYPE'=>'payment', 'TRANSACTIONID'=>'A189063', 'EXECCODE'=>'1001', 'MESSAGE'=>"The parameter \"CARDCODE\" is missing.\n", 'DESCRIPTOR'=>'RENTABILITEST'}.to_json
+ { 'OPERATIONTYPE' => 'payment', 'TRANSACTIONID' => 'A189063', 'EXECCODE' => '1001', 'MESSAGE' => "The parameter \"CARDCODE\" is missing.\n", 'DESCRIPTOR' => 'RENTABILITEST' }.to_json
end
end
diff --git a/test/unit/gateways/beanstream_interac_test.rb b/test/unit/gateways/beanstream_interac_test.rb
index a0a7bac3862..71f7d3f9dda 100644
--- a/test/unit/gateways/beanstream_interac_test.rb
+++ b/test/unit/gateways/beanstream_interac_test.rb
@@ -3,16 +3,16 @@
class BeanstreamInteracTest < Test::Unit::TestCase
def setup
@gateway = BeanstreamInteracGateway.new(
- :login => 'login',
- :password => 'password'
- )
+ login: 'login',
+ password: 'password'
+ )
@amount = 100
@options = {
- :order_id => '1',
- :billing_address => address,
- :description => 'Store Purchase'
+ order_id: '1',
+ billing_address: address,
+ description: 'Store Purchase'
}
end
diff --git a/test/unit/gateways/beanstream_test.rb b/test/unit/gateways/beanstream_test.rb
index c07adf22c0e..fa9f748c9ff 100644
--- a/test/unit/gateways/beanstream_test.rb
+++ b/test/unit/gateways/beanstream_test.rb
@@ -7,11 +7,11 @@ def setup
Base.mode = :test
@gateway = BeanstreamGateway.new(
- :login => 'merchant id',
- :user => 'username',
- :password => 'password',
- :api_key => 'api_key'
- )
+ login: 'merchant id',
+ user: 'username',
+ password: 'password',
+ api_key: 'api_key'
+ )
@credit_card = credit_card
@@ -25,42 +25,43 @@ def setup
transaction_id: 'transaction ID'
)
- @check = check(
- :institution_number => '001',
- :transit_number => '26729'
- )
+ @check = check(
+ institution_number: '001',
+ transit_number: '26729'
+ )
@amount = 1000
@options = {
- :order_id => '1234',
- :billing_address => {
- :name => 'xiaobo zzz',
- :phone => '555-555-5555',
- :address1 => '1234 Levesque St.',
- :address2 => 'Apt B',
- :city => 'Montreal',
- :state => 'QC',
- :country => 'CA',
- :zip => 'H2C1X8'
+ order_id: '1234',
+ billing_address: {
+ name: 'xiaobo zzz',
+ phone: '555-555-5555',
+ address1: '1234 Levesque St.',
+ address2: 'Apt B',
+ city: 'Montreal',
+ state: 'QC',
+ country: 'CA',
+ zip: 'H2C1X8'
},
- :email => 'xiaobozzz@example.com',
- :subtotal => 800,
- :shipping => 100,
- :tax1 => 100,
- :tax2 => 100,
- :custom => 'reference one'
+ email: 'xiaobozzz@example.com',
+ subtotal: 800,
+ shipping: 100,
+ tax1: 100,
+ tax2: 100,
+ custom: 'reference one'
}
@recurring_options = @options.merge(
- :interval => { :unit => :months, :length => 1 },
- :occurrences => 5)
+ interval: { unit: :months, length: 1 },
+ occurrences: 5
+ )
end
def test_successful_purchase
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @decrypted_credit_card, @options)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
refute_match(/recurringPayment=true/, data)
end.respond_with(successful_purchase_response)
@@ -71,7 +72,7 @@ def test_successful_purchase
def test_successful_purchase_with_recurring
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @decrypted_credit_card, @options.merge(recurring: true))
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/recurringPayment=1/, data)
end.respond_with(successful_purchase_response)
@@ -81,7 +82,7 @@ def test_successful_purchase_with_recurring
def test_successful_authorize_with_recurring
response = stub_comms(@gateway, :ssl_request) do
@gateway.authorize(@amount, @decrypted_credit_card, @options.merge(recurring: true))
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/recurringPayment=1/, data)
end.respond_with(successful_purchase_response)
@@ -210,7 +211,7 @@ def test_successful_update_recurring
@gateway.expects(:ssl_post).returns(successful_update_recurring_response)
response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do
- @gateway.update_recurring(@amount, @credit_card, @recurring_options.merge(:account_id => response.params['rbAccountId']))
+ @gateway.update_recurring(@amount, @credit_card, @recurring_options.merge(account_id: response.params['rbAccountId']))
end
assert_success response
assert_equal 'Request successful', response.message
@@ -228,14 +229,14 @@ def test_successful_cancel_recurring
@gateway.expects(:ssl_post).returns(successful_cancel_recurring_response)
response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do
- @gateway.cancel_recurring(:account_id => response.params['rbAccountId'])
+ @gateway.cancel_recurring(account_id: response.params['rbAccountId'])
end
assert_success response
assert_equal 'Request successful', response.message
end
def test_ip_is_being_sent
- @gateway.expects(:ssl_post).with do |url, data|
+ @gateway.expects(:ssl_post).with do |_url, data|
data =~ /customerIp=123\.123\.123\.123/
end.returns(successful_purchase_response)
@@ -246,7 +247,7 @@ def test_ip_is_being_sent
def test_includes_network_tokenization_fields
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @decrypted_credit_card, @options)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/3DSecureXID/, data)
assert_match(/3DSecureECI/, data)
assert_match(/3DSecureCAVV/, data)
@@ -261,7 +262,7 @@ def test_defaults_state_and_zip_with_country
@options[:shipping_address] = address
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @decrypted_credit_card, @options)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/ordProvince=--/, data)
assert_match(/ordPostalCode=000000/, data)
assert_match(/shipProvince=--/, data)
@@ -272,12 +273,12 @@ def test_defaults_state_and_zip_with_country
end
def test_no_state_and_zip_default_with_missing_country
- address = { }
+ address = {}
@options[:billing_address] = address
@options[:shipping_address] = address
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @decrypted_credit_card, @options)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_no_match(/ordProvince=--/, data)
assert_no_match(/ordPostalCode=000000/, data)
assert_no_match(/shipProvince=--/, data)
@@ -293,7 +294,7 @@ def test_sends_email_without_addresses
@options[:shipping_email] = 'ship@mail.com'
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @decrypted_credit_card, @options)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/ordEmailAddress=xiaobozzz%40example.com/, data)
assert_match(/shipEmailAddress=ship%40mail.com/, data)
end.respond_with(successful_purchase_response)
@@ -301,6 +302,19 @@ def test_sends_email_without_addresses
assert_success response
end
+ def test_sends_alternate_phone_number_value
+ @options[:billing_address][:phone] = nil
+ @options[:billing_address][:phone_number] = '9191234567'
+
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(/ordPhoneNumber=9191234567/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
def test_transcript_scrubbing
assert_equal scrubbed_transcript, @gateway.scrub(transcript)
end
@@ -340,11 +354,11 @@ def unsuccessful_void_response
end
def brazilian_address_params_without_zip_and_state
- { :shipProvince => '--', :shipPostalCode => '000000', :ordProvince => '--', :ordPostalCode => '000000', :ordCountry => 'BR', :trnCardOwner => 'Longbob Longsen', :shipCity => 'Rio de Janeiro', :ordAddress1 => '1234 Levesque St.', :ordShippingPrice => '1.00', :deliveryEstimate => nil, :shipName => 'xiaobo zzz', :trnCardNumber => '4242424242424242', :trnAmount => '10.00', :trnType => 'P', :ordAddress2 => 'Apt B', :ordTax1Price => '1.00', :shipEmailAddress => 'xiaobozzz@example.com', :trnExpMonth => '09', :ordCity => 'Rio de Janeiro', :shipPhoneNumber => '555-555-5555', :ordName => 'xiaobo zzz', :trnExpYear => next_year, :trnOrderNumber => '1234', :shipCountry => 'BR', :ordTax2Price => '1.00', :shipAddress1 => '1234 Levesque St.', :ordEmailAddress => 'xiaobozzz@example.com', :trnCardCvd => '123', :trnComments => nil, :shippingMethod => nil, :ref1 => 'reference one', :shipAddress2 => 'Apt B', :ordPhoneNumber => '555-555-5555', :ordItemPrice => '8.00' }
+ { shipProvince: '--', shipPostalCode: '000000', ordProvince: '--', ordPostalCode: '000000', ordCountry: 'BR', trnCardOwner: 'Longbob Longsen', shipCity: 'Rio de Janeiro', ordAddress1: '1234 Levesque St.', ordShippingPrice: '1.00', deliveryEstimate: nil, shipName: 'xiaobo zzz', trnCardNumber: '4242424242424242', trnAmount: '10.00', trnType: 'P', ordAddress2: 'Apt B', ordTax1Price: '1.00', shipEmailAddress: 'xiaobozzz@example.com', trnExpMonth: '09', ordCity: 'Rio de Janeiro', shipPhoneNumber: '555-555-5555', ordName: 'xiaobo zzz', trnExpYear: next_year, trnOrderNumber: '1234', shipCountry: 'BR', ordTax2Price: '1.00', shipAddress1: '1234 Levesque St.', ordEmailAddress: 'xiaobozzz@example.com', trnCardCvd: '123', trnComments: nil, shippingMethod: nil, ref1: 'reference one', shipAddress2: 'Apt B', ordPhoneNumber: '555-555-5555', ordItemPrice: '8.00' }
end
def german_address_params_without_state
- { :shipProvince => '--', :shipPostalCode => '12345', :ordProvince => '--', :ordPostalCode => '12345', :ordCountry => 'DE', :trnCardOwner => 'Longbob Longsen', :shipCity => 'Berlin', :ordAddress1 => '1234 Levesque St.', :ordShippingPrice => '1.00', :deliveryEstimate => nil, :shipName => 'xiaobo zzz', :trnCardNumber => '4242424242424242', :trnAmount => '10.00', :trnType => 'P', :ordAddress2 => 'Apt B', :ordTax1Price => '1.00', :shipEmailAddress => 'xiaobozzz@example.com', :trnExpMonth => '09', :ordCity => 'Berlin', :shipPhoneNumber => '555-555-5555', :ordName => 'xiaobo zzz', :trnExpYear => next_year, :trnOrderNumber => '1234', :shipCountry => 'DE', :ordTax2Price => '1.00', :shipAddress1 => '1234 Levesque St.', :ordEmailAddress => 'xiaobozzz@example.com', :trnCardCvd => '123', :trnComments => nil, :shippingMethod => nil, :ref1 => 'reference one', :shipAddress2 => 'Apt B', :ordPhoneNumber => '555-555-5555', :ordItemPrice => '8.00' }
+ { shipProvince: '--', shipPostalCode: '12345', ordProvince: '--', ordPostalCode: '12345', ordCountry: 'DE', trnCardOwner: 'Longbob Longsen', shipCity: 'Berlin', ordAddress1: '1234 Levesque St.', ordShippingPrice: '1.00', deliveryEstimate: nil, shipName: 'xiaobo zzz', trnCardNumber: '4242424242424242', trnAmount: '10.00', trnType: 'P', ordAddress2: 'Apt B', ordTax1Price: '1.00', shipEmailAddress: 'xiaobozzz@example.com', trnExpMonth: '09', ordCity: 'Berlin', shipPhoneNumber: '555-555-5555', ordName: 'xiaobo zzz', trnExpYear: next_year, trnOrderNumber: '1234', shipCountry: 'DE', ordTax2Price: '1.00', shipAddress1: '1234 Levesque St.', ordEmailAddress: 'xiaobozzz@example.com', trnCardCvd: '123', trnComments: nil, shippingMethod: nil, ref1: 'reference one', shipAddress2: 'Apt B', ordPhoneNumber: '555-555-5555', ordItemPrice: '8.00' }
end
def next_year
@@ -370,5 +384,4 @@ def transcript
def scrubbed_transcript
'ref1=reference+one&trnCardOwner=Longbob+Longsen&trnCardNumber=[FILTERED]&trnExpMonth=09&trnExpYear=16&trnCardCvd=[FILTERED]&ordName=xiaobo+zzz&ordEmailAddress=xiaobozzz%40example.com&username=awesomesauce&password=[FILTERED]'
end
-
end
diff --git a/test/unit/gateways/blue_pay_test.rb b/test/unit/gateways/blue_pay_test.rb
index df8f4e62022..d1bc53db5c8 100644
--- a/test/unit/gateways/blue_pay_test.rb
+++ b/test/unit/gateways/blue_pay_test.rb
@@ -1,11 +1,11 @@
require 'test_helper'
RSP = {
- :approved_auth => 'AUTH_CODE=XCADZ&PAYMENT_ACCOUNT_MASK=xxxxxxxxxxxx4242&CARD_TYPE=VISA&TRANS_TYPE=AUTH&REBID=&STATUS=1&AVS=_&TRANS_ID=100134203758&CVV2=_&MESSAGE=Approved%20Auth',
- :approved_capture => 'AUTH_CODE=CHTHX&PAYMENT_ACCOUNT_MASK=xxxxxxxxxxxx4242&CARD_TYPE=VISA&TRANS_TYPE=CAPTURE&REBID=&STATUS=1&AVS=_&TRANS_ID=100134203760&CVV2=_&MESSAGE=Approved%20Capture',
- :approved_void => 'AUTH_CODE=KTMHB&PAYMENT_ACCOUNT_MASK=xxxxxxxxxxxx4242&CARD_TYPE=VISA&TRANS_TYPE=VOID&REBID=&STATUS=1&AVS=_&TRANS_ID=100134203763&CVV2=_&MESSAGE=Approved%20Void',
- :declined => 'TRANS_ID=100000000150&STATUS=0&AVS=0&CVV2=7&MESSAGE=Declined&REBID=',
- :approved_purchase => 'AUTH_CODE=GYRUY&PAYMENT_ACCOUNT_MASK=xxxxxxxxxxxx4242&CARD_TYPE=VISA&TRANS_TYPE=SALE&REBID=&STATUS=1&AVS=_&TRANS_ID=100134203767&CVV2=_&MESSAGE=Approved%20Sale'
+ approved_auth: 'AUTH_CODE=XCADZ&PAYMENT_ACCOUNT_MASK=xxxxxxxxxxxx4242&CARD_TYPE=VISA&TRANS_TYPE=AUTH&REBID=&STATUS=1&AVS=_&TRANS_ID=100134203758&CVV2=_&MESSAGE=Approved%20Auth',
+ approved_capture: 'AUTH_CODE=CHTHX&PAYMENT_ACCOUNT_MASK=xxxxxxxxxxxx4242&CARD_TYPE=VISA&TRANS_TYPE=CAPTURE&REBID=&STATUS=1&AVS=_&TRANS_ID=100134203760&CVV2=_&MESSAGE=Approved%20Capture',
+ approved_void: 'AUTH_CODE=KTMHB&PAYMENT_ACCOUNT_MASK=xxxxxxxxxxxx4242&CARD_TYPE=VISA&TRANS_TYPE=VOID&REBID=&STATUS=1&AVS=_&TRANS_ID=100134203763&CVV2=_&MESSAGE=Approved%20Void',
+ declined: 'TRANS_ID=100000000150&STATUS=0&AVS=0&CVV2=7&MESSAGE=Declined&REBID=',
+ approved_purchase: 'AUTH_CODE=GYRUY&PAYMENT_ACCOUNT_MASK=xxxxxxxxxxxx4242&CARD_TYPE=VISA&TRANS_TYPE=SALE&REBID=&STATUS=1&AVS=_&TRANS_ID=100134203767&CVV2=_&MESSAGE=Approved%20Sale'
}
class BluePayTest < Test::Unit::TestCase
@@ -13,20 +13,21 @@ class BluePayTest < Test::Unit::TestCase
def setup
@gateway = BluePayGateway.new(
- :login => 'X',
- :password => 'Y'
+ login: 'X',
+ password: 'Y'
)
@amount = 100
@credit_card = credit_card
+ @check = check
@rebill_id = '100096219669'
@rebill_status = 'active'
- @options = {ip: '192.168.0.1'}
+ @options = { ip: '192.168.0.1' }
end
def test_successful_authorization
response = stub_comms do
@gateway.authorize(@amount, @credit_card, @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/CUSTOMER_IP=192.168.0.1/, data)
end.respond_with(RSP[:approved_auth])
@@ -39,7 +40,7 @@ def test_successful_authorization
def test_successful_purchase
response = stub_comms do
@gateway.purchase(@amount, @credit_card, @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/CUSTOMER_IP=192.168.0.1/, data)
end.respond_with(RSP[:approved_purchase])
@@ -52,7 +53,7 @@ def test_successful_purchase
def test_failed_authorization
response = stub_comms do
@gateway.authorize(@amount, @credit_card, @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/CUSTOMER_IP=192.168.0.1/, data)
end.respond_with(RSP[:declined])
@@ -65,8 +66,8 @@ def test_failed_authorization
def test_add_address_outsite_north_america
result = {}
- @gateway.send(:add_address, result, :billing_address => {:address1 => '123 Test St.', :address2 => '5F', :city => 'Testville', :company => 'Test Company', :country => 'DE', :state => ''})
- assert_equal ['ADDR1', 'ADDR2', 'CITY', 'COMPANY_NAME', 'COUNTRY', 'PHONE', 'STATE', 'ZIP'], result.stringify_keys.keys.sort
+ @gateway.send(:add_address, result, billing_address: { address1: '123 Test St.', address2: '5F', city: 'Testville', company: 'Test Company', country: 'DE', state: '' })
+ assert_equal %w[ADDR1 ADDR2 CITY COMPANY_NAME COUNTRY PHONE STATE ZIP], result.stringify_keys.keys.sort
assert_equal 'n/a', result[:STATE]
assert_equal '123 Test St.', result[:ADDR1]
assert_equal 'DE', result[:COUNTRY]
@@ -75,9 +76,9 @@ def test_add_address_outsite_north_america
def test_add_address
result = {}
- @gateway.send(:add_address, result, :billing_address => {:address1 => '123 Test St.', :address2 => '5F', :city => 'Testville', :company => 'Test Company', :country => 'US', :state => 'AK'})
+ @gateway.send(:add_address, result, billing_address: { address1: '123 Test St.', address2: '5F', city: 'Testville', company: 'Test Company', country: 'US', state: 'AK' })
- assert_equal ['ADDR1', 'ADDR2', 'CITY', 'COMPANY_NAME', 'COUNTRY', 'PHONE', 'STATE', 'ZIP'], result.stringify_keys.keys.sort
+ assert_equal %w[ADDR1 ADDR2 CITY COMPANY_NAME COUNTRY PHONE STATE ZIP], result.stringify_keys.keys.sort
assert_equal 'AK', result[:STATE]
assert_equal '123 Test St.', result[:ADDR1]
assert_equal 'US', result[:COUNTRY]
@@ -87,7 +88,7 @@ def test_name_comes_from_payment_method
result = {}
@gateway.send(:add_creditcard, result, @credit_card)
- @gateway.send(:add_address, result, :billing_address => {:address1 => '123 Test St.', :address2 => '5F', :city => 'Testville', :company => 'Test Company', :country => 'US', :state => 'AK'})
+ @gateway.send(:add_address, result, billing_address: { address1: '123 Test St.', address2: '5F', city: 'Testville', company: 'Test Company', country: 'US', state: 'AK' })
assert_equal @credit_card.first_name, result[:NAME1]
assert_equal @credit_card.last_name, result[:NAME2]
@@ -95,19 +96,19 @@ def test_name_comes_from_payment_method
def test_add_invoice
result = {}
- @gateway.send(:add_invoice, result, :order_id => '#1001')
+ @gateway.send(:add_invoice, result, order_id: '#1001')
assert_equal '#1001', result[:invoice_num]
end
def test_add_description
result = {}
- @gateway.send(:add_invoice, result, :description => 'My Purchase is great')
+ @gateway.send(:add_invoice, result, description: 'My Purchase is great')
assert_equal 'My Purchase is great', result[:description]
end
def test_purchase_meets_minimum_requirements
params = {
- :amount => '1.01',
+ amount: '1.01'
}
@gateway.send(:add_creditcard, params, @credit_card)
@@ -120,8 +121,8 @@ def test_purchase_meets_minimum_requirements
def test_successful_refund
response = stub_comms do
- @gateway.refund(@amount, '100134230412', @options.merge({:card_number => @credit_card.number}))
- end.check_request do |endpoint, data, headers|
+ @gateway.refund(@amount, '100134230412', @options.merge({ card_number: @credit_card.number }))
+ end.check_request do |_endpoint, data, _headers|
assert_match(/CUSTOMER_IP=192\.168\.0\.1/, data)
end.respond_with(successful_refund_response)
@@ -132,12 +133,13 @@ def test_successful_refund
def test_refund_passing_extra_info
response = stub_comms do
- @gateway.refund(50, '123456789', @options.merge({:card_number => @credit_card.number, :first_name => 'Bob', :last_name => 'Smith', :zip => '12345'}))
- end.check_request do |endpoint, data, headers|
+ @gateway.refund(50, '123456789', @options.merge({ card_number: @credit_card.number, first_name: 'Bob', last_name: 'Smith', zip: '12345', doc_type: 'WEB' }))
+ end.check_request do |_endpoint, data, _headers|
assert_match(/NAME1=Bob/, data)
assert_match(/NAME2=Smith/, data)
assert_match(/ZIP=12345/, data)
assert_match(/CUSTOMER_IP=192\.168\.0\.1/, data)
+ assert_match(/DOC_TYPE=WEB/, data)
end.respond_with(successful_purchase_response)
assert_success response
@@ -145,8 +147,8 @@ def test_refund_passing_extra_info
def test_failed_refund
response = stub_comms do
- @gateway.refund(@amount, '123456789', @options.merge({:card_number => @credit_card.number}))
- end.check_request do |endpoint, data, headers|
+ @gateway.refund(@amount, '123456789', @options.merge({ card_number: @credit_card.number }))
+ end.check_request do |_endpoint, data, _headers|
assert_match(/CUSTOMER_IP=192\.168\.0\.1/, data)
end.respond_with(failed_refund_response)
@@ -159,8 +161,8 @@ def test_deprecated_credit
@gateway.expects(:ssl_post).returns(successful_purchase_response)
assert_deprecation_warning('credit should only be used to credit a payment method') do
response = stub_comms do
- @gateway.credit(@amount, '123456789', @options.merge({:card_number => @credit_card.number}))
- end.check_request do |endpoint, data, headers|
+ @gateway.credit(@amount, '123456789', @options.merge({ card_number: @credit_card.number }))
+ end.check_request do |_endpoint, data, _headers|
assert_match(/CUSTOMER_IP=192\.168\.0\.1/, data)
end.respond_with(failed_refund_response)
@@ -170,12 +172,22 @@ def test_deprecated_credit
end
end
+ def test_successful_credit_with_check
+ response = stub_comms do
+ @gateway.credit(50, @check, @options.merge({ doc_type: 'PPD' }))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/DOC_TYPE=PPD/, data)
+ end.respond_with(successful_credit_response)
+
+ assert_success response
+ end
+
def test_supported_countries
- assert_equal ['US', 'CA'], BluePayGateway.supported_countries
+ assert_equal %w[US CA], BluePayGateway.supported_countries
end
def test_supported_card_types
- assert_equal [:visa, :master, :american_express, :discover, :diners_club, :jcb], BluePayGateway.supported_cardtypes
+ assert_equal %i[visa master american_express discover diners_club jcb], BluePayGateway.supported_cardtypes
end
def test_parser_extracts_exactly_the_keys_in_gateway_response
@@ -208,8 +220,37 @@ def test_cvv_result
def test_message_from
assert_equal 'CVV does not match', @gateway.send(:parse, 'STATUS=2&CVV2=N&AVS=A&MESSAGE=FAILURE').message
- assert_equal 'Street address matches, but 5-digit and 9-digit postal code do not match.',
- @gateway.send(:parse, 'STATUS=2&CVV2=M&AVS=A&MESSAGE=FAILURE').message
+ assert_equal 'Street address matches, but postal code does not match.', @gateway.send(:parse, 'STATUS=2&CVV2=M&AVS=A&MESSAGE=FAILURE').message
+ end
+
+ def test_passing_stored_credentials_data_for_mit_transaction
+ options = @options.merge({ stored_credential: { initiator: 'merchant', reason_type: 'installment' } })
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/cof=M/, data)
+ assert_match(/cofscheduled=Y/, data)
+ end.respond_with(RSP[:approved_auth])
+ end
+
+ def test_passing_stored_credentials_for_cit_transaction
+ options = @options.merge({ stored_credential: { initiator: 'cardholder', reason_type: 'unscheduled' } })
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/cof=C/, data)
+ assert_match(/cofscheduled=N/, data)
+ end.respond_with(RSP[:approved_auth])
+ end
+
+ def test_passes_nothing_for_unrecognized_stored_credentials_values
+ options = @options.merge({ stored_credential: { initiator: 'unknown', reason_type: 'something weird' } })
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/cof=&/, data)
+ assert_match(/cofscheduled=&/, data)
+ end.respond_with(RSP[:approved_auth])
end
# Recurring Billing Unit Tests
@@ -217,12 +258,14 @@ def test_successful_recurring
@gateway.expects(:ssl_post).returns(successful_recurring_response)
response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do
- @gateway.recurring(@amount, @credit_card,
- :billing_address => address.merge(:first_name => 'Jim', :last_name => 'Smith'),
- :rebill_start_date => '1 MONTH',
- :rebill_expression => '14 DAYS',
- :rebill_cycles => '24',
- :rebill_amount => @amount * 4
+ @gateway.recurring(
+ @amount,
+ @credit_card,
+ billing_address: address.merge(first_name: 'Jim', last_name: 'Smith'),
+ rebill_start_date: '1 MONTH',
+ rebill_expression: '14 DAYS',
+ rebill_cycles: '24',
+ rebill_amount: @amount * 4
)
end
@@ -236,7 +279,7 @@ def test_successful_update_recurring
@gateway.expects(:ssl_post).returns(successful_update_recurring_response)
response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do
- @gateway.update_recurring(:rebill_id => @rebill_id, :rebill_amount => @amount * 2)
+ @gateway.update_recurring(rebill_id: @rebill_id, rebill_amount: @amount * 2)
end
assert_instance_of Response, response
@@ -324,6 +367,10 @@ def successful_status_recurring_response
'last_date=2012-04-13%2009%3A49%3A27&usual_date=2012-04-13%2000%3A00%3A00&template_id=100096219668&status=active&account_id=100096218902&rebill_id=100096219669&reb_amount=2.00&creation_date=2012-04-13%2009%3A49%3A19&sched_expr=1%20DAY&next_date=2012-04-13%2000%3A00%3A00&next_amount=&user_id=100096218903&cycles_remain=4'
end
+ def successful_credit_response
+ 'REBID=&AVS=_&TRANS_TYPE=CREDIT&STATUS=1&PAYMENT_ACCOUNT_MASK=C%3A244183602%3Axxxx8535&AUTH_CODE=&CARD_TYPE=ACH&MESSAGE=App%20ACH%20Credit&CVV2=_&TRANS_ID=100786598799'
+ end
+
def transcript
'card_num=4111111111111111&exp_date=1212&MASTER_ID=&PAYMENT_TYPE=CREDIT&PAYMENT_ACCOUNT=4242424242424242&CARD_CVV2=123&CARD_EXPIRE=0916&NAME1=Longbob&NAME2=Longsen&ORDER_ID=78c40687dd55dbdc140df777b0e8ece3&INVOICE_ID=&invoice_num=78c40687dd55dbdc140df777b0e8ece3&EMAIL=&CUSTOM_ID=&DUPLICATE_OVERRIDE=&TRANS_TYPE=SALE&AMOUNT=1.00&MODE=TEST&ACCOUNT_ID=100096218902&TAMPER_PROOF_SEAL=55624458ce3e15fa8e33e6f2d784bbcb'
end
diff --git a/test/unit/gateways/blue_snap_test.rb b/test/unit/gateways/blue_snap_test.rb
index c3cb84bea00..8553f4e9aea 100644
--- a/test/unit/gateways/blue_snap_test.rb
+++ b/test/unit/gateways/blue_snap_test.rb
@@ -1,5 +1,17 @@
+# coding: utf-8
+
require 'test_helper'
+class BlueSnapCurrencyDocMock
+ attr_accessor :received_amount
+
+ def currency(currency); end
+
+ def amount(amount)
+ @received_amount = amount
+ end
+end
+
class BlueSnapTest < Test::Unit::TestCase
include CommStub
@@ -8,7 +20,25 @@ def setup
@credit_card = credit_card
@check = check
@amount = 100
+
+ # BlueSnap may require support contact to activate fraud checking on sandbox accounts.
+ # Specific merchant-configurable thresholds were set and are reflected in the
+ # recorded responses:
+ # Order Total Amount Decline Threshold = 3728
+ # Payment Country Decline List = Brazil
+ @fraudulent_amount = 3729
+ @fraudulent_card = credit_card('4007702835532454')
+
@options = { order_id: '1', personal_identification_number: 'CNPJ' }
+ @options_3ds2 = @options.merge(
+ three_d_secure: {
+ eci: '05',
+ cavv: 'AAABAWFlmQAAAABjRWWZEEFgFz+A',
+ xid: 'MGpHWm5ZWVpKclo0aUk0VmltVDA=',
+ ds_transaction_id: 'jhg34-sdgds87-sdg87-sdfg7',
+ version: '2.2.0'
+ }
+ )
@valid_check_options = {
billing_address: {
address1: '123 Street',
@@ -19,6 +49,11 @@ def setup
},
authorized_by_shopper: true
}
+ @option_fraud_info = @options.merge(
+ transaction_fraud_info: {
+ fraud_session_id: 'fbcc094208f54c0e974d56875c73af7a'
+ }
+ )
end
def test_successful_purchase
@@ -29,6 +64,193 @@ def test_successful_purchase
assert_equal '1012082839', response.authorization
end
+ def test_successful_purchase_with_shipping_contact_info
+ more_options = @options.merge({
+ shipping_address: {
+ address1: '123 Main St',
+ adress2: 'Apt B',
+ city: 'Springfield',
+ state: 'NC',
+ country: 'US',
+ zip: '27701'
+ }
+ })
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, more_options)
+ end.check_request do |_method, _url, data|
+ assert_match(/shipping-contact-info/, data)
+ assert_match(/123 Main St/, data)
+ assert_match(/Springfield/, data)
+ assert_match(/NC/, data)
+ assert_match(/US/, data)
+ assert_match(/27701/, data)
+ end.respond_with(successful_purchase_response_with_metadata)
+
+ assert_success response
+ assert_equal '1012082839', response.authorization
+ end
+
+ def test_successful_purchase_with_card_holder_info
+ more_options = @options.merge({
+ billing_address: {
+ address1: '123 Street',
+ address2: 'Apt 1',
+ city: 'Happy City',
+ state: 'CA',
+ zip: '94901'
+ },
+ phone_number: '555 888 0000'
+ })
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, more_options)
+ end.check_request do |_method, _url, data|
+ assert_match(/card-holder-info/, data)
+ assert_match(/123 Street/, data)
+ assert_match(/Apt 1/, data)
+ assert_match(/555 888 0000/, data)
+ end.respond_with(successful_purchase_response_with_metadata)
+
+ assert_success response
+ assert_equal '1012082839', response.authorization
+ end
+
+ def test_successful_purchase_with_metadata
+ # description option should become meta-data field
+
+ more_options = @options.merge({
+ order_id: '1',
+ ip: '127.0.0.1',
+ email: 'joe@example.com',
+ transaction_meta_data: [
+ {
+ meta_key: 'stateTaxAmount',
+ meta_value: '20.00',
+ meta_description: 'State Tax Amount'
+ },
+ {
+ meta_key: 'cityTaxAmount',
+ meta_value: 10.00,
+ meta_description: 'City Tax Amount'
+ },
+ {
+ meta_key: 'websiteInfo',
+ meta_value: 'www.info.com',
+ meta_description: 'Website'
+ }
+ ],
+ description: 'Legacy Product Desc',
+ soft_descriptor: 'OnCardStatement',
+ personal_identification_number: 'CNPJ'
+ })
+
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, more_options)
+ end.check_request do |_method, _url, data|
+ assert_match(/transaction-meta-data/, data)
+ assert_match(/Legacy Product Desc<\/meta-value>/, data)
+ assert_match(/description<\/meta-key>/, data)
+ assert_match(/cityTaxAmount<\/meta-key>/, data)
+ assert_match(/stateTaxAmount<\/meta-key>/, data)
+ assert_match(/websiteInfo<\/meta-key>/, data)
+ end.respond_with(successful_purchase_response_with_metadata)
+
+ assert_success response
+ assert_equal '1012082839', response.authorization
+
+ assert_equal 4, response.params['transaction-meta-data'].length
+
+ response.params['transaction-meta-data'].each { |m|
+ assert_true m['meta-key'].length > 0
+ assert_true m['meta-value'].length > 0
+ assert_true m['meta-description'].length > 0
+
+ case m['meta-key']
+ when 'description'
+ assert_equal 'Product ABC', m['meta-value']
+ assert_equal 'Product Description', m['meta-description']
+ when 'cityTaxAmount'
+ assert_equal '10.00', m['meta-value']
+ assert_equal 'City Tax Amount', m['meta-description']
+ when 'stateTaxAmount'
+ assert_equal '20.00', m['meta-value']
+ assert_equal 'State Tax Amount', m['meta-description']
+ end
+ }
+ end
+
+ def test_successful_purchase_with_metadata_empty
+ more_options = @options.merge({
+ order_id: '1',
+ ip: '127.0.0.1',
+ email: 'joe@example.com',
+ transaction_meta_data: [],
+ soft_descriptor: 'OnCardStatement',
+ personal_identification_number: 'CNPJ'
+ })
+
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, more_options)
+ end.check_request do |_method, _url, data|
+ assert_not_match(/transaction-meta-data/, data)
+ assert_not_match(/meta-key/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ assert_nil response.params['transaction-meta-data']
+ end
+
+ def test_successful_purchase_with_metadata_nil
+ more_options = @options.merge({
+ order_id: '1',
+ ip: '127.0.0.1',
+ email: 'joe@example.com',
+ transaction_meta_data: nil,
+ soft_descriptor: 'OnCardStatement',
+ personal_identification_number: 'CNPJ'
+ })
+
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, more_options)
+ end.check_request do |_method, _url, data|
+ assert_not_match(/transaction-meta-data/, data)
+ assert_not_match(/meta-key/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ assert_nil response.params['transaction-meta-data']
+ end
+
+ def test_successful_purchase_with_unused_state_code
+ unrecognized_state_code_options = {
+ billing_address: {
+ city: 'Dresden',
+ state: 'Sachsen',
+ country: 'DE',
+ zip: '01069'
+ }
+ }
+
+ @gateway.expects(:raw_ssl_request).returns(successful_stateless_purchase_response)
+
+ response = @gateway.purchase(@amount, @credit_card, unrecognized_state_code_options)
+ assert_success response
+ assert_equal '1021645629', response.authorization
+ assert_not_includes(response.params, 'state')
+ end
+
+ def test_successful_purchase_with_fraud_info
+ fraud_info = @option_fraud_info.merge({ ip: '123.12.134.1' })
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, fraud_info)
+ end.check_request do |_method, _url, data|
+ assert_match(/fbcc094208f54c0e974d56875c73af7a<\/fraud-session-id>/, data)
+ assert_match(/123.12.134.1<\/shopper-ip-address>/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ assert_equal '1012082839', response.authorization
+ end
+
def test_successful_echeck_purchase
@gateway.expects(:raw_ssl_request).returns(successful_echeck_purchase_response)
@@ -37,6 +259,63 @@ def test_successful_echeck_purchase
assert_equal '1019803029', response.authorization
end
+ def test_successful_purchase_with_3ds_auth
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options_3ds2)
+ end.check_request do |_method, _url, data|
+ assert_match(//, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:eci])}<\/eci>/, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:cavv])}<\/cavv>/, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:xid])}<\/xid>/, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:version])}<\/three-d-secure-version>/, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:ds_transaction_id])}<\/ds-transaction-id>/, data)
+ end.respond_with(successful_purchase_with_3ds_auth_response)
+
+ assert_success response
+ assert_equal '1024951831', response.authorization
+ assert_equal '019082915501456', response.params['original-network-transaction-id']
+ assert_equal '019082915501456', response.params['network-transaction-id']
+ end
+
+ def test_successful_purchase_with_cit_stored_credential_fields
+ cit_stored_credentials = {
+ initiator: 'cardholder',
+ network_transaction_id: 'ABC123'
+ }
+ stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options_3ds2.merge({ stored_credential: cit_stored_credentials }))
+ end.check_request do |_method, _url, data|
+ assert_match 'SHOPPER', data
+ assert_match 'ABC123', data
+ end.respond_with(successful_purchase_with_3ds_auth_response)
+ end
+
+ def test_successful_purchase_with_mit_stored_credential_fields
+ cit_stored_credentials = {
+ initiator: 'merchant',
+ network_transaction_id: 'QER100'
+ }
+ stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options_3ds2.merge({ stored_credential: cit_stored_credentials }))
+ end.check_request do |_method, _url, data|
+ assert_match 'MERCHANT', data
+ assert_match 'QER100', data
+ end.respond_with(successful_purchase_with_3ds_auth_response)
+ end
+
+ def test_does_not_send_3ds_auth_when_empty
+ stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_method, _url, data|
+ assert_not_match(//, data)
+ assert_not_match(//, data)
+ assert_not_match(//, data)
+ assert_not_match(//, data)
+ assert_not_match(//, data)
+ assert_not_match(//, data)
+ end.respond_with(successful_purchase_response)
+ end
+
def test_failed_purchase
@gateway.expects(:raw_ssl_request).returns(failed_purchase_response)
@@ -56,7 +335,7 @@ def test_failed_echeck_purchase
def test_successful_authorize
response = stub_comms(@gateway, :raw_ssl_request) do
@gateway.authorize(@amount, @credit_card, @options)
- end.check_request do |type, endpoint, data, headers|
+ end.check_request do |_type, _endpoint, data, _headers|
assert_match 'false', data
assert_match 'CNPJ', data
end.respond_with(successful_authorize_response)
@@ -64,6 +343,37 @@ def test_successful_authorize
assert_equal '1012082893', response.authorization
end
+ def test_successful_authorize_with_descriptor_phone_number
+ options_with_phone_number = {
+ descriptor_phone_number: '321-321-4321'
+ }
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.authorize(@amount, @credit_card, options_with_phone_number)
+ end.check_request do |_method, _url, data|
+ assert_match('321-321-4321', data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_successful_authorize_with_3ds_auth
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.authorize(@amount, @credit_card, @options_3ds2)
+ end.check_request do |_type, _endpoint, data, _headers|
+ assert_match(//, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:eci])}<\/eci>/, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:cavv])}<\/cavv>/, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:xid])}<\/xid>/, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:version])}<\/three-d-secure-version>/, data)
+ assert_match(/#{Regexp.quote(@options_3ds2[:three_d_secure][:ds_transaction_id])}<\/ds-transaction-id>/, data)
+ end.respond_with(successful_authorize_with_3ds_auth_response)
+
+ assert_success response
+ assert_equal '1024951833', response.authorization
+ assert_equal 'MCC8929120829', response.params['original-network-transaction-id']
+ assert_equal 'MCC8929120829', response.params['network-transaction-id']
+ end
+
def test_failed_authorize
@gateway.expects(:raw_ssl_request).returns(failed_authorize_response)
@@ -73,9 +383,25 @@ def test_failed_authorize
end
def test_successful_capture
- @gateway.expects(:raw_ssl_request).returns(successful_capture_response)
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.capture(@amount, @credit_card, @options)
+ end.check_request do |_method, _url, data|
+ assert_not_match(/1.00<\/amount>/, data)
+ assert_not_match(/USD<\/currency>/, data)
+ end.respond_with(successful_capture_response)
+
+ assert_success response
+ assert_equal '1012082881', response.authorization
+ end
+
+ def test_successful_partial_capture
+ response = stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.capture(@amount, @credit_card, @options.merge(include_capture_amount: true))
+ end.check_request do |_method, _url, data|
+ assert_match(/1.00<\/amount>/, data)
+ assert_match(/USD<\/currency>/, data)
+ end.respond_with(successful_capture_response)
- response = @gateway.capture(@amount, 'Authorization')
assert_success response
assert_equal '1012082881', response.authorization
end
@@ -89,9 +415,58 @@ def test_failed_capture
end
def test_successful_refund
- @gateway.expects(:raw_ssl_request).returns(successful_refund_response)
+ options = {
+ reason: 'Refund for order #1992',
+ cancel_subscription: 'false',
+ tax_amount: 0.05,
+ transaction_meta_data: [
+ {
+ meta_key: 'refundedItems',
+ meta_value: '1552,8832',
+ meta_description: 'Refunded Items',
+ meta_is_visible: 'false'
+ },
+ {
+ meta_key: 'Number2',
+ meta_value: 'KTD',
+ meta_description: 'Metadata 2',
+ meta_is_visible: 'true'
+ }
+ ]
+ }
+ transaction_id = '1286'
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.refund(@amount, transaction_id, options)
+ end.check_request do |_action, endpoint, data, _headers|
+ doc = REXML::Document.new(data)
+
+ assert_includes endpoint, "/refund/#{transaction_id}"
+ assert_match(/1.00<\/amount>/, data)
+ assert_match(/0.05<\/tax-amount>/, data)
+ assert_match(/false<\/cancel-subscription>/, data)
+ assert_match(/Refund for order #1992<\/reason>/, data)
+ assert_match(/refundedItems<\/meta-key>/, data)
+ assert_match(/KTD<\/meta-value>/, data)
+ assert_match(/Metadata 2<\/meta-description>/, data)
+ transaction_meta_data = doc.root.elements['transaction-meta-data'].elements.to_a
+ transaction_meta_data.each_with_index do |item, index|
+ assert_match item.elements['meta-key'].text, options[:transaction_meta_data][index][:meta_key]
+ assert_match item.elements['meta-value'].text, options[:transaction_meta_data][index][:meta_value]
+ assert_match item.elements['meta-description'].text, options[:transaction_meta_data][index][:meta_description]
+ assert_match item.elements['is-visible'].text, options[:transaction_meta_data][index][:meta_is_visible]
+ end
+ end.respond_with(successful_refund_without_merchant_transaction_id_response)
+ assert_success response
+ assert_equal '1061398943', response.authorization
+ end
- response = @gateway.refund(@amount, 'Authorization')
+ def test_successful_refund_with_merchant_id
+ merchant_transaction_id = '12678'
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.refund(@amount, '', @options.merge({ merchant_transaction_id: merchant_transaction_id }))
+ end.check_request do |_action, endpoint, _data, _headers|
+ assert_includes endpoint, "/refund/merchant/#{merchant_transaction_id}"
+ end.respond_with(successful_refund_response)
assert_success response
assert_equal '1012082907', response.authorization
end
@@ -171,7 +546,7 @@ def test_failed_echeck_store
def test_currency_added_correctly
stub_comms(@gateway, :raw_ssl_request) do
@gateway.purchase(@amount, @credit_card, @options.merge(currency: 'CAD'))
- end.check_request do |method, url, data|
+ end.check_request do |_method, _url, data|
assert_match(/CAD<\/currency>/, data)
end.respond_with(successful_purchase_response)
end
@@ -194,15 +569,41 @@ def test_failed_forbidden_response
assert_equal 'You are not authorized to perform this request due to inappropriate role permissions.', response.message
end
+ def test_failed_rate_limit_response
+ @gateway.expects(:raw_ssl_request).returns(rate_limit_response)
+
+ response = @gateway.purchase(@amount, @credit_card, @options)
+ assert_failure response
+ assert_equal 'Client request rate is too high', response.message
+ end
+
def test_does_not_send_level_3_when_empty
response = stub_comms(@gateway, :raw_ssl_request) do
@gateway.purchase(@amount, @credit_card, @options)
- end.check_request do |type, endpoint, data, headers|
+ end.check_request do |_type, _endpoint, data, _headers|
assert_not_match(/level-3-data/, data)
end.respond_with(successful_purchase_response)
assert_success response
end
+ def test_fraud_response_handling
+ @gateway.expects(:raw_ssl_request).returns(fraudulent_purchase_response)
+
+ response = @gateway.purchase(@fraudulent_amount, @credit_card, @options)
+ assert_failure response
+ assert_match(/fraud-reference-id/, response.message)
+ assert_match(/fraud-event/, response.message)
+ end
+
+ def test_fraud_response_handling_multiple_triggers
+ @gateway.expects(:raw_ssl_request).returns(fraudulent_purchase_response_multiple_triggers)
+
+ response = @gateway.purchase(@fraudulent_amount, @fraudulent_card, @options)
+ assert_failure response
+ assert_match(/orderTotalDecline/, response.message)
+ assert_match(/blacklistPaymentCountryDecline/, response.message)
+ end
+
def test_scrub
assert @gateway.supports_scrubbing?
assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed
@@ -213,8 +614,41 @@ def test_echeck_scrub
assert_equal @gateway.scrub(pre_scrubbed_echeck), post_scrubbed_echeck
end
+ def test_localizes_currencies
+ amount = 1234
+
+ # Check a 2 decimal place currency
+ assert_equal '12.34', check_amount_registered(amount, 'USD')
+
+ # Check all 0 decimal currencies
+ ActiveMerchant::Billing::BlueSnapGateway.currencies_without_fractions.each do |currency|
+ assert_equal '12', check_amount_registered(amount, currency)
+ end
+
+ # Check all 3 decimal currencies
+ ActiveMerchant::Billing::BlueSnapGateway.currencies_with_three_decimal_places.each do |currency|
+ assert_equal '1.234', check_amount_registered(amount, currency)
+ end
+ end
+
+ def test_optional_idempotency_key_header
+ stub_comms(@gateway, :raw_ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options.merge({ idempotency_key: 'test123' }))
+ end.check_request do |_method, _url, _data, headers|
+ assert_equal 'test123', headers['Idempotency-Key']
+ end.respond_with(successful_authorize_response)
+ end
+
private
+ def check_amount_registered(amount, currency)
+ doc = BlueSnapCurrencyDocMock.new
+ options = @options.merge(currency: currency)
+ @gateway.send(:add_amount, doc, amount, options)
+
+ doc.received_amount
+ end
+
def pre_scrubbed
%q{
opening connection to sandbox.bluesnap.com:443...
@@ -306,6 +740,108 @@ def successful_purchase_response
XML
end
+ def successful_purchase_response_with_metadata
+ MockResponse.succeeded <<-XML
+
+
+ AUTH_CAPTURE
+ 1012082839
+ ECOMMERCE
+ BLS*Spreedly
+ 1.00
+ USD
+
+ Longbob
+ Longsen
+ CA
+ ON
+ Ottawa
+ K1C2N6
+ CNPJ
+
+
+ 9299
+ VISA
+ CREDIT
+
+
+
+ stateTaxAmount
+ 20.00
+ State Tax Amount
+
+
+ cityTaxAmount
+ 10.00
+ City Tax Amount
+
+
+ shippingAmount
+ 150.00
+ Shipping Amount
+
+
+ websiteInfo
+ www.info.com
+ Website
+
+
+
+ success
+ ND
+ U
+ U
+ U
+
+
+ XML
+ end
+
+ def successful_purchase_with_3ds_auth_response
+ MockResponse.succeeded <<-XML
+
+
+ AUTH_CAPTURE
+ 1024951831
+ ECOMMERCE
+ BLS*Spreedly
+ 1.00
+ 1.00
+ USD
+ N
+
+ Longbob
+ Longsen
+ CA
+ ON
+ Ottawa
+ K1C2N6
+
+ 25105083
+
+ 1091
+ VISA
+ CREDIT
+ CONSUMER
+ N
+ us
+
+
+ 019082915501456
+ 019082915501456
+
+
+ success
+ NR
+ N
+ N
+ U
+ 019082915501456
+
+
+ XML
+ end
+
def successful_echeck_purchase_response
MockResponse.succeeded <<-XML
@@ -333,6 +869,46 @@ def successful_echeck_purchase_response
XML
end
+ def successful_stateless_purchase_response
+ MockResponse.succeeded <<-XML
+
+
+ AUTH_CAPTURE
+ 1021645629
+ ECOMMERCE
+ BLS*Spreedly
+ 1.00
+ 1.00
+ USD
+
+ Longbob
+ Longsen
+ DE
+ Dresden
+ 01069
+
+ 24449087
+
+ 9299
+ VISA
+ CREDIT
+ PLATINUM
+ CONSUMER
+ N
+ ALLIED IRISH BANKS PLC
+ ie
+
+
+ success
+ ND
+ U
+ U
+ U
+
+
+ XML
+ end
+
def failed_purchase_response
body = <<-XML
@@ -398,6 +974,53 @@ def successful_authorize_response
XML
end
+ def successful_authorize_with_3ds_auth_response
+ MockResponse.succeeded <<-XML
+
+
+ AUTH_ONLY
+ 1024951833
+ ECOMMERCE
+ BLS*Spreedly
+ 1.00
+ 1.00
+ USD
+ S
+
+ Longbob
+ Longsen
+ CA
+ ON
+ Ottawa
+ K1C2N6
+
+ 25105085
+
+ 1096
+ MASTERCARD
+ CREDIT
+ STANDARD
+ CONSUMER
+ N
+ PUBLIC BANK BERHAD
+ my
+
+
+ MCC8929120829
+ MCC8929120829
+
+
+ success
+ NC
+ U
+ U
+ U
+ MCC8929120829
+
+
+ XML
+ end
+
def failed_authorize_response
body = <<-XML
@@ -510,6 +1133,32 @@ def failed_refund_response
MockResponse.failed(body, 400)
end
+ def successful_refund_without_merchant_transaction_id_response
+ MockResponse.succeeded <<-XML
+
+
+ 1061398943
+ 1.00
+ 0.05
+
+
+ refundedItems
+ 1552,8832
+ Refunded Items
+ false
+
+
+ Number2
+ KTD
+ Metadata 2
+ true
+
+
+ Refund for order #1992
+
+ XML
+ end
+
def successful_void_response
MockResponse.succeeded <<-XML
@@ -712,6 +1361,59 @@ def forbidden_response
MockResponse.new(403, 'You are not authorized to perform this request due to inappropriate role permissions.')
end
+ def rate_limit_response
+ MockResponse.new(429, 'Client request rate is too high')
+ end
+
+ def fraudulent_purchase_response
+ body = <<-XML
+
+
+
+ FRAUD_DETECTED
+ 15011
+ The request cannot be fulfilled for the current shopper. Please contact BlueSnap support for further details.
+
+ 6270209
+
+ orderTotalDecline
+ D
+ 3729 > 3728
+
+
+
+
+ XML
+ MockResponse.new(400, body)
+ end
+
+ def fraudulent_purchase_response_multiple_triggers
+ body = <<-XML
+
+
+
+ FRAUD_DETECTED
+ 15011
+ The request cannot be fulfilled for the current shopper. Please contact BlueSnap support for further details.
+
+ 6270189
+
+ blacklistPaymentCountryDecline
+ D
+ BR is in list: [BR]
+
+
+ orderTotalDecline
+ D
+ 3729 > 3728
+
+
+
+
+ XML
+ MockResponse.new(400, body)
+ end
+
def credentials_are_legit_response
MockResponse.new(400, 'Server Error')
end
diff --git a/test/unit/gateways/bogus_test.rb b/test/unit/gateways/bogus_test.rb
index e6978d828e1..301ed2ddfa6 100644
--- a/test/unit/gateways/bogus_test.rb
+++ b/test/unit/gateways/bogus_test.rb
@@ -8,13 +8,13 @@ class BogusTest < Test::Unit::TestCase
def setup
@gateway = BogusGateway.new(
- :login => 'bogus',
- :password => 'bogus'
+ login: 'bogus',
+ password: 'bogus'
)
@creditcard = credit_card(CC_SUCCESS_PLACEHOLDER)
- @response = ActiveMerchant::Billing::Response.new(true, 'Transaction successful', :transid => BogusGateway::AUTHORIZATION)
+ @response = ActiveMerchant::Billing::Response.new(true, 'Transaction successful', transid: BogusGateway::AUTHORIZATION)
end
def test_authorize
@@ -47,7 +47,7 @@ def test_purchase
def test_capture
assert @gateway.capture(1000, '1337').success?
assert @gateway.capture(1000, @response.params['transid']).success?
- response = @gateway.capture(1000, CC_FAILURE_PLACEHOLDER)
+ response = @gateway.capture(1000, CC_FAILURE_PLACEHOLDER)
refute response.success?
assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], response.error_code
assert_raises(ActiveMerchant::Billing::Error) do
@@ -57,7 +57,7 @@ def test_capture
def test_credit
assert @gateway.credit(1000, credit_card(CC_SUCCESS_PLACEHOLDER)).success?
- response = @gateway.credit(1000, credit_card(CC_FAILURE_PLACEHOLDER))
+ response = @gateway.credit(1000, credit_card(CC_FAILURE_PLACEHOLDER))
refute response.success?
assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], response.error_code
e = assert_raises(ActiveMerchant::Billing::Error) do
@@ -78,7 +78,7 @@ def test_refund
end
def test_credit_uses_refund
- options = {:foo => :bar}
+ options = { foo: :bar }
@gateway.expects(:refund).with(1000, '1337', options)
assert_deprecation_warning(Gateway::CREDIT_DEPRECATION_MESSAGE) do
@gateway.credit(1000, '1337', options)
@@ -96,6 +96,17 @@ def test_void
end
end
+ def test_verify
+ assert @gateway.verify(credit_card(CC_SUCCESS_PLACEHOLDER)).success?
+ response = @gateway.verify(credit_card(CC_FAILURE_PLACEHOLDER))
+ refute response.success?
+ assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], response.error_code
+ e = assert_raises(ActiveMerchant::Billing::Error) do
+ @gateway.verify(credit_card('123'))
+ end
+ assert_equal('Bogus Gateway: Use CreditCard number ending in 1 for success, 2 for exception and anything else for error', e.message)
+ end
+
def test_store
assert @gateway.store(credit_card(CC_SUCCESS_PLACEHOLDER)).success?
response = @gateway.store(credit_card(CC_FAILURE_PLACEHOLDER))
@@ -125,71 +136,71 @@ def test_supported_card_types
end
def test_authorize_with_check
- assert @gateway.authorize(1000, check(:account_number => CHECK_SUCCESS_PLACEHOLDER, :number => nil)).success?
- assert !@gateway.authorize(1000, check(:account_number => CHECK_FAILURE_PLACEHOLDER, :number => nil)).success?
+ assert @gateway.authorize(1000, check(account_number: CHECK_SUCCESS_PLACEHOLDER, number: nil)).success?
+ assert !@gateway.authorize(1000, check(account_number: CHECK_FAILURE_PLACEHOLDER, number: nil)).success?
e = assert_raises(ActiveMerchant::Billing::Error) do
- @gateway.authorize(1000, check(:account_number => '123', :number => nil))
+ @gateway.authorize(1000, check(account_number: '123', number: nil))
end
assert_equal('Bogus Gateway: Use bank account number ending in 1 for success, 2 for exception and anything else for error', e.message)
end
def test_purchase_with_check
# use account number if number isn't given
- assert @gateway.purchase(1000, check(:account_number => CHECK_SUCCESS_PLACEHOLDER, :number => nil)).success?
- assert !@gateway.purchase(1000, check(:account_number => CHECK_FAILURE_PLACEHOLDER, :number => nil)).success?
+ assert @gateway.purchase(1000, check(account_number: CHECK_SUCCESS_PLACEHOLDER, number: nil)).success?
+ assert !@gateway.purchase(1000, check(account_number: CHECK_FAILURE_PLACEHOLDER, number: nil)).success?
# give priority to number over account_number if given
- assert !@gateway.purchase(1000, check(:account_number => CHECK_SUCCESS_PLACEHOLDER, :number => CHECK_FAILURE_PLACEHOLDER)).success?
- assert @gateway.purchase(1000, check(:account_number => CHECK_FAILURE_PLACEHOLDER, :number => CHECK_SUCCESS_PLACEHOLDER)).success?
+ assert !@gateway.purchase(1000, check(account_number: CHECK_SUCCESS_PLACEHOLDER, number: CHECK_FAILURE_PLACEHOLDER)).success?
+ assert @gateway.purchase(1000, check(account_number: CHECK_FAILURE_PLACEHOLDER, number: CHECK_SUCCESS_PLACEHOLDER)).success?
e = assert_raises(ActiveMerchant::Billing::Error) do
- @gateway.purchase(1000, check(:account_number => '123', :number => nil))
+ @gateway.purchase(1000, check(account_number: '123', number: nil))
end
assert_equal('Bogus Gateway: Use bank account number ending in 1 for success, 2 for exception and anything else for error', e.message)
end
def test_store_with_check
- assert @gateway.store(check(:account_number => CHECK_SUCCESS_PLACEHOLDER, :number => nil)).success?
- assert !@gateway.store(check(:account_number => CHECK_FAILURE_PLACEHOLDER, :number => nil)).success?
+ assert @gateway.store(check(account_number: CHECK_SUCCESS_PLACEHOLDER, number: nil)).success?
+ assert !@gateway.store(check(account_number: CHECK_FAILURE_PLACEHOLDER, number: nil)).success?
e = assert_raises(ActiveMerchant::Billing::Error) do
- @gateway.store(check(:account_number => '123', :number => nil))
+ @gateway.store(check(account_number: '123', number: nil))
end
assert_equal('Bogus Gateway: Use bank account number ending in 1 for success, 2 for exception and anything else for error', e.message)
end
def test_credit_with_check
- assert @gateway.credit(1000, check(:account_number => CHECK_SUCCESS_PLACEHOLDER, :number => nil)).success?
- assert !@gateway.credit(1000, check(:account_number => CHECK_FAILURE_PLACEHOLDER, :number => nil)).success?
+ assert @gateway.credit(1000, check(account_number: CHECK_SUCCESS_PLACEHOLDER, number: nil)).success?
+ assert !@gateway.credit(1000, check(account_number: CHECK_FAILURE_PLACEHOLDER, number: nil)).success?
e = assert_raises(ActiveMerchant::Billing::Error) do
- @gateway.credit(1000, check(:account_number => '123', :number => nil))
+ @gateway.credit(1000, check(account_number: '123', number: nil))
end
assert_equal('Bogus Gateway: Use bank account number ending in 1 for success, 2 for exception and anything else for error', e.message)
end
def test_store_then_purchase_with_check
- reference = @gateway.store(check(:account_number => CHECK_SUCCESS_PLACEHOLDER, :number => nil))
+ reference = @gateway.store(check(account_number: CHECK_SUCCESS_PLACEHOLDER, number: nil))
assert @gateway.purchase(1000, reference.authorization).success?
end
def test_authorize_emv
- approve_response = @gateway.authorize(1000, credit_card('123', {icc_data: 'DEADBEEF'}))
+ approve_response = @gateway.authorize(1000, credit_card('123', { icc_data: 'DEADBEEF' }))
assert approve_response.success?
assert_equal '8A023030', approve_response.emv_authorization
- decline_response = @gateway.authorize(1005, credit_card('123', {icc_data: 'DEADBEEF'}))
+ decline_response = @gateway.authorize(1005, credit_card('123', { icc_data: 'DEADBEEF' }))
refute decline_response.success?
assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], decline_response.error_code
assert_equal '8A023035', decline_response.emv_authorization
e = assert_raises(ActiveMerchant::Billing::Error) do
- @gateway.authorize(1001, credit_card('123', {icc_data: 'DEADBEEF'}))
+ @gateway.authorize(1001, credit_card('123', { icc_data: 'DEADBEEF' }))
end
assert_equal('Bogus Gateway: Use amount ending in 00 for success, 05 for failure and anything else for exception', e.message)
end
def test_purchase_emv
- assert @gateway.purchase(1000, credit_card('123', {icc_data: 'DEADBEEF'})).success?
- response = @gateway.purchase(1005, credit_card('123', {icc_data: 'DEADBEEF'}))
+ assert @gateway.purchase(1000, credit_card('123', { icc_data: 'DEADBEEF' })).success?
+ response = @gateway.purchase(1005, credit_card('123', { icc_data: 'DEADBEEF' }))
refute response.success?
assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], response.error_code
e = assert_raises(ActiveMerchant::Billing::Error) do
- @gateway.purchase(1001, credit_card('123', {icc_data: 'DEADBEEF'}))
+ @gateway.purchase(1001, credit_card('123', { icc_data: 'DEADBEEF' }))
end
assert_equal('Bogus Gateway: Use amount ending in 00 for success, 05 for failure and anything else for exception', e.message)
end
diff --git a/test/unit/gateways/borgun_test.rb b/test/unit/gateways/borgun_test.rb
index bd38587664a..8550b24eb79 100644
--- a/test/unit/gateways/borgun_test.rb
+++ b/test/unit/gateways/borgun_test.rb
@@ -49,13 +49,72 @@ def test_authorize_and_capture
capture = stub_comms do
@gateway.capture(@amount, response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/140601083732/, data)
end.respond_with(successful_capture_response)
assert_success capture
end
+ def test_failed_preauth_3ds
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options.merge({ redirect_url: 'http://localhost/index.html', apply_3d_secure: '1', sale_description: 'product description' }))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/MerchantReturnURL>#{@options[:redirect_url]}/, data)
+ assert_match(/SaleDescription>#{@options[:sale_description]}/, data)
+ assert_match(/TrCurrencyExponent>2/, data)
+ end.respond_with(failed_get_3ds_authentication_response)
+
+ assert_failure response
+ assert_equal response.message, 'Exception in PostEnrollmentRequest.'
+ assert response.authorization.blank?
+ end
+
+ def test_successful_preauth_3ds
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options.merge({ redirect_url: 'http://localhost/index.html', apply_3d_secure: '1', sale_description: 'product description' }))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/MerchantReturnURL>#{@options[:redirect_url]}/, data)
+ assert_match(/SaleDescription>#{@options[:sale_description]}/, data)
+ assert_match(/TrCurrencyExponent>2/, data)
+ end.respond_with(successful_get_3ds_authentication_response)
+
+ assert_success response
+ assert !response.params['redirecttoacsform'].blank?
+ assert !response.params['acsformfields_actionurl'].blank?
+ assert !response.params['acsformfields_pareq'].blank?
+ assert !response.params['threedsmessageid'].blank?
+ assert response.authorization.blank?
+ end
+
+ def test_successful_purchase_after_3ds
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options.merge({ three_ds_message_id: '98324_zzi_1234353' }))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/ThreeDSMessageId>#{@options[:three_ds_message_id]}/, data)
+ assert_match(/TrCurrencyExponent>0/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ def test_authorize_airline_data
+ # itinerary data abbreviated for brevity
+ passenger_itinerary_data = {
+ 'MessageNumber' => '1111111',
+ 'TrDate' => '20120222',
+ 'TrTime' => '151515',
+ 'PassengerName' => 'Jane Doe'
+ }
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, { passenger_itinerary_data: passenger_itinerary_data })
+ end.check_request do |_endpoint, data, _headers|
+ assert_match('PassengerItineraryData', data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
def test_refund
response = stub_comms do
@gateway.purchase(@amount, @credit_card)
@@ -66,7 +125,7 @@ def test_refund
refund = stub_comms do
@gateway.refund(@amount, response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/140216103700/, data)
end.respond_with(successful_refund_response)
@@ -83,7 +142,7 @@ def test_void
refund = stub_comms do
@gateway.void(response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/140216103700/, data)
end.respond_with(successful_void_response)
@@ -93,7 +152,7 @@ def test_void
def test_passing_cvv
stub_comms do
@gateway.purchase(@amount, @credit_card)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/#{@credit_card.verification_value}/, data)
end.respond_with(successful_purchase_response)
end
@@ -101,7 +160,7 @@ def test_passing_cvv
def test_passing_terminal_id
stub_comms do
@gateway.purchase(@amount, @credit_card, { terminal_id: '3' })
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/TerminalID>3/, data)
end.respond_with(successful_purchase_response)
end
@@ -295,6 +354,55 @@ def successful_void_response
)
end
+ def successful_get_3ds_authentication_response
+ <<~RESPONSE
+
+
+
+
+
+ 0
+
+
+ 1000
+ 23
+ 23
+ 23_20201408041400003
+ 9
+ ToberedirectedtoACS
+ Y
+ 3C21444F43545950452068746D6C2053595354454D202261626F75743A6C65676163792D636F6D706174223E0D0D0A3C68746D6C20636C6173733D226E6F2D6A7322206C616E673D22656E2220786D6C6E733D22687474703A2F2F7777772E77332E6F72672F313939392F7868746D6C223E0D0D0A3C686561643E0D0D0A3C6D65746120687474702D65717569763D22436F6E74656E742D547970652220636F6E74656E743D22746578742F68746D6C3B20636861727365743D7574662D38222F3E0D0D0A3C6D65746120636861727365743D227574662D38222F3E0D0D0A3C7469746C653E3344205365637572652050726F63657373696E673C2F7469746C653E0D0D0A3C6C696E6B20687265663D2268747470733A2F2F6D70692E626F7267756E2E69732F6D647061796D70692F7374617469632F6D70692E637373222072656C3D227374796C6573686565742220747970653D22746578742F637373222F3E0D0D0A3C2F686561643E0D0D0A3C626F64793E0D0D0A3C6469762069643D226D61696E223E0D0D0A3C6469762069643D22636F6E74656E74223E0D0D0A3C6469762069643D226F72646572223E0D0D0A3C68323E3344205365637572652050726F63657373696E673C2F68323E0D0D0A3C696D67207372633D2268747470733A2F2F6D70692E626F7267756E2E69732F6D647061796D70692F7374617469632F7072656C6F616465722E6769662220616C743D22506C6561736520776169742E2E222F3E0D0D0A3C696D67207372633D2268747470733A2F2F6D70692E626F7267756E2E69732F6D647061796D70692F7374617469632F6D635F6964636865636B5F68727A5F6C74645F706F735F31303370782E706E672220616C743D224D61737465724361726420494420436865636B222F3E0D0D0A3C6469762069643D22666F726D646976223E0D0D0A3C73637269707420747970653D22746578742F6A617661736372697074223E0D0D0A66756E6374696F6E2068696465416E645375626D697454696D656428666F726D6964290D0D0A7B0D0D0A7661722074696D65723D73657454696D656F7574282268696465416E645375626D69742827222B666F726D69642B2227293B222C313030293B0D0D0A7D0D0D0A0D0D0A66756E6374696F6E2068696465416E645375626D697428666F726D6964290D0D0A7B0D0D0A76617220666F726D783D646F63756D656E742E676574456C656D656E744279496428666F726D6964293B0D0D0A0969662028666F726D78213D6E756C6C290D0D0A097B0D0D0A09666F726D782E7374796C652E7669736962696C6974793D2268696464656E223B0D0D0A09666F726D782E7375626D697428293B0D0D0A097D0D0D0A7D0D0D0A3C2F7363726970743E0D0D0A3C6469763E0D0D0A3C666F726D2069643D22776562666F726D3022206E616D653D2272656432414353763122206D6574686F643D22504F53542220616374696F6E3D2268747470733A2F2F616373312E3364732E6D6F646972756D2E636F6D2F6D647061796163732F706172657122206163636570745F636861727365743D225554462D38223E0D0D0A3C696E70757420747970653D2268696464656E22206E616D653D225F636861727365745F222076616C75653D225554462D38222F3E0D0D0A3C696E70757420747970653D2268696464656E22206E616D653D225061526571222076616C75653D22654A785655753175676A4155665258692F396D57723443354E7346684D724C676D4F7746574C6C427A437861697445392F56715575663237353979766E6E4D4C487A75466D4A596F426F556363757A37716B476E725A657A5976764F614F4146455976634759636932654B4A77786C5633336153737A6D647530416D614471563246565363366A45615A5674654F417A502F4B4133434563554755706A39306744434D6679413243724137495635317142756B384F586D52505A56765365466F374855724779426A486B5133534B32753341764D79676E416F4C37345475766A6770445063634B383759465946736A6A4F6356676F39354D756251317A2F664A4E552B5449452B627932612F706E6D6166322F53684F587065676E45566B42646165517564536D4E61655377634D4838425456435268367167313350732F4C56595A51616554634D5237736D75594578385A6341343635434B53594645774B384844754A707349302F4D5A51597939346F627036454E6F70555A31626755625A53414E354348702B7357344C6259786B4E4B4978382B4B5157636448796735766A5538756F3279636267455132305475787954336535766F337A2F34415552317277553D222F3E0D0D0A3C696E70757420747970653D2268696464656E22206E616D653D224D44222076616C75653D2232335F3230323031343038303431343030303033222F3E0D0D0A3C696E70757420747970653D2268696464656E22206E616D653D225465726D55726C222076616C75653D22687474703A2F2F6C6F63616C686F73742F696E6465782E68746D6C222F3E0D0D0A3C696E70757420747970653D227375626D697422206E616D653D227375626D697442746E222076616C75653D22506C6561736520636C69636B206865726520746F20636F6E74696E7565222F3E0D0D0A3C2F666F726D3E0D0D0A3C2F6469763E0D0D0A3C2F6469763E0D0D0A3C73637269707420747970653D22746578742F6A617661736372697074223E0D0D0A09090968696465416E645375626D697454696D65642827776562666F726D3027293B0D0D0A09093C2F7363726970743E0D0D0A3C6E6F7363726970743E0D0D0A3C64697620616C69676E3D2263656E746572223E0D0D0A3C623E4A617661736372697074206973207475726E6564206F6666206F72206E6F7420737570706F72746564213C2F623E0D0D0A3C62722F3E0D0D0A3C2F6469763E0D0D0A3C2F6E6F7363726970743E0D0D0A3C2F6469763E0D0D0A3C6469762069643D22636F6E74656E742D666F6F746572223E0D0D0A3C62722F3E0D0D0A3C696D67206865696768743D22323022207372633D2268747470733A2F2F6D70692E626F7267756E2E69732F6D647061796D70692F7374617469632F706F77657265642D62792D6D6F646972756D2E7376672220616C743D22506F7765726564206279204D6F646972756D222F3E0D0D0A3C2F6469763E0D0D0A3C2F6469763E0D0D0A3C2F6469763E0D0D0A3C2F626F64793E0D0D0A3C2F68746D6C3E0D0D0A
+
+
+ https://acs1.3ds.modirum.com/mdpayacs/pareq
+ eJxVUu1ugjAUfRXi/9mWr4C5NsFhMrLgmOwFWLlBzCxaitE9/VqUuf2759yvnnMLHzuFmJYoBoUccuz7qkGnrZezYvvOaOAFEYvcGYci2eKJwxlV33aSszmdu0AmaDqV2FVSc6jEaZVteOAzP/KA3CEcUGUpj90gDCMfyA2CrA7IV51qBuk8OXmRPZVvSeFo7HUrGyBjHkQ3SK2u3AvMygnAoL74TuvjgpDPccK87YFYFsjjOcVgo95MubQ1z/fJNU+TIE+by2a/pnmaf2/ShOXpegnEVkBdaeQudSmNaeSwcMH8BTVCRh6qg13Ps/LVYZQaeTcMR7smuYEx8ZcA465CKSYFEwK8HDuJpsI0/MZQYy94obp6ENopUZ1bgUbZSAN5CHp+sW4LbYxkNKIx8+KQWcdHyg5vjU8uo2ycbgEQ20TuxyT3e5vo3z/4AUR1rwU=
+ http://localhost/index.html
+
+
+
+
+ RESPONSE
+ end
+
+ def failed_get_3ds_authentication_response
+ %(
+
+
+
+
+ <?xml version="1.0" encoding="iso-8859-1"?>
+ <get3DSAuthenticationReply>
+ <Status>
+ <ResultCode>30</ResultCode>
+ <ResultText>MPI returns error</ResultText>
+ <ErrorMessage>Exception in PostEnrollmentRequest.</ErrorMessage>
+ </Status>
+ </get3DSAuthenticationReply>
+
+
+ )
+ end
+
def transcript
<<-PRE_SCRUBBED
<- "POST /ws/Heimir.pub.ws:Authorization HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAuthorization: Basic yyyyyyyyyyyyyyyyyyyyyyyyyy==\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: gateway01.borgun.is\r\nContent-Length: 1220\r\n\r\n"
diff --git a/test/unit/gateways/bpoint_test.rb b/test/unit/gateways/bpoint_test.rb
index 384862ab576..1c156a6212e 100644
--- a/test/unit/gateways/bpoint_test.rb
+++ b/test/unit/gateways/bpoint_test.rb
@@ -88,13 +88,23 @@ def test_failed_refund
def test_successful_void
@gateway.expects(:ssl_post).returns(successful_void_response)
- response = @gateway.void(@amount, '')
+ response = @gateway.void('', amount: 300)
assert_success response
end
+ def test_void_passes_correct_transaction_reference
+ stub_comms do
+ # transaction number from successful authorize response
+ @gateway.void('219388558', amount: 300)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(%r(219388558)m, data)
+ assert_match(%r(300)m, data)
+ end.respond_with(successful_void_response)
+ end
+
def test_failed_void
@gateway.expects(:ssl_post).returns(failed_void_response)
- response = @gateway.void(@amount, '')
+ response = @gateway.void('')
assert_failure response
end
@@ -125,11 +135,20 @@ def test_scrub
def test_passing_biller_code
stub_comms do
@gateway.authorize(@amount, @credit_card, { biller_code: '1234' })
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(%r(1234)m, data)
end.respond_with(successful_authorize_response)
end
+ def test_passing_reference_and_crn
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options.merge({ crn1: 'ref' }))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(%r(1)m, data)
+ assert_match(%r(ref)m, data)
+ end.respond_with(successful_authorize_response)
+ end
+
private
def pre_scrubbed
@@ -225,7 +244,7 @@ def successful_authorize_response
)
end
- alias_method :successful_verify_response, :successful_authorize_response
+ alias successful_verify_response successful_authorize_response
def failed_authorize_response
%(
@@ -252,7 +271,7 @@ def failed_authorize_response
)
end
- alias_method :failed_verify_response, :failed_authorize_response
+ alias failed_verify_response failed_authorize_response
def successful_capture_response
%(
diff --git a/test/unit/gateways/braintree_blue_test.rb b/test/unit/gateways/braintree_blue_test.rb
index ad3a1f1a848..14662a8e1bc 100644
--- a/test/unit/gateways/braintree_blue_test.rb
+++ b/test/unit/gateways/braintree_blue_test.rb
@@ -5,10 +5,10 @@ def setup
@old_verbose, $VERBOSE = $VERBOSE, false
@gateway = BraintreeBlueGateway.new(
- :merchant_id => 'test',
- :public_key => 'test',
- :private_key => 'test',
- :test => true
+ merchant_id: 'test',
+ public_key: 'test',
+ private_key: 'test',
+ test: true
)
@internal_gateway = @gateway.instance_variable_get(:@braintree_gateway)
@@ -21,22 +21,22 @@ def teardown
def test_refund_legacy_method_signature
Braintree::TransactionGateway.any_instance.expects(:refund).
with('transaction_id', nil).
- returns(braintree_result(:id => 'refund_transaction_id'))
- response = @gateway.refund('transaction_id', :test => true)
+ returns(braintree_result(id: 'refund_transaction_id'))
+ response = @gateway.refund('transaction_id', test: true)
assert_equal 'refund_transaction_id', response.authorization
end
def test_refund_method_signature
Braintree::TransactionGateway.any_instance.expects(:refund).
with('transaction_id', '10.00').
- returns(braintree_result(:id => 'refund_transaction_id'))
- response = @gateway.refund(1000, 'transaction_id', :test => true)
+ returns(braintree_result(id: 'refund_transaction_id'))
+ response = @gateway.refund(1000, 'transaction_id', test: true)
assert_equal 'refund_transaction_id', response.authorization
end
def test_transaction_uses_customer_id_by_default
Braintree::TransactionGateway.any_instance.expects(:sale).
- with(has_entries(:customer_id => 'present')).
+ with(has_entries(customer_id: 'present')).
returns(braintree_result)
assert response = @gateway.purchase(10, 'present', {})
@@ -46,7 +46,7 @@ def test_transaction_uses_customer_id_by_default
def test_transaction_uses_payment_method_token_when_option
Braintree::TransactionGateway.any_instance.expects(:sale).
- with(has_entries(:payment_method_token => 'present')).
+ with(has_entries(payment_method_token: 'present')).
returns(braintree_result)
assert response = @gateway.purchase(10, 'present', { payment_method_token: true })
@@ -56,7 +56,7 @@ def test_transaction_uses_payment_method_token_when_option
def test_transaction_uses_payment_method_nonce_when_option
Braintree::TransactionGateway.any_instance.expects(:sale).
- with(has_entries(:payment_method_nonce => 'present')).
+ with(all_of(has_entries(payment_method_nonce: 'present'), has_key(:customer))).
returns(braintree_result)
assert response = @gateway.purchase(10, 'present', { payment_method_nonce: true })
@@ -86,7 +86,7 @@ def test_purchase_transaction
def test_capture_transaction
Braintree::TransactionGateway.any_instance.expects(:submit_for_settlement).
- returns(braintree_result(:id => 'capture_transaction_id'))
+ returns(braintree_result(id: 'capture_transaction_id'))
response = @gateway.capture(100, 'transaction_id')
@@ -94,9 +94,19 @@ def test_capture_transaction
assert_equal true, response.test
end
+ def test_partial_capture_transaction
+ Braintree::TransactionGateway.any_instance.expects(:submit_for_partial_settlement).
+ returns(braintree_result(id: 'capture_transaction_id'))
+
+ response = @gateway.capture(100, 'transaction_id', { partial_capture: true })
+
+ assert_equal 'capture_transaction_id', response.authorization
+ assert_equal true, response.test
+ end
+
def test_refund_transaction
Braintree::TransactionGateway.any_instance.expects(:refund).
- returns(braintree_result(:id => 'refund_transaction_id'))
+ returns(braintree_result(id: 'refund_transaction_id'))
response = @gateway.refund(1000, 'transaction_id')
assert_equal 'refund_transaction_id', response.authorization
@@ -106,7 +116,7 @@ def test_refund_transaction
def test_void_transaction
Braintree::TransactionGateway.any_instance.expects(:void).
with('transaction_id').
- returns(braintree_result(:id => 'void_transaction_id'))
+ returns(braintree_result(id: 'void_transaction_id'))
response = @gateway.void('transaction_id')
assert_equal 'void_transaction_id', response.authorization
@@ -127,20 +137,53 @@ def test_verify_bad_credentials
assert !@gateway.verify_credentials
end
+ def test_zero_dollar_verification_transaction
+ Braintree::CreditCardVerificationGateway.any_instance.expects(:create).
+ returns(braintree_result(cvv_response_code: 'M', avs_error_response_code: 'P'))
+
+ card = credit_card('4111111111111111')
+ options = {
+ allow_card_verification: true,
+ billing_address: {
+ zip: '10000'
+ }
+ }
+ response = @gateway.verify(card, options)
+ assert_success response
+ assert_equal 'transaction_id', response.params['authorization']
+ assert_equal 'M', response.cvv_result['code']
+ assert_equal 'P', response.avs_result['code']
+ end
+
+ def test_failed_verification_transaction
+ Braintree::CreditCardVerificationGateway.any_instance.expects(:create).
+ returns(braintree_error_result(message: 'CVV must be 4 digits for American Express and 3 digits for other card types. (81707)'))
+
+ card = credit_card('4111111111111111')
+ options = {
+ allow_card_verification: true,
+ billing_address: {
+ zip: '10000'
+ }
+ }
+ response = @gateway.verify(card, options)
+ assert_failure response
+ end
+
def test_user_agent_includes_activemerchant_version
assert @internal_gateway.config.user_agent.include?("(ActiveMerchant #{ActiveMerchant::VERSION})")
end
def test_merchant_account_id_present_when_provided_on_gateway_initialization
@gateway = BraintreeBlueGateway.new(
- :merchant_id => 'test',
- :merchant_account_id => 'present',
- :public_key => 'test',
- :private_key => 'test'
+ merchant_id: 'test',
+ merchant_account_id: 'present',
+ public_key: 'test',
+ private_key: 'test'
)
Braintree::TransactionGateway.any_instance.expects(:sale).
- with(has_entries(:merchant_account_id => 'present')).
+ with(has_entries(merchant_account_id: 'present')).
returns(braintree_result)
@gateway.authorize(100, credit_card('41111111111111111111'))
@@ -148,33 +191,69 @@ def test_merchant_account_id_present_when_provided_on_gateway_initialization
def test_merchant_account_id_on_transaction_takes_precedence
@gateway = BraintreeBlueGateway.new(
- :merchant_id => 'test',
- :merchant_account_id => 'present',
- :public_key => 'test',
- :private_key => 'test'
+ merchant_id: 'test',
+ merchant_account_id: 'present',
+ public_key: 'test',
+ private_key: 'test'
)
Braintree::TransactionGateway.any_instance.expects(:sale).
- with(has_entries(:merchant_account_id => 'account_on_transaction')).
+ with(has_entries(merchant_account_id: 'account_on_transaction')).
returns(braintree_result)
- @gateway.authorize(100, credit_card('41111111111111111111'), :merchant_account_id => 'account_on_transaction')
+ @gateway.authorize(100, credit_card('41111111111111111111'), merchant_account_id: 'account_on_transaction')
end
def test_merchant_account_id_present_when_provided
Braintree::TransactionGateway.any_instance.expects(:sale).
- with(has_entries(:merchant_account_id => 'present')).
+ with(has_entries(merchant_account_id: 'present')).
returns(braintree_result)
- @gateway.authorize(100, credit_card('41111111111111111111'), :merchant_account_id => 'present')
+ @gateway.authorize(100, credit_card('41111111111111111111'), merchant_account_id: 'present')
end
def test_service_fee_amount_can_be_specified
Braintree::TransactionGateway.any_instance.expects(:sale).
- with(has_entries(:service_fee_amount => '2.31')).
+ with(has_entries(service_fee_amount: '2.31')).
returns(braintree_result)
- @gateway.authorize(100, credit_card('41111111111111111111'), :service_fee_amount => '2.31')
+ @gateway.authorize(100, credit_card('41111111111111111111'), service_fee_amount: '2.31')
+ end
+
+ def test_venmo_profile_id_can_be_specified
+ Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
+ (params[:options][:venmo][:profile_id] == 'profile_id')
+ end.returns(braintree_result)
+
+ @gateway.authorize(100, credit_card('41111111111111111111'), venmo_profile_id: 'profile_id')
+ end
+
+ def test_customer_has_default_payment_method
+ options = {
+ payment_method_nonce: 'fake-paypal-future-nonce',
+ store: true,
+ device_data: 'device_data',
+ paypal: {
+ paypal_flow_type: 'checkout_with_vault'
+ }
+ }
+
+ Braintree::TransactionGateway.any_instance.expects(:sale).returns(braintree_result(paypal: { implicitly_vaulted_payment_method_token: 'abc123' }))
+
+ Braintree::CustomerGateway.any_instance.expects(:update).with(nil, { default_payment_method_token: 'abc123' }).returns(nil)
+
+ @gateway.authorize(100, 'fake-paypal-future-nonce', options)
+ end
+
+ def test_risk_data_can_be_specified
+ risk_data = {
+ customer_browser: 'User-Agent Header',
+ customer_ip: '127.0.0.1'
+ }
+ Braintree::TransactionGateway.any_instance.expects(:sale).
+ with(has_entries(risk_data: risk_data)).returns(braintree_result)
+
+ @gateway.authorize(100, credit_card('4111111111111111'), risk_data: risk_data)
end
def test_hold_in_escrow_can_be_specified
@@ -182,7 +261,16 @@ def test_hold_in_escrow_can_be_specified
(params[:options][:hold_in_escrow] == true)
end.returns(braintree_result)
- @gateway.authorize(100, credit_card('41111111111111111111'), :hold_in_escrow => true)
+ @gateway.authorize(100, credit_card('41111111111111111111'), hold_in_escrow: true)
+ end
+
+ def test_paypal_options_can_be_specified
+ Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
+ (params[:options][:paypal][:custom_field] == 'abc')
+ (params[:options][:paypal][:description] == 'shoes')
+ end.returns(braintree_result)
+
+ @gateway.authorize(100, credit_card('4111111111111111'), paypal_custom_field: 'abc', paypal_description: 'shoes')
end
def test_merchant_account_id_absent_if_not_provided
@@ -195,61 +283,61 @@ def test_merchant_account_id_absent_if_not_provided
def test_verification_merchant_account_id_exists_when_verify_card_and_merchant_account_id
gateway = BraintreeBlueGateway.new(
- :merchant_id => 'merchant_id',
- :merchant_account_id => 'merchant_account_id',
- :public_key => 'public_key',
- :private_key => 'private_key'
+ merchant_id: 'merchant_id',
+ merchant_account_id: 'merchant_account_id',
+ public_key: 'public_key',
+ private_key: 'private_key'
)
customer = stub(
- :credit_cards => [stub_everything],
- :email => 'email',
- :phone => '321-654-0987',
- :first_name => 'John',
- :last_name => 'Smith'
+ credit_cards: [stub_everything],
+ email: 'email',
+ phone: '321-654-0987',
+ first_name: 'John',
+ last_name: 'Smith'
)
customer.stubs(:id).returns('123')
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
params[:credit_card][:options][:verification_merchant_account_id] == 'merchant_account_id'
end.returns(result)
- gateway.store(credit_card('41111111111111111111'), :verify_card => true)
+ gateway.store(credit_card('41111111111111111111'), verify_card: true)
end
def test_merchant_account_id_can_be_set_by_options
gateway = BraintreeBlueGateway.new(
- :merchant_id => 'merchant_id',
- :merchant_account_id => 'merchant_account_id',
- :public_key => 'public_key',
- :private_key => 'private_key'
+ merchant_id: 'merchant_id',
+ merchant_account_id: 'merchant_account_id',
+ public_key: 'public_key',
+ private_key: 'private_key'
)
customer = stub(
- :credit_cards => [stub_everything],
- :email => 'email',
- :phone => '321-654-0987',
- :first_name => 'John',
- :last_name => 'Smith'
+ credit_cards: [stub_everything],
+ email: 'email',
+ phone: '321-654-0987',
+ first_name: 'John',
+ last_name: 'Smith'
)
customer.stubs(:id).returns('123')
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
params[:credit_card][:options][:verification_merchant_account_id] == 'value_from_options'
end.returns(result)
- gateway.store(credit_card('41111111111111111111'), :verify_card => true, :verification_merchant_account_id => 'value_from_options')
+ gateway.store(credit_card('41111111111111111111'), verify_card: true, verification_merchant_account_id: 'value_from_options')
end
def test_store_with_verify_card_true
customer = stub(
- :credit_cards => [stub_everything],
- :email => 'email',
- :phone => '321-654-0987',
- :first_name => 'John',
- :last_name => 'Smith'
+ credit_cards: [stub_everything],
+ email: 'email',
+ phone: '321-654-0987',
+ first_name: 'John',
+ last_name: 'Smith'
)
customer.stubs(:id).returns('123')
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
params[:credit_card][:options].has_key?(:verify_card)
assert_equal true, params[:credit_card][:options][:verify_card]
@@ -257,171 +345,171 @@ def test_store_with_verify_card_true
params
end.returns(result)
- response = @gateway.store(credit_card('41111111111111111111'), :verify_card => true)
+ response = @gateway.store(credit_card('41111111111111111111'), verify_card: true)
assert_equal '123', response.params['customer_vault_id']
assert_equal response.params['customer_vault_id'], response.authorization
end
def test_passes_email
customer = stub(
- :credit_cards => [stub_everything],
- :email => 'bob@example.com',
- :phone => '321-654-0987',
- :first_name => 'John',
- :last_name => 'Smith',
+ credit_cards: [stub_everything],
+ email: 'bob@example.com',
+ phone: '321-654-0987',
+ first_name: 'John',
+ last_name: 'Smith',
id: '123'
)
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
assert_equal 'bob@example.com', params[:email]
params
end.returns(result)
- response = @gateway.store(credit_card('41111111111111111111'), :email => 'bob@example.com')
+ response = @gateway.store(credit_card('41111111111111111111'), email: 'bob@example.com')
assert_success response
end
def test_scrubs_invalid_email
customer = stub(
- :credit_cards => [stub_everything],
- :email => nil,
- :phone => '321-654-0987',
- :first_name => 'John',
- :last_name => 'Smith',
- :id => '123'
+ credit_cards: [stub_everything],
+ email: nil,
+ phone: '321-654-0987',
+ first_name: 'John',
+ last_name: 'Smith',
+ id: '123'
)
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
assert_equal nil, params[:email]
params
end.returns(result)
- response = @gateway.store(credit_card('41111111111111111111'), :email => 'bogus')
+ response = @gateway.store(credit_card('41111111111111111111'), email: 'bogus')
assert_success response
end
def test_store_with_verify_card_false
customer = stub(
- :credit_cards => [stub_everything],
- :email => 'email',
- :phone => '321-654-0987',
- :first_name => 'John',
- :last_name => 'Smith'
+ credit_cards: [stub_everything],
+ email: 'email',
+ phone: '321-654-0987',
+ first_name: 'John',
+ last_name: 'Smith'
)
customer.stubs(:id).returns('123')
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
params[:credit_card][:options].has_key?(:verify_card)
assert_equal false, params[:credit_card][:options][:verify_card]
params
end.returns(result)
- response = @gateway.store(credit_card('41111111111111111111'), :verify_card => false)
+ response = @gateway.store(credit_card('41111111111111111111'), verify_card: false)
assert_equal '123', response.params['customer_vault_id']
assert_equal response.params['customer_vault_id'], response.authorization
end
def test_store_with_billing_address_options
customer_attributes = {
- :credit_cards => [stub_everything],
- :email => 'email',
- :phone => '321-654-0987',
- :first_name => 'John',
- :last_name => 'Smith'
+ credit_cards: [stub_everything],
+ email: 'email',
+ phone: '321-654-0987',
+ first_name: 'John',
+ last_name: 'Smith'
}
billing_address = {
- :address1 => '1 E Main St',
- :address2 => 'Suite 403',
- :city => 'Chicago',
- :state => 'Illinois',
- :zip => '60622',
- :country_name => 'US'
+ address1: '1 E Main St',
+ address2: 'Suite 403',
+ city: 'Chicago',
+ state: 'Illinois',
+ zip: '60622',
+ country_name: 'US'
}
customer = stub(customer_attributes)
customer.stubs(:id).returns('123')
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
assert_not_nil params[:credit_card][:billing_address]
- [:street_address, :extended_address, :locality, :region, :postal_code, :country_name].each do |billing_attribute|
+ %i[street_address extended_address locality region postal_code country_name].each do |billing_attribute|
params[:credit_card][:billing_address].has_key?(billing_attribute) if params[:billing_address]
end
params
end.returns(result)
- @gateway.store(credit_card('41111111111111111111'), :billing_address => billing_address)
+ @gateway.store(credit_card('41111111111111111111'), billing_address: billing_address)
end
def test_store_with_phone_only_billing_address_option
customer_attributes = {
- :credit_cards => [stub_everything],
- :email => 'email',
- :first_name => 'John',
- :last_name => 'Smith',
- :phone => '123-456-7890'
+ credit_cards: [stub_everything],
+ email: 'email',
+ first_name: 'John',
+ last_name: 'Smith',
+ phone: '123-456-7890'
}
billing_address = {
- :phone => '123-456-7890'
+ phone: '123-456-7890'
}
customer = stub(customer_attributes)
customer.stubs(:id).returns('123')
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
assert_nil params[:credit_card][:billing_address]
params
end.returns(result)
- @gateway.store(credit_card('41111111111111111111'), :billing_address => billing_address)
+ @gateway.store(credit_card('41111111111111111111'), billing_address: billing_address)
end
def test_store_with_nil_billing_address_options
customer_attributes = {
- :credit_cards => [stub_everything],
- :email => 'email',
- :first_name => 'John',
- :last_name => 'Smith',
- :phone => '123-456-7890'
+ credit_cards: [stub_everything],
+ email: 'email',
+ first_name: 'John',
+ last_name: 'Smith',
+ phone: '123-456-7890'
}
billing_address = {
- :name => 'John Smith',
- :phone => '123-456-7890',
- :company => nil,
- :address1 => nil,
- :address2 => '',
- :city => nil,
- :state => nil,
- :zip => nil,
- :country_name => nil
+ name: 'John Smith',
+ phone: '123-456-7890',
+ company: nil,
+ address1: nil,
+ address2: '',
+ city: nil,
+ state: nil,
+ zip: nil,
+ country_name: nil
}
customer = stub(customer_attributes)
customer.stubs(:id).returns('123')
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
assert_nil params[:credit_card][:billing_address]
params
end.returns(result)
- @gateway.store(credit_card('41111111111111111111'), :billing_address => billing_address)
+ @gateway.store(credit_card('41111111111111111111'), billing_address: billing_address)
end
def test_store_with_credit_card_token
customer = stub(
- :email => 'email',
- :phone => '321-654-0987',
- :first_name => 'John',
- :last_name => 'Smith'
+ email: 'email',
+ phone: '321-654-0987',
+ first_name: 'John',
+ last_name: 'Smith'
)
customer.stubs(:id).returns('123')
braintree_credit_card = stub_everything(token: 'cctoken')
customer.stubs(:credit_cards).returns([braintree_credit_card])
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:create).with do |params|
assert_equal 'cctoken', params[:credit_card][:token]
params
end.returns(result)
- response = @gateway.store(credit_card('41111111111111111111'), :credit_card_token => 'cctoken')
+ response = @gateway.store(credit_card('41111111111111111111'), credit_card_token: 'cctoken')
assert_success response
assert_equal 'cctoken', response.params['braintree_customer']['credit_cards'][0]['token']
assert_equal 'cctoken', response.params['credit_card_token']
@@ -429,15 +517,15 @@ def test_store_with_credit_card_token
def test_store_with_customer_id
customer = stub(
- :email => 'email',
- :phone => '321-654-0987',
- :first_name => 'John',
- :last_name => 'Smith',
- :credit_cards => [stub_everything]
+ email: 'email',
+ phone: '321-654-0987',
+ first_name: 'John',
+ last_name: 'Smith',
+ credit_cards: [stub_everything]
)
customer.stubs(:id).returns('customerid')
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:find).
with('customerid').
raises(Braintree::NotFoundError)
@@ -446,7 +534,7 @@ def test_store_with_customer_id
params
end.returns(result)
- response = @gateway.store(credit_card('41111111111111111111'), :customer => 'customerid')
+ response = @gateway.store(credit_card('41111111111111111111'), customer: 'customerid')
assert_success response
assert_equal 'customerid', response.params['braintree_customer']['id']
end
@@ -479,17 +567,17 @@ def test_store_with_existing_customer_id_and_nil_billing_address_options
token: 'cctoken'
)
options = {
- :customer => 'customerid',
- :billing_address => {
- :name => 'John Smith',
- :phone => '123-456-7890',
- :company => nil,
- :address1 => nil,
- :address2 => nil,
- :city => nil,
- :state => nil,
- :zip => nil,
- :country_name => nil
+ customer: 'customerid',
+ billing_address: {
+ name: 'John Smith',
+ phone: '123-456-7890',
+ company: nil,
+ address1: nil,
+ address2: nil,
+ city: nil,
+ state: nil,
+ zip: nil,
+ country_name: nil
}
}
@@ -510,88 +598,88 @@ def test_store_with_existing_customer_id_and_nil_billing_address_options
end
def test_update_with_cvv
- stored_credit_card = mock(:token => 'token', :default? => true)
- customer = mock(:credit_cards => [stored_credit_card], :id => '123')
+ stored_credit_card = mock(token: 'token', default?: true)
+ customer = mock(credit_cards: [stored_credit_card], id: '123')
Braintree::CustomerGateway.any_instance.stubs(:find).with('vault_id').returns(customer)
BraintreeBlueGateway.any_instance.stubs(:customer_hash)
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:update).with do |vault, params|
assert_equal '567', params[:credit_card][:cvv]
assert_equal 'Longbob Longsen', params[:credit_card][:cardholder_name]
[vault, params]
end.returns(result)
- @gateway.update('vault_id', credit_card('41111111111111111111', :verification_value => '567'))
+ @gateway.update('vault_id', credit_card('41111111111111111111', verification_value: '567'))
end
def test_update_with_verify_card_true
- stored_credit_card = stub(:token => 'token', :default? => true)
- customer = stub(:credit_cards => [stored_credit_card], :id => '123')
+ stored_credit_card = stub(token: 'token', default?: true)
+ customer = stub(credit_cards: [stored_credit_card], id: '123')
Braintree::CustomerGateway.any_instance.stubs(:find).with('vault_id').returns(customer)
BraintreeBlueGateway.any_instance.stubs(:customer_hash)
- result = Braintree::SuccessfulResult.new(:customer => customer)
+ result = Braintree::SuccessfulResult.new(customer: customer)
Braintree::CustomerGateway.any_instance.expects(:update).with do |vault, params|
assert_equal true, params[:credit_card][:options][:verify_card]
[vault, params]
end.returns(result)
- @gateway.update('vault_id', credit_card('41111111111111111111'), :verify_card => true)
+ @gateway.update('vault_id', credit_card('41111111111111111111'), verify_card: true)
end
def test_merge_credit_card_options_ignores_bad_option
- params = {:first_name => 'John', :credit_card => {:cvv => '123'}}
- options = {:verify_card => true, :bogus => 'ignore me'}
+ params = { first_name: 'John', credit_card: { cvv: '123' } }
+ options = { verify_card: true, bogus: 'ignore me' }
merged_params = @gateway.send(:merge_credit_card_options, params, options)
- expected_params = {:first_name => 'John', :credit_card => {:cvv => '123', :options => {:verify_card => true}}}
+ expected_params = { first_name: 'John', credit_card: { cvv: '123', options: { verify_card: true } } }
assert_equal expected_params, merged_params
end
def test_merge_credit_card_options_handles_nil_credit_card
- params = {:first_name => 'John'}
- options = {:verify_card => true, :bogus => 'ignore me'}
+ params = { first_name: 'John' }
+ options = { verify_card: true, bogus: 'ignore me' }
merged_params = @gateway.send(:merge_credit_card_options, params, options)
- expected_params = {:first_name => 'John', :credit_card => {:options => {:verify_card => true}}}
+ expected_params = { first_name: 'John', credit_card: { options: { verify_card: true } } }
assert_equal expected_params, merged_params
end
def test_merge_credit_card_options_handles_billing_address
billing_address = {
- :address1 => '1 E Main St',
- :city => 'Chicago',
- :state => 'Illinois',
- :zip => '60622',
- :country => 'US'
+ address1: '1 E Main St',
+ city: 'Chicago',
+ state: 'Illinois',
+ zip: '60622',
+ country: 'US'
}
- params = {:first_name => 'John'}
- options = {:billing_address => billing_address}
+ params = { first_name: 'John' }
+ options = { billing_address: billing_address }
expected_params = {
- :first_name => 'John',
- :credit_card => {
- :billing_address => {
- :street_address => '1 E Main St',
- :extended_address => nil,
- :company => nil,
- :locality => 'Chicago',
- :region => 'Illinois',
- :postal_code => '60622',
- :country_code_alpha2 => 'US',
- :country_code_alpha3 => 'USA'
+ first_name: 'John',
+ credit_card: {
+ billing_address: {
+ street_address: '1 E Main St',
+ extended_address: nil,
+ company: nil,
+ locality: 'Chicago',
+ region: 'Illinois',
+ postal_code: '60622',
+ country_code_alpha2: 'US',
+ country_code_alpha3: 'USA'
},
- :options => {}
+ options: {}
}
}
assert_equal expected_params, @gateway.send(:merge_credit_card_options, params, options)
end
def test_merge_credit_card_options_only_includes_billing_address_when_present
- params = {:first_name => 'John'}
+ params = { first_name: 'John' }
options = {}
expected_params = {
- :first_name => 'John',
- :credit_card => {
- :options => {}
+ first_name: 'John',
+ credit_card: {
+ options: {}
}
}
assert_equal expected_params, @gateway.send(:merge_credit_card_options, params, options)
@@ -601,78 +689,144 @@ def test_address_country_handling
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:billing][:country_code_alpha2] == 'US')
end.returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :billing_address => {:country => 'US'})
+ @gateway.purchase(100, credit_card('41111111111111111111'), billing_address: { country: 'US' })
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:billing][:country_code_alpha2] == 'US')
end.returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :billing_address => {:country_code_alpha2 => 'US'})
+ @gateway.purchase(100, credit_card('41111111111111111111'), billing_address: { country_code_alpha2: 'US' })
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:billing][:country_name] == 'United States of America')
end.returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :billing_address => {:country_name => 'United States of America'})
+ @gateway.purchase(100, credit_card('41111111111111111111'), billing_address: { country_name: 'United States of America' })
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:billing][:country_code_alpha3] == 'USA')
end.returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :billing_address => {:country_code_alpha3 => 'USA'})
+ @gateway.purchase(100, credit_card('41111111111111111111'), billing_address: { country_code_alpha3: 'USA' })
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:billing][:country_code_numeric] == 840)
end.returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :billing_address => {:country_code_numeric => 840})
+ @gateway.purchase(100, credit_card('41111111111111111111'), billing_address: { country_code_numeric: 840 })
end
def test_address_zip_handling
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:billing][:postal_code] == '12345')
end.returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :billing_address => {:zip => '12345'})
+ @gateway.purchase(100, credit_card('41111111111111111111'), billing_address: { zip: '12345' })
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:billing][:postal_code] == nil)
end.returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :billing_address => {:zip => '1234567890'})
+ @gateway.purchase(100, credit_card('41111111111111111111'), billing_address: { zip: '1234567890' })
end
def test_cardholder_name_passing_with_card
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:credit_card][:cardholder_name] == 'Longbob Longsen')
end.returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :customer => {:first_name => 'Longbob', :last_name => 'Longsen'})
+ @gateway.purchase(100, credit_card('41111111111111111111'), customer: { first_name: 'Longbob', last_name: 'Longsen' })
end
- def test_three_d_secure_pass_thru_handling
+ def test_three_d_secure_pass_thru_handling_version_1
Braintree::TransactionGateway.
any_instance.
expects(:sale).
with(has_entries(three_d_secure_pass_thru: {
cavv: 'cavv',
eci_flag: 'eci',
- xid: 'xid',
+ xid: 'xid'
})).
returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), three_d_secure: {cavv: 'cavv', eci: 'eci', xid: 'xid'})
+ @gateway.purchase(100, credit_card('41111111111111111111'), three_d_secure: { cavv: 'cavv', eci: 'eci', xid: 'xid' })
+ end
+
+ def test_three_d_secure_pass_thru_handling_version_2
+ three_ds_expectation = {
+ three_d_secure_version: '2.0',
+ cavv: 'cavv',
+ eci_flag: 'eci',
+ ds_transaction_id: 'trans_id',
+ cavv_algorithm: 'algorithm',
+ directory_response: 'directory',
+ authentication_response: 'auth'
+ }
+
+ Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
+ (params[:sca_exemption] == 'low_value')
+ (params[:three_d_secure_pass_thru] == three_ds_expectation)
+ end.returns(braintree_result)
+
+ options = {
+ three_ds_exemption_type: 'low_value',
+ three_d_secure: {
+ version: '2.0',
+ cavv: 'cavv',
+ eci: 'eci',
+ ds_transaction_id: 'trans_id',
+ cavv_algorithm: 'algorithm',
+ directory_response_status: 'directory',
+ authentication_response_status: 'auth'
+ }
+ }
+ @gateway.purchase(100, credit_card('41111111111111111111'), options)
+ end
+
+ def test_three_d_secure_pass_thru_some_fields
+ Braintree::TransactionGateway.
+ any_instance.
+ expects(:sale).
+ with(has_entries(three_d_secure_pass_thru: has_entries(
+ three_d_secure_version: '2.0',
+ cavv: 'cavv',
+ eci_flag: 'eci',
+ ds_transaction_id: 'trans_id'
+ ))).
+ returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), three_d_secure: { version: '2.0', cavv: 'cavv', eci: 'eci', ds_transaction_id: 'trans_id' })
+ end
+
+ def test_purchase_string_based_payment_method_nonce_removes_customer
+ Braintree::TransactionGateway.
+ any_instance.
+ expects(:sale).
+ with(Not(has_key(:customer))).
+ returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), payment_method_nonce: '1234')
+ end
+
+ def test_authorize_string_based_payment_method_nonce_removes_customer
+ Braintree::TransactionGateway.
+ any_instance.
+ expects(:sale).
+ with(Not(has_key(:customer))).
+ returns(braintree_result)
+
+ @gateway.authorize(100, credit_card('41111111111111111111'), payment_method_nonce: '1234')
end
def test_passes_recurring_flag
@gateway = BraintreeBlueGateway.new(
- :merchant_id => 'test',
- :merchant_account_id => 'present',
- :public_key => 'test',
- :private_key => 'test'
+ merchant_id: 'test',
+ merchant_account_id: 'present',
+ public_key: 'test',
+ private_key: 'test'
)
Braintree::TransactionGateway.any_instance.expects(:sale).
- with(has_entries(:recurring => true)).
+ with(has_entries(transaction_source: 'recurring')).
returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :recurring => true)
+ @gateway.purchase(100, credit_card('41111111111111111111'), recurring: true)
Braintree::TransactionGateway.any_instance.expects(:sale).
- with(Not(has_entries(:recurring => true))).
+ with(Not(has_entries(recurring: true))).
returns(braintree_result)
@gateway.purchase(100, credit_card('41111111111111111111'))
@@ -680,10 +834,35 @@ def test_passes_recurring_flag
def test_passes_transaction_source
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
- (params[:transaction_source] == 'recurring')
- (params[:recurring] == nil)
+ (params[:transaction_source] == 'recurring') && (params[:recurring] == nil)
+ end.returns(braintree_result)
+ @gateway.purchase(100, credit_card('41111111111111111111'), transaction_source: 'recurring', recurring: true)
+ end
+
+ def test_passes_skip_avs
+ Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
+ (params[:options][:skip_avs] == true)
+ end.returns(braintree_result(avs_postal_code_response_code: 'B', avs_street_address_response_code: 'B'))
+
+ response = @gateway.purchase(100, credit_card('41111111111111111111'), skip_avs: true)
+ assert_equal 'B', response.avs_result['code']
+ end
+
+ def test_passes_skip_cvv
+ Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
+ (params[:options][:skip_cvv] == true)
+ end.returns(braintree_result(cvv_response_code: 'B'))
+
+ response = @gateway.purchase(100, credit_card('41111111111111111111'), skip_cvv: true)
+ assert_equal 'B', response.cvv_result['code']
+ end
+
+ def test_successful_purchase_with_account_type
+ Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
+ params[:options][:credit_card][:account_type] == 'credit'
end.returns(braintree_result)
- @gateway.purchase(100, credit_card('41111111111111111111'), :transaction_source => 'recurring', :recurring => true)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), account_type: 'credit')
end
def test_configured_logger_has_a_default
@@ -704,9 +883,9 @@ def test_default_logger_sets_warn_level_without_overwriting_global
# Re-instantiate a gateway to show it doesn't touch the global
gateway = BraintreeBlueGateway.new(
- :merchant_id => 'test',
- :public_key => 'test',
- :private_key => 'test'
+ merchant_id: 'test',
+ public_key: 'test',
+ private_key: 'test'
)
internal_gateway = gateway.instance_variable_get(:@braintree_gateway)
@@ -723,9 +902,9 @@ def test_that_setting_a_wiredump_device_on_the_gateway_sets_the_braintree_logger
assert_not_equal logger, Braintree::Configuration.logger
gateway = BraintreeBlueGateway.new(
- :merchant_id => 'test',
- :public_key => 'test',
- :private_key => 'test'
+ merchant_id: 'test',
+ public_key: 'test',
+ private_key: 'test'
)
internal_gateway = gateway.instance_variable_get(:@braintree_gateway)
@@ -739,7 +918,7 @@ def test_solution_id_is_added_to_create_transaction_parameters
ActiveMerchant::Billing::BraintreeBlueGateway.application_id = 'ABC123'
assert_equal @gateway.send(:create_transaction_parameters, 100, credit_card('41111111111111111111'), {})[:channel], 'ABC123'
- gateway = BraintreeBlueGateway.new(:merchant_id => 'test', :public_key => 'test', :private_key => 'test', channel: 'overidden-channel')
+ gateway = BraintreeBlueGateway.new(merchant_id: 'test', public_key: 'test', private_key: 'test', channel: 'overidden-channel')
assert_equal gateway.send(:create_transaction_parameters, 100, credit_card('41111111111111111111'), {})[:channel], 'overidden-channel'
ensure
ActiveMerchant::Billing::BraintreeBlueGateway.application_id = nil
@@ -748,8 +927,8 @@ def test_solution_id_is_added_to_create_transaction_parameters
def test_successful_purchase_with_descriptor
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:descriptor][:name] == 'wow*productname') &&
- (params[:descriptor][:phone] == '4443331112') &&
- (params[:descriptor][:url] == 'wow.com')
+ (params[:descriptor][:phone] == '4443331112') &&
+ (params[:descriptor][:url] == 'wow.com')
end.returns(braintree_result)
@gateway.purchase(100, credit_card('41111111111111111111'), descriptor_name: 'wow*productname', descriptor_phone: '4443331112', descriptor_url: 'wow.com')
end
@@ -757,7 +936,7 @@ def test_successful_purchase_with_descriptor
def test_successful_purchase_with_device_data
Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
(params[:device_data] == 'device data string')
- end.returns(braintree_result({risk_data: {id: 123456, decision: 'Decline', device_data_captured: true, fraud_service_provider: 'kount'}}))
+ end.returns(braintree_result({ risk_data: { id: 123456, decision: 'Decline', device_data_captured: true, fraud_service_provider: 'kount' } }))
response = @gateway.purchase(100, credit_card('41111111111111111111'), device_data: 'device data string')
@@ -769,102 +948,146 @@ def test_successful_purchase_with_device_data
assert_equal 'kount', transaction['risk_data']['fraud_service_provider']
end
+ def test_successful_purchase_with_travel_data
+ Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
+ (params[:industry][:industry_type] == Braintree::Transaction::IndustryType::TravelAndCruise) &&
+ (params[:industry][:data][:travel_package] == 'flight') &&
+ (params[:industry][:data][:departure_date] == '2050-07-22') &&
+ (params[:industry][:data][:lodging_check_in_date] == '2050-07-22') &&
+ (params[:industry][:data][:lodging_check_out_date] == '2050-07-25') &&
+ (params[:industry][:data][:lodging_name] == 'Best Hotel Ever')
+ end.returns(braintree_result)
+
+ @gateway.purchase(
+ 100,
+ credit_card('41111111111111111111'),
+ travel_data: {
+ travel_package: 'flight',
+ departure_date: '2050-07-22',
+ lodging_check_in_date: '2050-07-22',
+ lodging_check_out_date: '2050-07-25',
+ lodging_name: 'Best Hotel Ever'
+ }
+ )
+ end
+
+ def test_successful_purchase_with_lodging_data
+ Braintree::TransactionGateway.any_instance.expects(:sale).with do |params|
+ (params[:industry][:industry_type] == Braintree::Transaction::IndustryType::Lodging) &&
+ (params[:industry][:data][:folio_number] == 'ABC123') &&
+ (params[:industry][:data][:check_in_date] == '2050-12-22') &&
+ (params[:industry][:data][:check_out_date] == '2050-12-25') &&
+ (params[:industry][:data][:room_rate] == '80.00')
+ end.returns(braintree_result)
+
+ @gateway.purchase(
+ 100,
+ credit_card('41111111111111111111'),
+ lodging_data: {
+ folio_number: 'ABC123',
+ check_in_date: '2050-12-22',
+ check_out_date: '2050-12-25',
+ room_rate: '80.00'
+ }
+ )
+ end
+
def test_apple_pay_card
Braintree::TransactionGateway.any_instance.expects(:sale).
with(
- :amount => '1.00',
- :order_id => '1',
- :customer => {:id => nil, :email => nil, :phone => nil,
- :first_name => 'Longbob', :last_name => 'Longsen'},
- :options => {:store_in_vault => false, :submit_for_settlement => nil, :hold_in_escrow => nil},
- :custom_fields => nil,
- :apple_pay_card => {
- :number => '4111111111111111',
- :expiration_month => '09',
- :expiration_year => (Time.now.year + 1).to_s,
- :cardholder_name => 'Longbob Longsen',
- :cryptogram => '111111111100cryptogram',
- :eci_indicator => '05'
+ amount: '1.00',
+ order_id: '1',
+ customer: { id: nil, email: nil, phone: nil,
+ first_name: 'Longbob', last_name: 'Longsen' },
+ options: { store_in_vault: false, submit_for_settlement: nil, hold_in_escrow: nil },
+ custom_fields: nil,
+ apple_pay_card: {
+ number: '4111111111111111',
+ expiration_month: '09',
+ expiration_year: (Time.now.year + 1).to_s,
+ cardholder_name: 'Longbob Longsen',
+ cryptogram: '111111111100cryptogram',
+ eci_indicator: '05'
}
).
- returns(braintree_result(:id => 'transaction_id'))
-
- credit_card = network_tokenization_credit_card('4111111111111111',
- :brand => 'visa',
- :transaction_id => '123',
- :eci => '05',
- :payment_cryptogram => '111111111100cryptogram'
+ returns(braintree_result(id: 'transaction_id'))
+
+ credit_card = network_tokenization_credit_card(
+ '4111111111111111',
+ brand: 'visa',
+ transaction_id: '123',
+ eci: '05',
+ payment_cryptogram: '111111111100cryptogram'
)
- response = @gateway.authorize(100, credit_card, :test => true, :order_id => '1')
+ response = @gateway.authorize(100, credit_card, test: true, order_id: '1')
assert_equal 'transaction_id', response.authorization
end
- def test_android_pay_card
+ def test_google_pay_card
Braintree::TransactionGateway.any_instance.expects(:sale).
with(
- :amount => '1.00',
- :order_id => '1',
- :customer => {:id => nil, :email => nil, :phone => nil,
- :first_name => 'Longbob', :last_name => 'Longsen'},
- :options => {:store_in_vault => false, :submit_for_settlement => nil, :hold_in_escrow => nil},
- :custom_fields => nil,
- :android_pay_card => {
- :number => '4111111111111111',
- :expiration_month => '09',
- :expiration_year => (Time.now.year + 1).to_s,
- :cryptogram => '111111111100cryptogram',
- :google_transaction_id => '1234567890',
- :source_card_type => 'visa',
- :source_card_last_four => '1111',
- :eci_indicator => '05'
+ amount: '1.00',
+ order_id: '1',
+ customer: { id: nil, email: nil, phone: nil,
+ first_name: 'Longbob', last_name: 'Longsen' },
+ options: { store_in_vault: false, submit_for_settlement: nil, hold_in_escrow: nil },
+ custom_fields: nil,
+ google_pay_card: {
+ number: '4111111111111111',
+ expiration_month: '09',
+ expiration_year: (Time.now.year + 1).to_s,
+ cryptogram: '111111111100cryptogram',
+ google_transaction_id: '1234567890',
+ source_card_type: 'visa',
+ source_card_last_four: '1111',
+ eci_indicator: '05'
}
).
- returns(braintree_result(:id => 'transaction_id'))
-
- credit_card = network_tokenization_credit_card('4111111111111111',
- :brand => 'visa',
- :eci => '05',
- :payment_cryptogram => '111111111100cryptogram',
- :source => :android_pay,
- :transaction_id => '1234567890'
+ returns(braintree_result(id: 'transaction_id'))
+
+ credit_card = network_tokenization_credit_card(
+ '4111111111111111',
+ brand: 'visa',
+ eci: '05',
+ payment_cryptogram: '111111111100cryptogram',
+ source: :google_pay,
+ transaction_id: '1234567890'
)
- response = @gateway.authorize(100, credit_card, :test => true, :order_id => '1')
+ response = @gateway.authorize(100, credit_card, test: true, order_id: '1')
assert_equal 'transaction_id', response.authorization
end
- def test_google_pay_card
+ def test_network_token_card
Braintree::TransactionGateway.any_instance.expects(:sale).
with(
- :amount => '1.00',
- :order_id => '1',
- :customer => {:id => nil, :email => nil, :phone => nil,
- :first_name => 'Longbob', :last_name => 'Longsen'},
- :options => {:store_in_vault => false, :submit_for_settlement => nil, :hold_in_escrow => nil},
- :custom_fields => nil,
- :android_pay_card => {
- :number => '4111111111111111',
- :expiration_month => '09',
- :expiration_year => (Time.now.year + 1).to_s,
- :cryptogram => '111111111100cryptogram',
- :google_transaction_id => '1234567890',
- :source_card_type => 'visa',
- :source_card_last_four => '1111',
- :eci_indicator => '05'
+ amount: '1.00',
+ order_id: '1',
+ customer: { id: nil, email: nil, phone: nil,
+ first_name: 'Longbob', last_name: 'Longsen' },
+ options: { store_in_vault: false, submit_for_settlement: nil, hold_in_escrow: nil },
+ custom_fields: nil,
+ credit_card: {
+ number: '4111111111111111',
+ expiration_month: '09',
+ expiration_year: (Time.now.year + 1).to_s,
+ cardholder_name: 'Longbob Longsen',
+ network_tokenization_attributes: {
+ cryptogram: '111111111100cryptogram',
+ ecommerce_indicator: '05'
+ }
}
).
- returns(braintree_result(:id => 'transaction_id'))
+ returns(braintree_result(id: 'transaction_id'))
credit_card = network_tokenization_credit_card('4111111111111111',
- :brand => 'visa',
- :eci => '05',
- :payment_cryptogram => '111111111100cryptogram',
- :source => :google_pay,
- :transaction_id => '1234567890'
- )
+ brand: 'visa',
+ eci: '05',
+ source: :network_token,
+ payment_cryptogram: '111111111100cryptogram')
- response = @gateway.authorize(100, credit_card, :test => true, :order_id => '1')
+ response = @gateway.authorize(100, credit_card, test: true, order_id: '1')
assert_equal 'transaction_id', response.authorization
end
@@ -873,7 +1096,7 @@ def test_supports_network_tokenization
end
def test_unsuccessful_transaction_returns_id_when_available
- Braintree::TransactionGateway.any_instance.expects(:sale).returns(braintree_error_result(transaction: {id: 'transaction_id'}))
+ Braintree::TransactionGateway.any_instance.expects(:sale).returns(braintree_error_result(transaction: { id: 'transaction_id' }))
assert response = @gateway.purchase(100, credit_card('41111111111111111111'))
refute response.success?
assert response.authorization.present?
@@ -914,14 +1137,287 @@ def test_refund_unsettled_payment_forces_void_on_full_refund
assert response.success?
end
+ def test_refund_unsettled_payment_other_error_does_not_void
+ Braintree::TransactionGateway.any_instance.
+ expects(:refund).
+ returns(braintree_error_result(message: 'Some error message'))
+
+ Braintree::TransactionGateway.any_instance.
+ expects(:void).
+ never
+
+ response = @gateway.refund(1.00, 'transaction_id', force_full_refund_if_unsettled: true)
+ refute response.success?
+ end
+
+ def test_stored_credential_recurring_cit_initial
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'will_vault'
+ },
+ transaction_source: ''
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:cardholder, :recurring, :initial) })
+ end
+
+ def test_stored_credential_recurring_cit_used
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'vaulted',
+ previous_network_transaction_id: '123ABC'
+ },
+ transaction_source: ''
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:cardholder, :recurring, id: '123ABC') })
+ end
+
+ def test_stored_credential_recurring_mit_initial
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'will_vault'
+ },
+ transaction_source: 'recurring'
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:merchant, :recurring, :initial) })
+ end
+
+ def test_stored_credential_recurring_mit_used
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'vaulted',
+ previous_network_transaction_id: '123ABC'
+ },
+ transaction_source: 'recurring'
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:merchant, :recurring, id: '123ABC') })
+ end
+
+ def test_stored_credential_installment_cit_initial
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'will_vault'
+ },
+ transaction_source: ''
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:cardholder, :installment, :initial) })
+ end
+
+ def test_stored_credential_installment_cit_used
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'vaulted',
+ previous_network_transaction_id: '123ABC'
+ },
+ transaction_source: ''
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:cardholder, :installment, id: '123ABC') })
+ end
+
+ def test_stored_credential_installment_mit_initial
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'will_vault'
+ },
+ transaction_source: 'recurring'
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:merchant, :installment, :initial) })
+ end
+
+ def test_stored_credential_installment_mit_used
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'vaulted',
+ previous_network_transaction_id: '123ABC'
+ },
+ transaction_source: 'recurring'
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:merchant, :installment, id: '123ABC') })
+ end
+
+ def test_stored_credential_unscheduled_cit_initial
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'will_vault'
+ },
+ transaction_source: ''
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:cardholder, :unscheduled, :initial) })
+ end
+
+ def test_stored_credential_unscheduled_cit_used
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'vaulted',
+ previous_network_transaction_id: '123ABC'
+ },
+ transaction_source: ''
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:cardholder, :unscheduled, id: '123ABC') })
+ end
+
+ def test_stored_credential_unscheduled_mit_initial
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'will_vault'
+ },
+ transaction_source: 'unscheduled'
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:merchant, :unscheduled, :initial) })
+ end
+
+ def test_stored_credential_unscheduled_mit_used
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'vaulted',
+ previous_network_transaction_id: '123ABC'
+ },
+ transaction_source: 'unscheduled'
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:merchant, :unscheduled, id: '123ABC') })
+ end
+
+ def test_stored_credential_recurring_first_cit_initial
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'will_vault'
+ },
+ transaction_source: 'recurring_first'
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: { initiator: 'merchant', reason_type: 'recurring_first', initial_transaction: true } })
+ end
+
+ def test_stored_credential_moto_cit_initial
+ Braintree::TransactionGateway.any_instance.expects(:sale).with(
+ standard_purchase_params.merge(
+ {
+ external_vault: {
+ status: 'will_vault'
+ },
+ transaction_source: 'moto'
+ }
+ )
+ ).returns(braintree_result)
+
+ @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: { initiator: 'merchant', reason_type: 'moto', initial_transaction: true } })
+ end
+
+ def test_raises_exeption_when_adding_bank_account_to_customer_without_billing_address
+ bank_account = check({ account_number: '1000000002', routing_number: '011000015' })
+
+ err = @gateway.store(bank_account, { customer: 'abc123' })
+ assert_equal 'billing_address is required parameter to store and verify Bank accounts.', err.message
+ end
+
+ def test_returns_error_on_authorize_when_passing_a_bank_account
+ bank_account = check({ account_number: '1000000002', routing_number: '011000015' })
+ response = @gateway.authorize(100, bank_account, {})
+
+ assert_failure response
+ assert_equal 'Direct bank account transactions are not supported. Bank accounts must be successfully stored before use.', response.message
+ end
+
+ def test_returns_error_on_general_credit_when_passing_a_bank_account
+ bank_account = check({ account_number: '1000000002', routing_number: '011000015' })
+ response = @gateway.credit(100, bank_account, {})
+
+ assert_failure response
+ assert_equal 'Direct bank account transactions are not supported. Bank accounts must be successfully stored before use.', response.message
+ end
+
+ def test_error_on_store_bank_account_without_a_mandate
+ options = {
+ billing_address: {
+ address1: '1670',
+ address2: '1670 NW 82ND AVE',
+ city: 'Miami',
+ state: 'FL',
+ zip: '32191'
+ }
+ }
+ bank_account = check({ account_number: '1000000002', routing_number: '011000015' })
+ response = @gateway.store(bank_account, options)
+
+ assert_failure response
+ assert_match(/ach_mandate is a required parameter to process/, response.message)
+ end
+
+ def test_scrub_sensitive_data
+ assert_equal filtered_success_token_nonce, @gateway.scrub(success_create_token_nonce)
+ end
+
private
def braintree_result(options = {})
- Braintree::SuccessfulResult.new(:transaction => Braintree::Transaction._new(nil, {:id => 'transaction_id'}.merge(options)))
+ Braintree::SuccessfulResult.new(transaction: Braintree::Transaction._new(nil, { id: 'transaction_id' }.merge(options)))
end
def braintree_error_result(options = {})
- Braintree::ErrorResult.new(@internal_gateway, {errors: {}}.merge(options))
+ Braintree::ErrorResult.new(@internal_gateway, { errors: {} }.merge(options))
end
def with_braintree_configuration_restoration(&block)
@@ -936,4 +1432,156 @@ def with_braintree_configuration_restoration(&block)
# Reset the Braintree logger
Braintree::Configuration.logger = nil
end
+
+ def standard_purchase_params
+ {
+ amount: '1.00',
+ order_id: '1',
+ customer: { id: nil, email: nil, phone: nil,
+ first_name: 'Longbob', last_name: 'Longsen' },
+ options: { store_in_vault: false, submit_for_settlement: true, hold_in_escrow: nil },
+ custom_fields: nil,
+ credit_card: {
+ number: '41111111111111111111',
+ cvv: '123',
+ expiration_month: '09',
+ expiration_year: (Time.now.year + 1).to_s,
+ cardholder_name: 'Longbob Longsen'
+ }
+ }
+ end
+
+ def success_create_token_nonce
+ <<-RESPONSE
+ [Braintree]
+ [Braintree] 673970040
+ [Braintree] tokenusbankacct_bc_tbf5zn_6xtcs8_wmknct_y3yfy5_sg6
+ [Braintree]
+ [Braintree] network_check
+ [Braintree]
+ [Braintree]
+ [Braintree]
+ [Braintree] eyJ2ZXJzaW9uIjoyLCJhdXRob3JpemF0aW9uRmluZ2VycHJpbnQiOiJleUowZVhBaU9pSktWMVFpTENKaGJHY2lPaUpGVXpJMU5pSXNJbXRwWkNJNklqSXdNVGd3TkRJMk1UWXRjMkZ1WkdKdmVDSXNJbWx6Y3lJNkltaDBkSEJ6T2k4dllYQnBMbk5oYm1SaWIzZ3VZbkpoYVc1MGNtVmxaMkYwWlhkaGVTNWpiMjBpZlEuZXlKbGVIQWlPakUyTkRNeE5EazFNVEFzSW1wMGFTSTZJbVJpTkRJME1XRmpMVGMwTkdVdE5EWmpOQzFoTjJWakxUbGlNakpoWm1KaFl6QmxZU0lzSW5OMVlpSTZJbXRrTm5SaVkydGpaR1JtTm5sMlpHY2lMQ0pwYzNNaU9pSm9kSFJ3Y3pvdkwyRndhUzV6WVc1a1ltOTRMbUp5WVdsdWRISmxaV2RoZEdWM1lYa3VZMjl0SWl3aWJXVnlZMmhoYm5RaU9uc2ljSFZpYkdsalgybGtJam9pYTJRMmRHSmphMk5rWkdZMmVYWmtaeUlzSW5abGNtbG1lVjlqWVhKa1gySjVYMlJsWm1GMWJIUWlPblJ5ZFdWOUxDSnlhV2RvZEhNaU9sc2liV0Z1WVdkbFgzWmhkV3gwSWwwc0luTmpiM0JsSWpwYklrSnlZV2x1ZEhKbFpUcFdZWFZzZENKZExDSnZjSFJwYjI1eklqcDdmWDAuYnpKRUFZWWxSenhmOUJfNGJvN1JrUlZaMERtR1pEVFRieDVQWWxXdFNCSjhnc19pT3RTQ0MtWHRYcEM3NE5pV1A5a0g0MG9neWVKVzZaNkpTbnNOTGciLCJjb25maWdVcmwiOiJodHRwczovL2FwaS5zYW5kYm94LmJyYWludHJlZWdhdGV3YXkuY29tOjQ0My9tZXJjaGFudHMva2Q2dGJja2NkZGY2eXZkZy9jbGllbnRfYXBpL3YxL2NvbmZpZ3VyYXRpb24iLCJncmFwaFFMIjp7InVybCI6Imh0dHBzOi8vcGF5bWVudHMuc2FuZGJveC5icmFpbnRyZWUtYXBpLmNvbS9ncmFwaHFsIiwiZGF0ZSI6IjIwMTgtMDUtMDgiLCJmZWF0dXJlcyI6WyJ0b2tlbml6ZV9jcmVkaXRfY2FyZHMiXX0sImNsaWVudEFwaVVybCI6Imh0dHBzOi8vYXBpLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb206NDQzL21lcmNoYW50cy9rZDZ0YmNrY2RkZjZ5dmRnL2NsaWVudF9hcGkiLCJlbnZpcm9ubWVudCI6InNhbmRib3giLCJtZXJjaGFudElkIjoia2Q2dGJja2NkZGY2eXZkZyIsImFzc2V0c1VybCI6Imh0dHBzOi8vYXNzZXRzLmJyYWludHJlZWdhdGV3YXkuY29tIiwiYXV0aFVybCI6Imh0dHBzOi8vYXV0aC52ZW5tby5zYW5kYm94LmJyYWludHJlZWdhdGV3YXkuY29tIiwidmVubW8iOiJvZmYiLCJjaGFsbGVuZ2VzIjpbXSwidGhyZWVEU2VjdXJlRW5hYmxlZCI6dHJ1ZSwiYW5hbHl0aWNzIjp7InVybCI6Imh0dHBzOi8vb3JpZ2luLWFuYWx5dGljcy1zYW5kLnNhbmRib3guYnJhaW50cmVlLWFwaS5jb20va2Q2dGJja2NkZGY2eXZkZyJ9LCJwYXlwYWxFbmFibGVkIjp0cnVlLCJicmFpbnRyZWVfYXBpIjp7InVybCI6Imh0dHBzOi8vcGF5bWVudHMuc2FuZGJveC5icmFpbnRyZWUtYXBpLmNvbSIsImFjY2Vzc190b2tlbiI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSkZVekkxTmlJc0ltdHBaQ0k2SWpJd01UZ3dOREkyTVRZdGMyRnVaR0p2ZUNJc0ltbHpjeUk2SW1oMGRIQnpPaTh2WVhCcExuTmhibVJpYjNndVluSmhhVzUwY21WbFoyRjBaWGRoZVM1amIyMGlmUS5leUpsZUhBaU9qRTJORE14TkRrMU1UQXNJbXAwYVNJNklqRmhNMkpqTm1OaExUY3hNalV0TkdKaU5TMWlOMk5tTFdReU5HUTNNMlEyWWpJd01TSXNJbk4xWWlJNkltdGtOblJpWTJ0alpHUm1ObmwyWkdjaUxDSnBjM01pT2lKb2RIUndjem92TDJGd2FTNXpZVzVrWW05NExtSnlZV2x1ZEhKbFpXZGhkR1YzWVhrdVkyOXRJaXdpYldWeVkyaGhiblFpT25zaWNIVmliR2xqWDJsa0lqb2lhMlEyZEdKamEyTmtaR1kyZVhaa1p5SXNJblpsY21sbWVWOWpZWEprWDJKNVgyUmxabUYxYkhRaU9uUnlkV1Y5TENKeWFXZG9kSE1pT2xzaWRHOXJaVzVwZW1VaUxDSnRZVzVoWjJWZmRtRjFiSFFpWFN3aWMyTnZjR1VpT2xzaVFuSmhhVzUwY21WbE9sWmhkV3gwSWwwc0ltOXdkR2x2Ym5NaU9udDlmUS52ZGtCVFVpOGtPdm1lSUVvdjRYMFBtVmpuLVFER2JNSWhyQ3JmVkpRcUIxVG5GSVYySkx3U2RxYlFXXzN6R2RIcUl6WkVzVEtQdXNxRF9nWUhwR2xjdyJ9LCJwYXlwYWwiOnsiYmlsbGluZ0FncmVlbWVudHNFbmFibGVkIjp0cnVlLCJlbnZpcm9ubWVudE5vTmV0d29yayI6dHJ1ZSwidW52ZXR0ZWRNZXJjaGFudCI6ZmFsc2UsImFsbG93SHR0cCI6dHJ1ZSwiZGlzcGxheU5hbWUiOiJlbmRhdmEiLCJjbGllbnRJZCI6bnVsbCwicHJpdmFjeVVybCI6Imh0dHA6Ly9leGFtcGxlLmNvbS9wcCIsInVzZXJBZ3JlZW1lbnRVcmwiOiJodHRwOi8vZXhhbXBsZS5jb20vdG9zIiwiYmFzZVVybCI6Imh0dHBzOi8vYXNzZXRzLmJyYWludHJlZWdhdGV3YXkuY29tIiwiYXNzZXRzVXJsIjoiaHR0cHM6Ly9jaGVja291dC5wYXlwYWwuY29tIiwiZGlyZWN0QmFzZVVybCI6bnVsbCwiZW52aXJvbm1lbnQiOiJvZmZsaW5lIiwiYnJhaW50cmVlQ2xpZW50SWQiOiJtYXN0ZXJjbGllbnQzIiwibWVyY2hhbnRBY2NvdW50SWQiOiJlbmRhdmEiLCJjdXJyZW5jeUlzb0NvZGUiOiJVU0QifX0=
+ [Braintree]
+ [Braintree]
+ [Braintree] 011000015
+ [Braintree] 0000
+ [Braintree] checking
+ [Braintree] Jon Doe
+ [Braintree] FEDERAL RESERVE BANK
+ [Braintree]
+ [Braintree] 2022-01-24T22:25:11Z
+ [Braintree] By clicking ["Checkout"], I authorize Braintree, a service of PayPal, on behalf of [your business name here] (i) to verify my bank account information using bank information and consumer reports and (ii) to debit my bank account.
+ [Braintree]
+ [Braintree] personal
+ [Braintree] true
+ [Braintree] 1000000000
+ [Braintree]
+ [Braintree] true
+ [Braintree]
+ [Braintree] Jon
+ [Braintree] Doe
+ [Braintree] true
+ [Braintree] 9dkrvzg
+ [Braintree] 673970040
+ [Braintree] Y3VzdG9tZXJfNjczOTcwMDQw
+ [Braintree] https://assets.braintreegateway.com/payment_method_logo/us_bank_account.png?environment=sandbox
+ [Braintree]
+ [Braintree]
+ [Braintree] verified
+ [Braintree]
+ [Braintree] endava
+ [Braintree] 1000
+ [Braintree] Approved
+ [Braintree] d4gaqtek
+ [Braintree] network_check
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree]
+ [Braintree] 9dkrvzg
+ [Braintree] 0000
+ [Braintree] checking
+ [Braintree] Jon Doe
+ [Braintree] FEDERAL RESERVE BANK
+ [Braintree] 011000015
+ [Braintree] true
+ [Braintree] personal
+ [Braintree]
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree] dXNiYW5rYWNjb3VudHZlcmlmaWNhdGlvbl9kNGdhcXRlaw
+ [Braintree]
+ [Braintree]
+ [Braintree] cGF5bWVudG1ldGhvZF91c2JfOWRrcnZ6Zw
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree]
+ RESPONSE
+ end
+
+ def filtered_success_token_nonce
+ <<-RESPONSE
+ [Braintree]
+ [Braintree] 673970040
+ [Braintree] [FILTERED]
+ [Braintree]
+ [Braintree] network_check
+ [Braintree]
+ [Braintree]
+ [Braintree]
+ [Braintree] [FILTERED]
+ [Braintree]
+ [Braintree]
+ [Braintree] 011000015
+ [Braintree] 0000
+ [Braintree] checking
+ [Braintree] Jon Doe
+ [Braintree] FEDERAL RESERVE BANK
+ [Braintree]
+ [Braintree] 2022-01-24T22:25:11Z
+ [Braintree] By clicking ["Checkout"], I authorize Braintree, a service of PayPal, on behalf of [your business name here] (i) to verify my bank account information using bank information and consumer reports and (ii) to debit my bank account.
+ [Braintree]
+ [Braintree] personal
+ [Braintree] true
+ [Braintree] [FILTERED]
+ [Braintree]
+ [Braintree] true
+ [Braintree]
+ [Braintree] Jon
+ [Braintree] Doe
+ [Braintree] true
+ [Braintree] [FILTERED]
+ [Braintree] 673970040
+ [Braintree] Y3VzdG9tZXJfNjczOTcwMDQw
+ [Braintree] https://assets.braintreegateway.com/payment_method_logo/us_bank_account.png?environment=sandbox
+ [Braintree]
+ [Braintree]
+ [Braintree] verified
+ [Braintree]
+ [Braintree] endava
+ [Braintree] 1000
+ [Braintree] Approved
+ [Braintree] d4gaqtek
+ [Braintree] network_check
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree]
+ [Braintree] [FILTERED]
+ [Braintree] 0000
+ [Braintree] checking
+ [Braintree] Jon Doe
+ [Braintree] FEDERAL RESERVE BANK
+ [Braintree] 011000015
+ [Braintree] true
+ [Braintree] personal
+ [Braintree]
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree] dXNiYW5rYWNjb3VudHZlcmlmaWNhdGlvbl9kNGdhcXRlaw
+ [Braintree]
+ [Braintree]
+ [Braintree] cGF5bWVudG1ldGhvZF91c2JfOWRrcnZ6Zw
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree] 2022-01-24T22:25:12Z
+ [Braintree]
+ RESPONSE
+ end
end
diff --git a/test/unit/gateways/braintree_orange_test.rb b/test/unit/gateways/braintree_orange_test.rb
index ee4149137bb..49a15e4abe6 100644
--- a/test/unit/gateways/braintree_orange_test.rb
+++ b/test/unit/gateways/braintree_orange_test.rb
@@ -5,14 +5,14 @@ class BraintreeOrangeTest < Test::Unit::TestCase
def setup
@gateway = BraintreeOrangeGateway.new(
- :login => 'LOGIN',
- :password => 'PASSWORD'
+ login: 'LOGIN',
+ password: 'PASSWORD'
)
@credit_card = credit_card
@amount = 100
- @options = { :billing_address => address }
+ @options = { billing_address: address }
end
def test_successful_purchase
@@ -27,7 +27,7 @@ def test_successful_purchase
def test_fractional_amounts
response = stub_comms do
@gateway.purchase(100, @credit_card, @options.merge(currency: 'JPY'))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
refute_match(/amount=1.00/, data)
end.respond_with(successful_purchase_response)
@@ -47,7 +47,7 @@ def test_successful_store
def test_add_processor
result = {}
- @gateway.send(:add_processor, result, {:processor => 'ccprocessorb'})
+ @gateway.send(:add_processor, result, { processor: 'ccprocessorb' })
assert_equal ['processor_id'], result.stringify_keys.keys.sort
assert_equal 'ccprocessorb', result[:processor_id]
end
@@ -86,8 +86,8 @@ def test_unsuccessful_verify
def test_add_address
result = {}
- @gateway.send(:add_address, result, {:address1 => '164 Waverley Street', :country => 'US', :state => 'CO'})
- assert_equal ['address1', 'city', 'company', 'country', 'phone', 'state', 'zip'], result.stringify_keys.keys.sort
+ @gateway.send(:add_address, result, { address1: '164 Waverley Street', country: 'US', state: 'CO' })
+ assert_equal %w[address1 city company country phone state zip], result.stringify_keys.keys.sort
assert_equal 'CO', result['state']
assert_equal '164 Waverley Street', result['address1']
assert_equal 'US', result['country']
@@ -96,8 +96,8 @@ def test_add_address
def test_add_shipping_address
result = {}
- @gateway.send(:add_address, result, {:address1 => '164 Waverley Street', :country => 'US', :state => 'CO'}, 'shipping')
- assert_equal ['shipping_address1', 'shipping_city', 'shipping_company', 'shipping_country', 'shipping_phone', 'shipping_state', 'shipping_zip'], result.stringify_keys.keys.sort
+ @gateway.send(:add_address, result, { address1: '164 Waverley Street', country: 'US', state: 'CO' }, 'shipping')
+ assert_equal %w[shipping_address1 shipping_city shipping_company shipping_country shipping_phone shipping_state shipping_zip], result.stringify_keys.keys.sort
assert_equal 'CO', result['shipping_state']
assert_equal '164 Waverley Street', result['shipping_address1']
assert_equal 'US', result['shipping_country']
@@ -106,8 +106,8 @@ def test_add_shipping_address
def test_adding_store_adds_vault_id_flag
result = {}
- @gateway.send(:add_creditcard, result, @credit_card, :store => true)
- assert_equal ['ccexp', 'ccnumber', 'customer_vault', 'cvv', 'firstname', 'lastname'], result.stringify_keys.keys.sort
+ @gateway.send(:add_creditcard, result, @credit_card, store: true)
+ assert_equal %w[ccexp ccnumber customer_vault cvv firstname lastname], result.stringify_keys.keys.sort
assert_equal 'add_customer', result[:customer_vault]
end
@@ -115,17 +115,17 @@ def test_blank_store_doesnt_add_vault_flag
result = {}
@gateway.send(:add_creditcard, result, @credit_card, {})
- assert_equal ['ccexp', 'ccnumber', 'cvv', 'firstname', 'lastname'], result.stringify_keys.keys.sort
+ assert_equal %w[ccexp ccnumber cvv firstname lastname], result.stringify_keys.keys.sort
assert_nil result[:customer_vault]
end
def test_accept_check
post = {}
- check = Check.new(:name => 'Fred Bloggs',
- :routing_number => '111000025',
- :account_number => '123456789012',
- :account_holder_type => 'personal',
- :account_type => 'checking')
+ check = Check.new(name: 'Fred Bloggs',
+ routing_number: '111000025',
+ account_number: '123456789012',
+ account_holder_type: 'personal',
+ account_type: 'checking')
@gateway.send(:add_check, post, check, {})
assert_equal %w[account_holder_type account_type checkaba checkaccount checkname payment], post.stringify_keys.keys.sort
end
@@ -155,7 +155,7 @@ def test_add_eci
@gateway.purchase(@amount, @credit_card, {})
@gateway.expects(:commit).with { |_, _, parameters| parameters[:billing_method] == 'recurring' }
- @gateway.purchase(@amount, @credit_card, {:eci => 'recurring'})
+ @gateway.purchase(@amount, @credit_card, { eci: 'recurring' })
end
def test_transcript_scrubbing
diff --git a/test/unit/gateways/braintree_test.rb b/test/unit/gateways/braintree_test.rb
index 7cff9f6512f..28fb1d0bc87 100644
--- a/test/unit/gateways/braintree_test.rb
+++ b/test/unit/gateways/braintree_test.rb
@@ -1,20 +1,19 @@
require 'test_helper'
class BraintreeTest < Test::Unit::TestCase
-
def test_new_with_login_password_creates_braintree_orange
gateway = BraintreeGateway.new(
- :login => 'LOGIN',
- :password => 'PASSWORD'
+ login: 'LOGIN',
+ password: 'PASSWORD'
)
assert_instance_of BraintreeOrangeGateway, gateway
end
def test_new_with_merchant_id_creates_braintree_blue
gateway = BraintreeGateway.new(
- :merchant_id => 'MERCHANT_ID',
- :public_key => 'PUBLIC_KEY',
- :private_key => 'PRIVATE_KEY'
+ merchant_id: 'MERCHANT_ID',
+ public_key: 'PUBLIC_KEY',
+ private_key: 'PRIVATE_KEY'
)
assert_instance_of BraintreeBlueGateway, gateway
end
@@ -28,7 +27,7 @@ def test_should_have_homepage_url
end
def test_should_have_supported_credit_card_types
- assert_equal [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro], BraintreeGateway.supported_cardtypes
+ assert_equal %i[visa master american_express discover jcb diners_club maestro], BraintreeGateway.supported_cardtypes
end
def test_should_have_default_currency
diff --git a/test/unit/gateways/braintree_token_nonce_test.rb b/test/unit/gateways/braintree_token_nonce_test.rb
new file mode 100644
index 00000000000..89aac7612c8
--- /dev/null
+++ b/test/unit/gateways/braintree_token_nonce_test.rb
@@ -0,0 +1,205 @@
+require 'test_helper'
+
+class BraintreeTokenNonceTest < Test::Unit::TestCase
+ def setup
+ @gateway = BraintreeBlueGateway.new(
+ merchant_id: 'test',
+ public_key: 'test',
+ private_key: 'test',
+ test: true
+ )
+
+ @braintree_backend = @gateway.instance_eval { @braintree_gateway }
+
+ @options = {
+ billing_address: {
+ name: 'Adrain',
+ address1: '96706 Onie Plains',
+ address2: '01897 Alysa Lock',
+ country: 'XXX',
+ city: 'Miami',
+ state: 'FL',
+ zip: '32191',
+ phone_number: '693-630-6935'
+ },
+ ach_mandate: 'ach_mandate'
+ }
+ @generator = TokenNonce.new(@braintree_backend, @options)
+ @no_address_generator = TokenNonce.new(@braintree_backend, { ach_mandate: 'ach_mandate' })
+ end
+
+ def test_build_nonce_request_for_credit_card
+ credit_card = credit_card('4111111111111111')
+ response = @generator.send(:build_nonce_request, credit_card)
+ parse_response = JSON.parse response
+ assert_client_sdk_metadata(parse_response)
+ assert_equal normalize_graph(parse_response['query']), normalize_graph(credit_card_query)
+ assert_includes parse_response['variables']['input'], 'creditCard'
+
+ credit_card_input = parse_response['variables']['input']['creditCard']
+
+ assert_equal credit_card_input['number'], credit_card.number
+ assert_equal credit_card_input['expirationYear'], credit_card.year.to_s
+ assert_equal credit_card_input['expirationMonth'], credit_card.month.to_s.rjust(2, '0')
+ assert_equal credit_card_input['cvv'], credit_card.verification_value
+ assert_equal credit_card_input['cardholderName'], credit_card.name
+ assert_billing_address_mapping(credit_card_input, credit_card)
+ end
+
+ def test_build_nonce_request_for_bank_account
+ bank_account = check({ account_number: '4012000033330125', routing_number: '011000015' })
+ response = @generator.send(:build_nonce_request, bank_account)
+ parse_response = JSON.parse response
+ assert_client_sdk_metadata(parse_response)
+ assert_equal normalize_graph(parse_response['query']), normalize_graph(bank_account_query)
+ assert_includes parse_response['variables']['input'], 'usBankAccount'
+
+ bank_account_input = parse_response['variables']['input']['usBankAccount']
+
+ assert_equal bank_account_input['routingNumber'], bank_account.routing_number
+ assert_equal bank_account_input['accountNumber'], bank_account.account_number
+ assert_equal bank_account_input['accountType'], bank_account.account_type.upcase
+ assert_equal bank_account_input['achMandate'], @options[:ach_mandate]
+
+ assert_billing_address_mapping(bank_account_input, bank_account)
+
+ assert_equal bank_account_input['individualOwner']['firstName'], bank_account.first_name
+ assert_equal bank_account_input['individualOwner']['lastName'], bank_account.last_name
+ end
+
+ def test_build_nonce_request_for_credit_card_without_address
+ credit_card = credit_card('4111111111111111')
+ response = @no_address_generator.send(:build_nonce_request, credit_card)
+ parse_response = JSON.parse response
+ assert_client_sdk_metadata(parse_response)
+ assert_equal normalize_graph(parse_response['query']), normalize_graph(credit_card_query)
+ assert_includes parse_response['variables']['input'], 'creditCard'
+
+ credit_card_input = parse_response['variables']['input']['creditCard']
+
+ assert_equal credit_card_input['number'], credit_card.number
+ assert_equal credit_card_input['expirationYear'], credit_card.year.to_s
+ assert_equal credit_card_input['expirationMonth'], credit_card.month.to_s.rjust(2, '0')
+ assert_equal credit_card_input['cvv'], credit_card.verification_value
+ assert_equal credit_card_input['cardholderName'], credit_card.name
+ end
+
+ def test_token_from
+ credit_card = credit_card(number: 4111111111111111)
+ c_token = @generator.send(:token_from, credit_card, token_credit_response)
+ assert_match(/tokencc_/, c_token)
+
+ bakn_account = check({ account_number: '4012000033330125', routing_number: '011000015' })
+ b_token = @generator.send(:token_from, bakn_account, token_bank_response)
+ assert_match(/tokenusbankacct_/, b_token)
+ end
+
+ def test_nil_token_from
+ credit_card = credit_card(number: 4111111111111111)
+ c_token = @generator.send(:token_from, credit_card, token_bank_response)
+ assert_nil c_token
+
+ bakn_account = check({ account_number: '4012000033330125', routing_number: '011000015' })
+ b_token = @generator.send(:token_from, bakn_account, token_credit_response)
+ assert_nil b_token
+ end
+
+ def assert_billing_address_mapping(request_input, payment_method)
+ assert_equal request_input['billingAddress']['streetAddress'], @options[:billing_address][:address1]
+ assert_equal request_input['billingAddress']['extendedAddress'], @options[:billing_address][:address2]
+
+ if payment_method.is_a?(Check)
+ assert_equal request_input['billingAddress']['city'], @options[:billing_address][:city]
+ assert_equal request_input['billingAddress']['state'], @options[:billing_address][:state]
+ assert_equal request_input['billingAddress']['zipCode'], @options[:billing_address][:zip]
+ else
+ assert_equal request_input['billingAddress']['locality'], @options[:billing_address][:city]
+ assert_equal request_input['billingAddress']['region'], @options[:billing_address][:state]
+ assert_equal request_input['billingAddress']['postalCode'], @options[:billing_address][:zip]
+ end
+ end
+
+ def assert_client_sdk_metadata(parse_response)
+ assert_equal parse_response['clientSdkMetadata']['platform'], 'web'
+ assert_equal parse_response['clientSdkMetadata']['source'], 'client'
+ assert_equal parse_response['clientSdkMetadata']['integration'], 'custom'
+ assert_match(/\A[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}\z/i, parse_response['clientSdkMetadata']['sessionId'])
+ assert_equal parse_response['clientSdkMetadata']['version'], '3.83.0'
+ end
+
+ private
+
+ def normalize_graph(graph)
+ graph.gsub(/\s+/, ' ').strip
+ end
+
+ def bank_account_query
+ <<-GRAPHQL
+ mutation TokenizeUsBankAccount($input: TokenizeUsBankAccountInput!) {
+ tokenizeUsBankAccount(input: $input) {
+ paymentMethod {
+ id
+ details {
+ ... on UsBankAccountDetails {
+ last4
+ }
+ }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ def credit_card_query
+ <<-GRAPHQL
+ mutation TokenizeCreditCard($input: TokenizeCreditCardInput!) {
+ tokenizeCreditCard(input: $input) {
+ paymentMethod {
+ id
+ details {
+ ... on CreditCardDetails {
+ last4
+ }
+ }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ def token_credit_response
+ {
+ 'data' => {
+ 'tokenizeCreditCard' => {
+ 'paymentMethod' => {
+ 'id' => 'tokencc_bc_72n3ms_74wsn3_jp2vn4_gjj62v_g33',
+ 'details' => {
+ 'last4' => '1111'
+ }
+ }
+ }
+ },
+ 'extensions' => {
+ 'requestId' => 'a093afbb-42a9-4a85-973f-0ca79dff9ba6'
+ }
+ }
+ end
+
+ def token_bank_response
+ {
+ 'data' => {
+ 'tokenizeUsBankAccount' => {
+ 'paymentMethod' => {
+ 'id' => 'tokenusbankacct_bc_zrg45z_7wz95v_nscrks_q4zpjs_5m7',
+ 'details' => {
+ 'last4' => '0125'
+ }
+ }
+ }
+ },
+ 'extensions' => {
+ 'requestId' => '769b26d5-27e4-4602-b51d-face8b6ffdd5'
+ }
+ }
+ end
+end
diff --git a/test/unit/gateways/bridge_pay_test.rb b/test/unit/gateways/bridge_pay_test.rb
index ce60e3e05f9..dde12fc7ee8 100644
--- a/test/unit/gateways/bridge_pay_test.rb
+++ b/test/unit/gateways/bridge_pay_test.rb
@@ -63,7 +63,7 @@ def test_authorize_and_capture
capture = stub_comms do
@gateway.capture(@amount, response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/OK2657/, data)
end.respond_with(successful_capture_response)
@@ -80,7 +80,7 @@ def test_refund
refund = stub_comms do
@gateway.refund(@amount, response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/OK9757/, data)
end.respond_with(successful_refund_response)
@@ -97,7 +97,7 @@ def test_void
refund = stub_comms do
@gateway.void(response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/OK9757/, data)
end.respond_with(successful_refund_response)
@@ -123,15 +123,15 @@ def test_store_and_purchase_with_token
def test_passing_cvv
stub_comms do
@gateway.purchase(@amount, @credit_card)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/#{@credit_card.verification_value}/, data)
end.respond_with(successful_purchase_response)
end
def test_passing_billing_address
stub_comms do
- @gateway.purchase(@amount, @credit_card, :billing_address => address)
- end.check_request do |endpoint, data, headers|
+ @gateway.purchase(@amount, @credit_card, billing_address: address)
+ end.check_request do |_endpoint, data, _headers|
assert_match(/Street=456\+My\+Street/, data)
assert_match(/Zip=K1C2N6/, data)
end.respond_with(successful_purchase_response)
diff --git a/test/unit/gateways/cams_test.rb b/test/unit/gateways/cams_test.rb
index 23102e41c39..fcd0a53cc54 100644
--- a/test/unit/gateways/cams_test.rb
+++ b/test/unit/gateways/cams_test.rb
@@ -7,8 +7,8 @@ def setup
password: 'password9'
)
- @credit_card = credit_card('4111111111111111', :month => 5, :year => 10)
- @bad_credit_card = credit_card('4242424245555555', :month => 5, :year => 10)
+ @credit_card = credit_card('4111111111111111', month: 5, year: 10)
+ @bad_credit_card = credit_card('4242424245555555', month: 5, year: 10)
@amount = 100
@options = {
@@ -116,46 +116,46 @@ def test_scrub
private
def pre_scrubbed
- <<-PRE_SCRUBBED
-opening connection to secure.centralams.com:443...
-opened
-starting SSL for secure.centralams.com:443...
-SSL established
-<- "POST /gw/api/transact.php HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: secure.centralams.com\r\nContent-Length: 249\r\n\r\n"
-<- "amount=1.03¤cy=USD&ccnumber=4111111111111111&ccexp=0916&firstname=Longbob&lastname=Longsen&address1=1234 My Street&address2=Apt 1&city=Ottawa&state=ON&zip=K1C2N6&country=US&phone=(555)555-5555&type=&password=password9&username=testintegrationc"
--> "HTTP/1.1 200 OK\r\n"
--> "Date: Tue, 21 Apr 2015 23:27:05 GMT\r\n"
--> "Server: Apache\r\n"
--> "Content-Length: 132\r\n"
--> "Connection: close\r\n"
--> "Content-Type: text/html; charset=UTF-8\r\n"
--> "\r\n"
-reading 132 bytes...
--> "response=1&responsetext=SUCCESS&authcode=123456&transactionid=2654605773&avsresponse=N&cvvresponse=&orderid=&type=&response_code=100"
-read 132 bytes
-Conn close
+ <<~PRE_SCRUBBED
+ opening connection to secure.centralams.com:443...
+ opened
+ starting SSL for secure.centralams.com:443...
+ SSL established
+ <- "POST /gw/api/transact.php HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: secure.centralams.com\r\nContent-Length: 249\r\n\r\n"
+ <- "amount=1.03¤cy=USD&ccnumber=4111111111111111&ccexp=0916&firstname=Longbob&lastname=Longsen&address1=1234 My Street&address2=Apt 1&city=Ottawa&state=ON&zip=K1C2N6&country=US&phone=(555)555-5555&type=&password=password9&username=testintegrationc"
+ -> "HTTP/1.1 200 OK\r\n"
+ -> "Date: Tue, 21 Apr 2015 23:27:05 GMT\r\n"
+ -> "Server: Apache\r\n"
+ -> "Content-Length: 132\r\n"
+ -> "Connection: close\r\n"
+ -> "Content-Type: text/html; charset=UTF-8\r\n"
+ -> "\r\n"
+ reading 132 bytes...
+ -> "response=1&responsetext=SUCCESS&authcode=123456&transactionid=2654605773&avsresponse=N&cvvresponse=&orderid=&type=&response_code=100"
+ read 132 bytes
+ Conn close
PRE_SCRUBBED
end
def post_scrubbed
- <<-POST_SCRUBBED
-opening connection to secure.centralams.com:443...
-opened
-starting SSL for secure.centralams.com:443...
-SSL established
-<- "POST /gw/api/transact.php HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: secure.centralams.com\r\nContent-Length: 249\r\n\r\n"
-<- "amount=1.03¤cy=USD&ccnumber=[FILTERED]&ccexp=0916&firstname=Longbob&lastname=Longsen&address1=1234 My Street&address2=Apt 1&city=Ottawa&state=ON&zip=K1C2N6&country=US&phone=(555)555-5555&type=&password=[FILTERED]&username=testintegrationc"
--> "HTTP/1.1 200 OK\r\n"
--> "Date: Tue, 21 Apr 2015 23:27:05 GMT\r\n"
--> "Server: Apache\r\n"
--> "Content-Length: 132\r\n"
--> "Connection: close\r\n"
--> "Content-Type: text/html; charset=UTF-8\r\n"
--> "\r\n"
-reading 132 bytes...
--> "response=1&responsetext=SUCCESS&authcode=123456&transactionid=2654605773&avsresponse=N&cvvresponse=&orderid=&type=&response_code=100"
-read 132 bytes
-Conn close
+ <<~POST_SCRUBBED
+ opening connection to secure.centralams.com:443...
+ opened
+ starting SSL for secure.centralams.com:443...
+ SSL established
+ <- "POST /gw/api/transact.php HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: secure.centralams.com\r\nContent-Length: 249\r\n\r\n"
+ <- "amount=1.03¤cy=USD&ccnumber=[FILTERED]&ccexp=0916&firstname=Longbob&lastname=Longsen&address1=1234 My Street&address2=Apt 1&city=Ottawa&state=ON&zip=K1C2N6&country=US&phone=(555)555-5555&type=&password=[FILTERED]&username=testintegrationc"
+ -> "HTTP/1.1 200 OK\r\n"
+ -> "Date: Tue, 21 Apr 2015 23:27:05 GMT\r\n"
+ -> "Server: Apache\r\n"
+ -> "Content-Length: 132\r\n"
+ -> "Connection: close\r\n"
+ -> "Content-Type: text/html; charset=UTF-8\r\n"
+ -> "\r\n"
+ reading 132 bytes...
+ -> "response=1&responsetext=SUCCESS&authcode=123456&transactionid=2654605773&avsresponse=N&cvvresponse=&orderid=&type=&response_code=100"
+ read 132 bytes
+ Conn close
POST_SCRUBBED
end
diff --git a/test/unit/gateways/card_connect_test.rb b/test/unit/gateways/card_connect_test.rb
index e4a49a1541b..7188dea17dc 100644
--- a/test/unit/gateways/card_connect_test.rb
+++ b/test/unit/gateways/card_connect_test.rb
@@ -14,11 +14,122 @@ def setup
billing_address: address,
description: 'Store Purchase'
}
+
+ @three_ds_secure = {
+ version: '2.0',
+ cavv: 'AJkBByEyYgAAAASwgmEodQAAAAA=',
+ eci: '05',
+ xid: '3875d372-d96d-412a-a806-5ac367d095b1'
+ }
+ end
+
+ def test_three_ds_2_object_construction
+ post = {}
+ @three_ds_secure[:ds_transaction_id] = '3875d372-d96d-412a-a806-5ac367d095b1'
+ @options[:three_d_secure] = @three_ds_secure
+
+ @gateway.send(:add_three_ds_mpi_data, post, @options)
+ three_ds_options = @options[:three_d_secure]
+ assert_equal three_ds_options[:cavv], post[:securevalue]
+ assert_equal three_ds_options[:eci], post[:secureflag]
+ assert_equal three_ds_options[:ds_transaction_id], post[:securedstid]
+ end
+
+ def test_purchase_with_three_ds
+ @options[:three_d_secure] = @three_ds_secure
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ three_ds_params = JSON.parse(data)['three_dsecure']
+ assert_equal 'AJkBByEyYgAAAASwgmEodQAAAAA=', three_ds_params['cavv']
+ assert_equal '05', three_ds_params['eci']
+ assert_equal '3875d372-d96d-412a-a806-5ac367d095b1', three_ds_params['xid']
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_initial_purchase_with_stored_credential
+ stored_credential_options = {
+ initial_transaction: true,
+ reason_type: 'recurring',
+ initiator: 'merchant'
+ }
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_options }))
+ end.check_request do |_verb, _url, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['cof'], 'M'
+ assert_equal request['cofscheduled'], 'Y'
+ assert_equal request['cofpermission'], 'Y'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_subsequent_purchase_with_stored_credential
+ stored_credential_options = {
+ initial_transaction: false,
+ reason_type: 'recurring',
+ initiator: 'cardholder'
+ }
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_options }))
+ end.check_request do |_verb, _url, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['cof'], 'C'
+ assert_equal request['cofscheduled'], 'Y'
+ assert_equal request['cofpermission'], 'N'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_purchase_with_ecomind
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options.merge({ ecomind: 't' }))
+ end.check_request do |_verb, _url, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['ecomind'], 'T'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_purchase_with_recurring
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options.merge({ recurring: true }))
+ end.check_request do |_verb, _url, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['ecomind'], 'R'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_purchase_without_recurring
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options.merge({ recurring: false }))
+ end.check_request do |_verb, _url, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['ecomind'], 'E'
+ end.respond_with(successful_purchase_response)
end
- def test_incorrect_domain
+ def test_allow_domains_without_ports
+ assert CardConnectGateway.new(username: 'username', password: 'password', merchant_id: 'merchand_id', domain: 'https://vendor.cardconnect.com/test')
+ end
+
+ def test_add_address
+ result = {}
+
+ @gateway.send(:add_address, result, billing_address: { address1: '123 Test St.', address2: '5F', city: 'Testville', zip: '12345', state: 'AK' })
+ assert_equal '123 Test St.', result[:address]
+ assert_equal '5F', result[:address2]
+ assert_equal 'Testville', result[:city]
+ assert_equal 'AK', result[:region]
+ assert_equal '12345', result[:postal]
+ end
+
+ def test_reject_domains_without_card_connect
+ assert_raise(ArgumentError) {
+ CardConnectGateway.new(username: 'username', password: 'password', merchant_id: 'merchand_id', domain: 'https://www.google.com')
+ }
+ end
+
+ def test_reject_domains_without_https
assert_raise(ArgumentError) {
- CardConnectGateway.new(username: 'username', password: 'password', merchant_id: 'merchand_id', domain: 'www.google.com')
+ CardConnectGateway.new(username: 'username', password: 'password', merchant_id: 'merchand_id', domain: 'ttps://cardconnect.com')
}
end
@@ -185,7 +296,7 @@ def test_failed_store
def test_successful_unstore
stub_comms(@gateway, :ssl_request) do
@gateway.unstore('1|16700875781344019340')
- end.check_request do |verb, url, data, headers|
+ end.check_request do |verb, url, _data, _headers|
assert_equal :delete, verb
assert_match %r{16700875781344019340/1}, url
end.respond_with(successful_unstore_response)
@@ -199,6 +310,17 @@ def test_scrub
assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed
end
+ def test_frontendid_is_added_to_post_data_parameters
+ @gateway.class.application_id = 'my_app'
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_, _, body|
+ assert_equal 'my_app', JSON.parse(body)['frontendid']
+ end.respond_with(successful_purchase_response)
+ ensure
+ @gateway.class.application_id = nil
+ end
+
private
def pre_scrubbed
diff --git a/test/unit/gateways/card_save_test.rb b/test/unit/gateways/card_save_test.rb
index bb19495a1f1..6689ca22eef 100644
--- a/test/unit/gateways/card_save_test.rb
+++ b/test/unit/gateways/card_save_test.rb
@@ -3,10 +3,10 @@
class CardSaveTest < Test::Unit::TestCase
def setup
Base.mode = :test
- @gateway = CardSaveGateway.new(:login => 'login', :password => 'password')
+ @gateway = CardSaveGateway.new(login: 'login', password: 'password')
@credit_card = credit_card
@amount = 100
- @options = {:order_id =>'1', :billing_address => address, :description =>'Store Purchase'}
+ @options = { order_id: '1', billing_address: address, description: 'Store Purchase' }
end
def test_successful_purchase
@@ -273,5 +273,4 @@ def failed_refund
)
end
-
end
diff --git a/test/unit/gateways/card_stream_test.rb b/test/unit/gateways/card_stream_test.rb
index e7f225346de..f648a960a42 100644
--- a/test/unit/gateways/card_stream_test.rb
+++ b/test/unit/gateways/card_stream_test.rb
@@ -5,45 +5,63 @@ class CardStreamTest < Test::Unit::TestCase
def setup
@gateway = CardStreamGateway.new(
- :login => 'login',
- :shared_secret => 'secret'
+ login: 'login',
+ shared_secret: 'secret'
)
- @visacreditcard = credit_card('4929421234600821',
- :month => '12',
- :year => '2014',
- :verification_value => '356',
- :brand => :visa
+ @visacreditcard = credit_card(
+ '4929421234600821',
+ month: '12',
+ year: '2014',
+ verification_value: '356',
+ brand: :visa
)
@visacredit_options = {
- :billing_address => {
- :address1 => 'Flat 6, Primrose Rise',
- :address2 => '347 Lavender Road',
- :city => '',
- :state => 'Northampton',
- :zip => 'NN17 8YG '
+ billing_address: {
+ address1: 'Flat 6, Primrose Rise',
+ address2: '347 Lavender Road',
+ city: '',
+ state: 'Northampton',
+ zip: 'NN17 8YG '
},
- :order_id => generate_unique_id,
- :description => 'AM test purchase'
+ order_id: generate_unique_id,
+ description: 'AM test purchase'
+ }
+
+ @visacredit_three_ds_options = {
+ threeds_required: true,
+ three_ds_version: '2.1.0',
+ three_d_secure: {
+ enrolled: 'true',
+ authentication_response_status: 'Y',
+ eci: '05',
+ cavv: 'Y2FyZGluYWxjb21tZXJjZWF1dGg',
+ xid: '362DF058-6061-47F1-A504-CACCBDF422B7'
+ }
}
@visacredit_descriptor_options = {
- :billing_address => {
- :address1 => 'Flat 6, Primrose Rise',
- :address2 => '347 Lavender Road',
- :city => '',
- :state => 'Northampton',
- :zip => 'NN17 8YG '
+ billing_address: {
+ address1: 'Flat 6, Primrose Rise',
+ address2: '347 Lavender Road',
+ city: '',
+ state: 'Northampton',
+ zip: 'NN17 8YG '
},
- :merchant_name => 'merchant',
- :dynamic_descriptor => 'product'
+ merchant_name: 'merchant',
+ dynamic_descriptor: 'product'
}
- @declined_card = credit_card('4000300011112220',
- :month => '9',
- :year => '2014'
+ @amex = credit_card(
+ '374245455400001',
+ month: '12',
+ year: 2014,
+ verification_value: '4887',
+ brand: :american_express
)
+
+ @declined_card = credit_card('4000300011112220', month: '9', year: '2014')
end
def test_successful_visacreditcard_authorization
@@ -130,7 +148,7 @@ def test_successful_visacreditcard_purchase
def test_successful_visacreditcard_purchase_with_descriptors
stub_comms do
@gateway.purchase(284, @visacreditcard, @visacredit_descriptor_options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/statementNarrative1=merchant/, data)
assert_match(/statementNarrative2=product/, data)
end.respond_with(successful_purchase_response_with_descriptors)
@@ -139,7 +157,7 @@ def test_successful_visacreditcard_purchase_with_descriptors
def test_successful_visacreditcard_purchase_with_default_ip
stub_comms do
@gateway.purchase(284, @visacreditcard, @visacredit_options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/remoteAddress=1\.1\.1\.1/, data)
end.respond_with(successful_purchase_response_with_descriptors)
end
@@ -147,7 +165,7 @@ def test_successful_visacreditcard_purchase_with_default_ip
def test_successful_visacreditcard_purchase_with_default_country
stub_comms do
@gateway.purchase(284, @visacreditcard, @visacredit_options.delete(:billing_address))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/customerCountryCode=GB/, data)
end.respond_with(successful_purchase_response)
end
@@ -179,6 +197,14 @@ def test_declined_mastercard_purchase
assert response.test?
end
+ def test_successful_amex_purchase_with_localized_invoice_amount
+ stub_comms do
+ @gateway.purchase(28400, @amex, @visacredit_descriptor_options.merge(currency: 'JPY', order_id: '1234567890'))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/item1GrossValue=284&/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
def test_successful_verify
response = stub_comms do
@gateway.verify(@visacreditcard, @visacredit_options)
@@ -199,7 +225,7 @@ def test_purchase_options
# Default
purchase = stub_comms do
@gateway.purchase(142, @visacreditcard, @visacredit_options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/type=1/, data)
end.respond_with(successful_purchase_response)
@@ -207,7 +233,7 @@ def test_purchase_options
purchase = stub_comms do
@gateway.purchase(142, @visacreditcard, @visacredit_options.merge(type: 2))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/type=2/, data)
end.respond_with(successful_purchase_response)
@@ -215,7 +241,7 @@ def test_purchase_options
purchase = stub_comms do
@gateway.purchase(142, @visacreditcard, @visacredit_options.merge(currency: 'PEN'))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/currencyCode=604/, data)
end.respond_with(successful_purchase_response)
@@ -224,7 +250,7 @@ def test_purchase_options
def test_successful_purchase_without_street_address
@gateway.expects(:ssl_post).returns(successful_purchase_response)
- assert response = @gateway.purchase(142, @visacreditcard, billing_address: {state: 'Northampton'})
+ assert response = @gateway.purchase(142, @visacreditcard, billing_address: { state: 'Northampton' })
assert_equal 'APPROVED', response.message
end
@@ -234,21 +260,39 @@ def test_successful_purchase_without_any_address
assert_equal 'APPROVED', response.message
end
+ def test_adding_country_code
+ %i[authorize purchase refund].each do |action|
+ stub_comms do
+ @gateway.send(action, 142, @visacreditcard, @visacredit_options.merge(country_code: 'US'))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/&countryCode=US/, data)
+ end.respond_with(successful_purchase_response)
+ end
+ end
+
def test_hmac_signature_added_to_post
post_params = "action=SALE&amount=10000&captureDelay=0&cardCVV=356&cardExpiryMonth=12&cardExpiryYear=14&cardNumber=4929421234600821&countryCode=GB¤cyCode=826&customerAddress=Flat+6%2C+Primrose+Rise+347+Lavender+Road&customerCountryCode=GB&customerName=Longbob+Longsen&customerPostCode=NN17+8YG+&merchantID=login&orderRef=AM+test+purchase&remoteAddress=1.1.1.1&threeDSRequired=N&transactionUnique=#{@visacredit_options[:order_id]}&type=1"
expected_signature = Digest::SHA512.hexdigest("#{post_params}#{@gateway.options[:shared_secret]}")
- @gateway.expects(:ssl_post).with do |url, data|
+ @gateway.expects(:ssl_post).with do |_url, data|
data.include?("signature=#{expected_signature}")
end.returns(successful_authorization_response)
@gateway.purchase(10000, @visacreditcard, @visacredit_options)
end
+ def test_nonfractional_currency_handling
+ stub_comms do
+ @gateway.authorize(200, @visacreditcard, @visacredit_options.merge(currency: 'JPY'))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/amount=2¤cyCode=392/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
def test_3ds_response
purchase = stub_comms do
@gateway.purchase(142, @visacreditcard, @visacredit_options.merge(threeds_required: true))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/threeDSRequired=Y/, data)
end.respond_with(successful_purchase_response_with_3dsecure)
@@ -261,14 +305,14 @@ def test_3ds_response
def test_deprecated_3ds_required
assert_deprecation_warning(CardStreamGateway::THREEDSECURE_REQUIRED_DEPRECATION_MESSAGE) do
@gateway = CardStreamGateway.new(
- :login => 'login',
- :shared_secret => 'secret',
- :threeDSRequired => true
+ login: 'login',
+ shared_secret: 'secret',
+ threeDSRequired: true
)
end
stub_comms do
@gateway.purchase(142, @visacreditcard, @visacredit_options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/threeDSRequired=Y/, data)
end.respond_with(successful_purchase_response)
end
@@ -276,11 +320,45 @@ def test_deprecated_3ds_required
def test_default_3dsecure_required
stub_comms do
@gateway.purchase(142, @visacreditcard, @visacredit_options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/threeDSRequired=N/, data)
end.respond_with(successful_purchase_response)
end
+ def test_3ds2_data
+ stub_comms do
+ @gateway.purchase(142, @visacreditcard, @visacredit_options.merge(@visacredit_three_ds_options))
+ end.check_request(skip_response: true) do |_endpoint, data, _headers|
+ assert_match(/threeDSRequired=Y/, data)
+ assert_match(/threeDSEnrolled=Y/, data)
+ assert_match(/threeDSAuthenticated=Y/, data)
+ assert_match(/threeDSECI=05/, data)
+ assert_match(/threeDSCAVV=Y2FyZGluYWxjb21tZXJjZWF1dGg/, data)
+ assert_match(/threeDSXID=362DF058-6061-47F1-A504-CACCBDF422B7/, data)
+ end
+ end
+
+ def test_3ds2_not_enrolled
+ stub_comms do
+ @visacredit_three_ds_options[:three_d_secure][:enrolled] = 'false'
+ @gateway.purchase(142, @visacreditcard, @visacredit_options.merge(@visacredit_three_ds_options))
+ end.check_request(skip_response: true) do |_endpoint, data, _headers|
+ assert_match(/threeDSRequired=Y/, data)
+ assert_match(/threeDSEnrolled=N/, data)
+ end
+ end
+
+ def test_3ds2_not_authenticated
+ stub_comms do
+ @visacredit_three_ds_options[:three_d_secure][:authentication_response_status] = 'N'
+ @gateway.purchase(142, @visacreditcard, @visacredit_options.merge(@visacredit_three_ds_options))
+ end.check_request(skip_response: true) do |_endpoint, data, _headers|
+ assert_match(/threeDSRequired=Y/, data)
+ assert_match(/threeDSEnrolled=Y/, data)
+ assert_match(/threeDSAuthenticated=N/, data)
+ end
+ end
+
def test_transcript_scrubbing
assert_equal scrubbed_transcript, @gateway.scrub(transcript)
end
@@ -340,16 +418,16 @@ def failed_reference_purchase_response
end
def transcript
- <<-eos
+ <<-REQUEST
POST /direct/ HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: gateway.cardstream.com\r\nContent-Length: 501\r\n\r\n"
amount=¤cyCode=826&transactionUnique=a017ca2ac0569188517ad8368c36a06d&orderRef=AM+test+purchase&customerName=Longbob+Longsen&cardNumber=4929421234600821&cardExpiryMonth=12&cardExpiryYear=14&cardCVV=356&customerAddress=Flat+6%2C+Primrose+Rise+347+Lavender+Road&customerPostCode=NN17+8YG+&merchantID=102922&action=SALE&type=1&countryCode=GB&threeDSRequired=N&signature=970b3fe099a85c9922a79af46c2cb798616b9fbd044a921ac5eb46cd1907a5e89b8c720aae59c7eb1d81a59563f209d5db51aa3c270838199f2bfdcbe2c1149d
- eos
+ REQUEST
end
def scrubbed_transcript
- <<-eos
+ <<-REQUEST
POST /direct/ HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: gateway.cardstream.com\r\nContent-Length: 501\r\n\r\n"
amount=¤cyCode=826&transactionUnique=a017ca2ac0569188517ad8368c36a06d&orderRef=AM+test+purchase&customerName=Longbob+Longsen&cardNumber=[FILTERED]&cardExpiryMonth=12&cardExpiryYear=14&cardCVV=[FILTERED]&customerAddress=Flat+6%2C+Primrose+Rise+347+Lavender+Road&customerPostCode=NN17+8YG+&merchantID=102922&action=SALE&type=1&countryCode=GB&threeDSRequired=N&signature=970b3fe099a85c9922a79af46c2cb798616b9fbd044a921ac5eb46cd1907a5e89b8c720aae59c7eb1d81a59563f209d5db51aa3c270838199f2bfdcbe2c1149d
- eos
+ REQUEST
end
end
diff --git a/test/unit/gateways/cardknox_test.rb b/test/unit/gateways/cardknox_test.rb
index bc10d5e0e70..11e05970f77 100644
--- a/test/unit/gateways/cardknox_test.rb
+++ b/test/unit/gateways/cardknox_test.rb
@@ -16,7 +16,7 @@ def setup
def test_successful_purchase_passing_extra_info
response = stub_comms do
@gateway.purchase(@amount, @credit_card, @options.merge(order_id: '1337', description: 'socool'))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/xOrderID=1337/, data)
assert_match(/xDescription=socool/, data)
end.respond_with(successful_purchase_response)
@@ -66,7 +66,7 @@ def test_manual_entry_is_properly_indicated_on_purchase
@credit_card.manual_entry = true
response = stub_comms do
@gateway.purchase(@amount, @credit_card, @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match %r{xCardNum=4242424242424242}, data
assert_match %r{xCardPresent=true}, data
end.respond_with(successful_purchase_response)
@@ -75,7 +75,7 @@ def test_manual_entry_is_properly_indicated_on_purchase
end
def test_ip_is_being_sent # failed
- @gateway.expects(:ssl_post).with do |url, data|
+ @gateway.expects(:ssl_post).with do |_url, data|
data =~ /xIP=123.123.123.123/
end.returns(successful_purchase_response)
@@ -131,7 +131,7 @@ def test_successful_capture
def test_failed_capture
@gateway.expects(:ssl_post).returns(failed_capture_response)
- assert capture = @gateway.capture(@amount-1, '')
+ assert capture = @gateway.capture(@amount - 1, '')
assert_failure capture
assert_equal 'Original transaction not specified', capture.message
end
diff --git a/test/unit/gateways/cardprocess_test.rb b/test/unit/gateways/cardprocess_test.rb
index 5377cd16c73..97e8061f2ff 100644
--- a/test/unit/gateways/cardprocess_test.rb
+++ b/test/unit/gateways/cardprocess_test.rb
@@ -167,7 +167,7 @@ def test_error_code_parsing
'800.800.202' => :invalid_zip
}
codes.each_pair do |code, key|
- response = {'result' => {'code' => code}}
+ response = { 'result' => { 'code' => code } }
assert_equal Gateway::STANDARD_ERROR_CODE[key], @gateway.send(:error_code_from, response), "expecting #{code} => #{key}"
end
end
diff --git a/test/unit/gateways/cashnet_test.rb b/test/unit/gateways/cashnet_test.rb
index 844702eac9a..7aeee072c3a 100644
--- a/test/unit/gateways/cashnet_test.rb
+++ b/test/unit/gateways/cashnet_test.rb
@@ -22,6 +22,35 @@ def test_successful_purchase
assert_equal '1234', response.authorization
end
+ def test_successful_purchase_with_multiple_items
+ options = { item_codes: { item_code: 'APPFEE', item_code2: 'LOBSTER', item_code3: 'CODES', amount: 100, amount2: 1234, amount3: 4321 } }
+
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match('itemcode=APPFEE&itemcode2=LOBSTER&itemcode3=CODES&amount=1.00&amount2=12.34&amount3=43.21', data)
+ end.respond_with(successful_purchase_response)
+
+ assert_instance_of Response, response
+ assert_success response
+ assert_equal '1234', response.authorization
+ end
+
+ def test_successful_purchase_with_filtered_itemcodes
+ options = { item_codes: { item_code: 'APPFEE', item_code2: 'LOBSTER', item_code3: 'CODES', bad_key: 'BADVALUE', amount: 100, amount2: 1234, amount3: 4321 } }
+
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match('itemcode=APPFEE&itemcode2=LOBSTER&itemcode3=CODES&amount=1.00&amount2=12.34&amount3=43.21', data)
+ refute_match('badkey=BADVALUE', data)
+ end.respond_with(successful_purchase_response)
+
+ assert_instance_of Response, response
+ assert_success response
+ assert_equal '1234', response.authorization
+ end
+
def test_failed_purchase
@gateway.expects(:ssl_post).returns(failed_purchase_response)
@@ -55,12 +84,12 @@ def test_supported_countries
end
def test_supported_card_types
- assert_equal [:visa, :master, :american_express, :discover, :diners_club, :jcb], CashnetGateway.supported_cardtypes
+ assert_equal %i[visa master american_express discover diners_club jcb], CashnetGateway.supported_cardtypes
end
def test_add_invoice
result = {}
- @gateway.send(:add_invoice, result, order_id: '#1001')
+ @gateway.send(:add_invoice, result, 1000, order_id: '#1001')
assert_equal '#1001', result[:order_number]
end
@@ -76,9 +105,9 @@ def test_add_creditcard
def test_add_address
result = {}
- @gateway.send(:add_address, result, billing_address: {address1: '123 Test St.', address2: '5F', city: 'Testville', zip: '12345', state: 'AK'})
+ @gateway.send(:add_address, result, billing_address: { address1: '123 Test St.', address2: '5F', city: 'Testville', zip: '12345', state: 'AK' })
- assert_equal ['addr_g', 'city_g', 'state_g', 'zip_g'], result.stringify_keys.keys.sort
+ assert_equal %w[addr_g city_g state_g zip_g], result.stringify_keys.keys.sort
assert_equal '123 Test St.,5F', result[:addr_g]
assert_equal 'Testville', result[:city_g]
assert_equal 'AK', result[:state_g]
@@ -93,11 +122,11 @@ def test_add_customer_data
def test_action_meets_minimum_requirements
params = {
- amount: '1.01',
+ amount: '1.01'
}
@gateway.send(:add_creditcard, params, @credit_card)
- @gateway.send(:add_invoice, params, {})
+ @gateway.send(:add_invoice, params, 101, {})
assert data = @gateway.send(:post_data, 'SALE', params)
minimum_requirements.each do |key|
@@ -108,7 +137,7 @@ def test_action_meets_minimum_requirements
def test_successful_purchase_with_fname_and_lname
stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card, {})
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/fname=Longbob/, data)
assert_match(/lname=Longsen/, data)
end.respond_with(successful_purchase_response)
@@ -127,7 +156,7 @@ def test_passes_custcode_from_credentials
gateway = CashnetGateway.new(merchant: 'X', operator: 'X', password: 'test123', merchant_gateway_name: 'X', custcode: 'TheCustCode')
stub_comms(gateway, :ssl_request) do
gateway.purchase(@amount, @credit_card, {})
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/custcode=TheCustCode/, data)
end.respond_with(successful_purchase_response)
end
@@ -136,7 +165,7 @@ def test_allows_custcode_override
gateway = CashnetGateway.new(merchant: 'X', operator: 'X', password: 'test123', merchant_gateway_name: 'X', custcode: 'TheCustCode')
stub_comms(gateway, :ssl_request) do
gateway.purchase(@amount, @credit_card, custcode: 'OveriddenCustCode')
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/custcode=OveriddenCustCode/, data)
end.respond_with(successful_purchase_response)
end
@@ -177,128 +206,128 @@ def invalid_response
end
def pre_scrubbed
- <<-TRANSCRIPT
-opening connection to train.cashnet.com:443...
-opened
-starting SSL for train.cashnet.com:443...
-SSL established
-<- "POST /givecorpsgateway HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: train.cashnet.com\r\nContent-Length: 364\r\n\r\n"
-<- "command=SALE&merchant=GiveCorpGW&operator=givecorp&password=14givecorps&station=WEB&custcode=ActiveMerchant%2F1.76.0&cardno=5454545454545454&cid=123&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2CApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00"
--> "HTTP/1.1 302 Found\r\n"
--> "Date: Wed, 03 Jan 2018 17:03:35 GMT\r\n"
--> "Content-Type: text/html; charset=utf-8\r\n"
--> "Transfer-Encoding: chunked\r\n"
--> "Connection: close\r\n"
--> "Set-Cookie: AWSALB=5ISjTg8Mez7jS1kEnzY4j5NkQ5bdlwDDNmfzTyEMBmILpb0Tn3k58pUQTGHBj3NUpciP0uqQs7FaAb42YZvt35ndLERGJA0dPQ03iCfrqbneQ+Wm5BhDzMGo5GUT; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
--> "Set-Cookie: AWSALB=bVhwwfJ2D6cI5zB3eapqNStEzF5yX1pXhaJGUBUCa+DZhEgn/TZGxznxIOYB9qKqzkPF4lq/zxWg/tuMBTiY4JGLRjayyhizvHnj2smrnNvr2DLQN7ZjLSh51BzM; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
--> "Cache-Control: private\r\n"
--> "Location: https://train.cashnet.com/cashneti/Gateway/htmlgw.aspx?client=EMARKETVENDOR_DEMO&command=SALE&merchant=GiveCorpGW&operator=givecorp&password=14givecorps&station=WEB&custcode=ActiveMerchant%2f1.76.0&cardno=5454545454545454&cid=123&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2cApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00\r\n"
--> "Set-Cookie: ASP.NET_SessionId=; path=/; HttpOnly\r\n"
--> "P3P: CP=\"NOI DSP COR NID NOR\"\r\n"
--> "Set-Cookie: BNI_persistence=0000000000000000000000004d79da0a00005000; Path=/\r\n"
--> "Strict-Transport-Security: max-age=31536000\r\n"
--> "\r\n"
--> "282\r\n"
-reading 642 bytes...
--> "Object moved\r\nObject moved to here.
\r\n\r\n"
-read 642 bytes
-reading 2 bytes...
--> "\r\n"
-read 2 bytes
--> "0\r\n"
--> "\r\n"
-Conn close
-opening connection to train.cashnet.com:443...
-opened
-starting SSL for train.cashnet.com:443...
-SSL established
-<- "GET /cashneti/Gateway/htmlgw.aspx?client=EMARKETVENDOR_DEMO&command=SALE&merchant=GiveCorpGW&operator=givecorp&password=14givecorps&station=WEB&custcode=ActiveMerchant%2f1.76.0&cardno=5454545454545454&cid=123&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2cApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: train.cashnet.com\r\n\r\n"
--> "HTTP/1.1 200 OK\r\n"
--> "Date: Wed, 03 Jan 2018 17:03:35 GMT\r\n"
--> "Content-Type: text/html; charset=utf-8\r\n"
--> "Transfer-Encoding: chunked\r\n"
--> "Connection: close\r\n"
--> "Set-Cookie: AWSALB=lFPwFYRnXJHRNmE6NCRAIfHtQadwx4bYJoT5xeAL5AuAXPcm1vYWx5F/s5FBr3GcungifktpWlwIgAmWS29K7YRXTCjk4xmcAnhXS86fpVUVQt4ECwPH2xdv8tf2; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
--> "Set-Cookie: AWSALB=mEfysFNBclo1/9+tTuI/XtHrmVkD89Fh6tAJ3Gl0u2EuLCYTW5VwEq+fVqYG1fEkN02dbhKSkIdM22QvyT6cRccDaUBsYAnOKjg2JlVShJlf+li5tfbrsUDk14jG; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
--> "Cache-Control: private\r\n"
--> "Set-Cookie: ASP.NET_SessionId=3ocslggtk4cdz54unbdnm25o; path=/; HttpOnly\r\n"
--> "P3P: CP=\"NOI DSP COR NID NOR\"\r\n"
--> "Set-Cookie: BNI_persistence=0000000000000000000000004d79da0a00005000; Path=/\r\n"
--> "Strict-Transport-Security: max-age=31536000\r\n"
--> "\r\n"
--> "3a\r\n"
-reading 58 bytes...
--> "result=0&tx=77972&busdate=7/25/2017"
-read 58 bytes
-reading 2 bytes...
--> "\r\n"
-read 2 bytes
--> "0\r\n"
--> "\r\n"
-Conn close
-TRANSCRIPT
+ <<~TRANSCRIPT
+ opening connection to train.cashnet.com:443...
+ opened
+ starting SSL for train.cashnet.com:443...
+ SSL established
+ <- "POST /givecorpsgateway HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: train.cashnet.com\r\nContent-Length: 364\r\n\r\n"
+ <- "command=SALE&merchant=GiveCorpGW&operator=givecorp&password=14givecorps&station=WEB&custcode=ActiveMerchant%2F1.76.0&cardno=5454545454545454&cid=123&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2CApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00"
+ -> "HTTP/1.1 302 Found\r\n"
+ -> "Date: Wed, 03 Jan 2018 17:03:35 GMT\r\n"
+ -> "Content-Type: text/html; charset=utf-8\r\n"
+ -> "Transfer-Encoding: chunked\r\n"
+ -> "Connection: close\r\n"
+ -> "Set-Cookie: AWSALB=5ISjTg8Mez7jS1kEnzY4j5NkQ5bdlwDDNmfzTyEMBmILpb0Tn3k58pUQTGHBj3NUpciP0uqQs7FaAb42YZvt35ndLERGJA0dPQ03iCfrqbneQ+Wm5BhDzMGo5GUT; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
+ -> "Set-Cookie: AWSALB=bVhwwfJ2D6cI5zB3eapqNStEzF5yX1pXhaJGUBUCa+DZhEgn/TZGxznxIOYB9qKqzkPF4lq/zxWg/tuMBTiY4JGLRjayyhizvHnj2smrnNvr2DLQN7ZjLSh51BzM; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
+ -> "Cache-Control: private\r\n"
+ -> "Location: https://train.cashnet.com/cashneti/Gateway/htmlgw.aspx?client=EMARKETVENDOR_DEMO&command=SALE&merchant=GiveCorpGW&operator=givecorp&password=14givecorps&station=WEB&custcode=ActiveMerchant%2f1.76.0&cardno=5454545454545454&cid=123&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2cApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00\r\n"
+ -> "Set-Cookie: ASP.NET_SessionId=; path=/; HttpOnly\r\n"
+ -> "P3P: CP=\"NOI DSP COR NID NOR\"\r\n"
+ -> "Set-Cookie: BNI_persistence=0000000000000000000000004d79da0a00005000; Path=/\r\n"
+ -> "Strict-Transport-Security: max-age=31536000\r\n"
+ -> "\r\n"
+ -> "282\r\n"
+ reading 642 bytes...
+ -> "Object moved\r\nObject moved to here.
\r\n\r\n"
+ read 642 bytes
+ reading 2 bytes...
+ -> "\r\n"
+ read 2 bytes
+ -> "0\r\n"
+ -> "\r\n"
+ Conn close
+ opening connection to train.cashnet.com:443...
+ opened
+ starting SSL for train.cashnet.com:443...
+ SSL established
+ <- "GET /cashneti/Gateway/htmlgw.aspx?client=EMARKETVENDOR_DEMO&command=SALE&merchant=GiveCorpGW&operator=givecorp&password=14givecorps&station=WEB&custcode=ActiveMerchant%2f1.76.0&cardno=5454545454545454&cid=123&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2cApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: train.cashnet.com\r\n\r\n"
+ -> "HTTP/1.1 200 OK\r\n"
+ -> "Date: Wed, 03 Jan 2018 17:03:35 GMT\r\n"
+ -> "Content-Type: text/html; charset=utf-8\r\n"
+ -> "Transfer-Encoding: chunked\r\n"
+ -> "Connection: close\r\n"
+ -> "Set-Cookie: AWSALB=lFPwFYRnXJHRNmE6NCRAIfHtQadwx4bYJoT5xeAL5AuAXPcm1vYWx5F/s5FBr3GcungifktpWlwIgAmWS29K7YRXTCjk4xmcAnhXS86fpVUVQt4ECwPH2xdv8tf2; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
+ -> "Set-Cookie: AWSALB=mEfysFNBclo1/9+tTuI/XtHrmVkD89Fh6tAJ3Gl0u2EuLCYTW5VwEq+fVqYG1fEkN02dbhKSkIdM22QvyT6cRccDaUBsYAnOKjg2JlVShJlf+li5tfbrsUDk14jG; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
+ -> "Cache-Control: private\r\n"
+ -> "Set-Cookie: ASP.NET_SessionId=3ocslggtk4cdz54unbdnm25o; path=/; HttpOnly\r\n"
+ -> "P3P: CP=\"NOI DSP COR NID NOR\"\r\n"
+ -> "Set-Cookie: BNI_persistence=0000000000000000000000004d79da0a00005000; Path=/\r\n"
+ -> "Strict-Transport-Security: max-age=31536000\r\n"
+ -> "\r\n"
+ -> "3a\r\n"
+ reading 58 bytes...
+ -> "result=0&tx=77972&busdate=7/25/2017"
+ read 58 bytes
+ reading 2 bytes...
+ -> "\r\n"
+ read 2 bytes
+ -> "0\r\n"
+ -> "\r\n"
+ Conn close
+ TRANSCRIPT
end
def post_scrubbed
- <<-SCRUBBED
-opening connection to train.cashnet.com:443...
-opened
-starting SSL for train.cashnet.com:443...
-SSL established
-<- "POST /givecorpsgateway HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: train.cashnet.com\r\nContent-Length: 364\r\n\r\n"
-<- "command=SALE&merchant=GiveCorpGW&operator=givecorp&password=[FILTERED]&station=WEB&custcode=ActiveMerchant%2F1.76.0&cardno=[FILTERED]&cid=[FILTERED]&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2CApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00"
--> "HTTP/1.1 302 Found\r\n"
--> "Date: Wed, 03 Jan 2018 17:03:35 GMT\r\n"
--> "Content-Type: text/html; charset=utf-8\r\n"
--> "Transfer-Encoding: chunked\r\n"
--> "Connection: close\r\n"
--> "Set-Cookie: AWSALB=5ISjTg8Mez7jS1kEnzY4j5NkQ5bdlwDDNmfzTyEMBmILpb0Tn3k58pUQTGHBj3NUpciP0uqQs7FaAb42YZvt35ndLERGJA0dPQ03iCfrqbneQ+Wm5BhDzMGo5GUT; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
--> "Set-Cookie: AWSALB=bVhwwfJ2D6cI5zB3eapqNStEzF5yX1pXhaJGUBUCa+DZhEgn/TZGxznxIOYB9qKqzkPF4lq/zxWg/tuMBTiY4JGLRjayyhizvHnj2smrnNvr2DLQN7ZjLSh51BzM; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
--> "Cache-Control: private\r\n"
--> "Location: https://train.cashnet.com/cashneti/Gateway/htmlgw.aspx?client=EMARKETVENDOR_DEMO&command=SALE&merchant=GiveCorpGW&operator=givecorp&password=[FILTERED]&station=WEB&custcode=ActiveMerchant%2f1.76.0&cardno=[FILTERED]&cid=[FILTERED]&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2cApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00\r\n"
--> "Set-Cookie: ASP.NET_SessionId=; path=/; HttpOnly\r\n"
--> "P3P: CP=\"NOI DSP COR NID NOR\"\r\n"
--> "Set-Cookie: BNI_persistence=0000000000000000000000004d79da0a00005000; Path=/\r\n"
--> "Strict-Transport-Security: max-age=31536000\r\n"
--> "\r\n"
--> "282\r\n"
-reading 642 bytes...
--> "Object moved\r\nObject moved to here.
\r\n\r\n"
-read 642 bytes
-reading 2 bytes...
--> "\r\n"
-read 2 bytes
--> "0\r\n"
--> "\r\n"
-Conn close
-opening connection to train.cashnet.com:443...
-opened
-starting SSL for train.cashnet.com:443...
-SSL established
-<- "GET /cashneti/Gateway/htmlgw.aspx?client=EMARKETVENDOR_DEMO&command=SALE&merchant=GiveCorpGW&operator=givecorp&password=[FILTERED]&station=WEB&custcode=ActiveMerchant%2f1.76.0&cardno=[FILTERED]&cid=[FILTERED]&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2cApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: train.cashnet.com\r\n\r\n"
--> "HTTP/1.1 200 OK\r\n"
--> "Date: Wed, 03 Jan 2018 17:03:35 GMT\r\n"
--> "Content-Type: text/html; charset=utf-8\r\n"
--> "Transfer-Encoding: chunked\r\n"
--> "Connection: close\r\n"
--> "Set-Cookie: AWSALB=lFPwFYRnXJHRNmE6NCRAIfHtQadwx4bYJoT5xeAL5AuAXPcm1vYWx5F/s5FBr3GcungifktpWlwIgAmWS29K7YRXTCjk4xmcAnhXS86fpVUVQt4ECwPH2xdv8tf2; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
--> "Set-Cookie: AWSALB=mEfysFNBclo1/9+tTuI/XtHrmVkD89Fh6tAJ3Gl0u2EuLCYTW5VwEq+fVqYG1fEkN02dbhKSkIdM22QvyT6cRccDaUBsYAnOKjg2JlVShJlf+li5tfbrsUDk14jG; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
--> "Cache-Control: private\r\n"
--> "Set-Cookie: ASP.NET_SessionId=3ocslggtk4cdz54unbdnm25o; path=/; HttpOnly\r\n"
--> "P3P: CP=\"NOI DSP COR NID NOR\"\r\n"
--> "Set-Cookie: BNI_persistence=0000000000000000000000004d79da0a00005000; Path=/\r\n"
--> "Strict-Transport-Security: max-age=31536000\r\n"
--> "\r\n"
--> "3a\r\n"
-reading 58 bytes...
--> "result=0&tx=77972&busdate=7/25/2017"
-read 58 bytes
-reading 2 bytes...
--> "\r\n"
-read 2 bytes
--> "0\r\n"
--> "\r\n"
-Conn close
-SCRUBBED
+ <<~SCRUBBED
+ opening connection to train.cashnet.com:443...
+ opened
+ starting SSL for train.cashnet.com:443...
+ SSL established
+ <- "POST /givecorpsgateway HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: train.cashnet.com\r\nContent-Length: 364\r\n\r\n"
+ <- "command=SALE&merchant=GiveCorpGW&operator=givecorp&password=[FILTERED]&station=WEB&custcode=ActiveMerchant%2F1.76.0&cardno=[FILTERED]&cid=[FILTERED]&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2CApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00"
+ -> "HTTP/1.1 302 Found\r\n"
+ -> "Date: Wed, 03 Jan 2018 17:03:35 GMT\r\n"
+ -> "Content-Type: text/html; charset=utf-8\r\n"
+ -> "Transfer-Encoding: chunked\r\n"
+ -> "Connection: close\r\n"
+ -> "Set-Cookie: AWSALB=5ISjTg8Mez7jS1kEnzY4j5NkQ5bdlwDDNmfzTyEMBmILpb0Tn3k58pUQTGHBj3NUpciP0uqQs7FaAb42YZvt35ndLERGJA0dPQ03iCfrqbneQ+Wm5BhDzMGo5GUT; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
+ -> "Set-Cookie: AWSALB=bVhwwfJ2D6cI5zB3eapqNStEzF5yX1pXhaJGUBUCa+DZhEgn/TZGxznxIOYB9qKqzkPF4lq/zxWg/tuMBTiY4JGLRjayyhizvHnj2smrnNvr2DLQN7ZjLSh51BzM; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
+ -> "Cache-Control: private\r\n"
+ -> "Location: https://train.cashnet.com/cashneti/Gateway/htmlgw.aspx?client=EMARKETVENDOR_DEMO&command=SALE&merchant=GiveCorpGW&operator=givecorp&password=[FILTERED]&station=WEB&custcode=ActiveMerchant%2f1.76.0&cardno=[FILTERED]&cid=[FILTERED]&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2cApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00\r\n"
+ -> "Set-Cookie: ASP.NET_SessionId=; path=/; HttpOnly\r\n"
+ -> "P3P: CP=\"NOI DSP COR NID NOR\"\r\n"
+ -> "Set-Cookie: BNI_persistence=0000000000000000000000004d79da0a00005000; Path=/\r\n"
+ -> "Strict-Transport-Security: max-age=31536000\r\n"
+ -> "\r\n"
+ -> "282\r\n"
+ reading 642 bytes...
+ -> "Object moved\r\nObject moved to here.
\r\n\r\n"
+ read 642 bytes
+ reading 2 bytes...
+ -> "\r\n"
+ read 2 bytes
+ -> "0\r\n"
+ -> "\r\n"
+ Conn close
+ opening connection to train.cashnet.com:443...
+ opened
+ starting SSL for train.cashnet.com:443...
+ SSL established
+ <- "GET /cashneti/Gateway/htmlgw.aspx?client=EMARKETVENDOR_DEMO&command=SALE&merchant=GiveCorpGW&operator=givecorp&password=[FILTERED]&station=WEB&custcode=ActiveMerchant%2f1.76.0&cardno=[FILTERED]&cid=[FILTERED]&expdate=1215&card_name_g=Longbob+Longsen&fname=Longbob&lname=Longsen&order_number=c440ec8493f215d21c8a993ceae30129&itemcode=FEE&addr_g=456+My+Street%2cApt+1&city_g=Ottawa&state_g=ON&zip_g=K1C2N6&email_g=&amount=1.00 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: train.cashnet.com\r\n\r\n"
+ -> "HTTP/1.1 200 OK\r\n"
+ -> "Date: Wed, 03 Jan 2018 17:03:35 GMT\r\n"
+ -> "Content-Type: text/html; charset=utf-8\r\n"
+ -> "Transfer-Encoding: chunked\r\n"
+ -> "Connection: close\r\n"
+ -> "Set-Cookie: AWSALB=lFPwFYRnXJHRNmE6NCRAIfHtQadwx4bYJoT5xeAL5AuAXPcm1vYWx5F/s5FBr3GcungifktpWlwIgAmWS29K7YRXTCjk4xmcAnhXS86fpVUVQt4ECwPH2xdv8tf2; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
+ -> "Set-Cookie: AWSALB=mEfysFNBclo1/9+tTuI/XtHrmVkD89Fh6tAJ3Gl0u2EuLCYTW5VwEq+fVqYG1fEkN02dbhKSkIdM22QvyT6cRccDaUBsYAnOKjg2JlVShJlf+li5tfbrsUDk14jG; Expires=Wed, 10 Jan 2018 17:03:35 GMT; Path=/\r\n"
+ -> "Cache-Control: private\r\n"
+ -> "Set-Cookie: ASP.NET_SessionId=3ocslggtk4cdz54unbdnm25o; path=/; HttpOnly\r\n"
+ -> "P3P: CP=\"NOI DSP COR NID NOR\"\r\n"
+ -> "Set-Cookie: BNI_persistence=0000000000000000000000004d79da0a00005000; Path=/\r\n"
+ -> "Strict-Transport-Security: max-age=31536000\r\n"
+ -> "\r\n"
+ -> "3a\r\n"
+ reading 58 bytes...
+ -> "result=0&tx=77972&busdate=7/25/2017"
+ read 58 bytes
+ reading 2 bytes...
+ -> "\r\n"
+ read 2 bytes
+ -> "0\r\n"
+ -> "\r\n"
+ Conn close
+ SCRUBBED
end
end
diff --git a/test/unit/gateways/cecabank_rest_json_test.rb b/test/unit/gateways/cecabank_rest_json_test.rb
new file mode 100644
index 00000000000..87ba73ef771
--- /dev/null
+++ b/test/unit/gateways/cecabank_rest_json_test.rb
@@ -0,0 +1,236 @@
+require 'test_helper'
+
+class CecabankJsonTest < Test::Unit::TestCase
+ include CommStub
+
+ def setup
+ @gateway = CecabankJsonGateway.new(
+ merchant_id: '12345678',
+ acquirer_bin: '12345678',
+ terminal_id: '00000003',
+ cypher_key: 'enc_key'
+ )
+
+ @credit_card = credit_card
+ @amount = 100
+
+ @options = {
+ order_id: '1',
+ description: 'Store Purchase'
+ }
+ end
+
+ def test_successful_authorize
+ @gateway.expects(:ssl_request).returns(successful_authorize_response)
+
+ assert response = @gateway.authorize(@amount, @credit_card, @options)
+ assert_instance_of Response, response
+ assert_success response
+ assert_equal '12004172282310181802446007000#1#100', response.authorization
+ assert response.test?
+ end
+
+ def test_failed_authorize
+ @gateway.expects(:ssl_request).returns(failed_authorize_response)
+ response = @gateway.authorize(@amount, @credit_card, @options)
+
+ assert_failure response
+ assert_equal '27', response.error_code
+ end
+
+ def test_successful_capture
+ @gateway.expects(:ssl_request).returns(successful_capture_response)
+
+ assert response = @gateway.capture(@amount, 'reference', @options)
+ assert_instance_of Response, response
+ assert_success response
+ assert_equal '12204172322310181826516007000#1#100', response.authorization
+ assert response.test?
+ end
+
+ def test_failed_capture
+ @gateway.expects(:ssl_request).returns(failed_capture_response)
+ response = @gateway.capture(@amount, 'reference', @options)
+
+ assert_failure response
+ assert_equal '807', response.error_code
+ end
+
+ def test_successful_purchase
+ @gateway.expects(:ssl_request).returns(successful_purchase_response)
+
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
+ assert_instance_of Response, response
+ assert_success response
+ assert_equal '12004172192310181720006007000#1#100', response.authorization
+ assert response.test?
+ end
+
+ def test_failed_purchase
+ @gateway.expects(:ssl_request).returns(failed_purchase_response)
+ response = @gateway.purchase(@amount, @credit_card, @options)
+
+ assert_failure response
+ assert_equal '27', response.error_code
+ end
+
+ def test_successful_refund
+ @gateway.expects(:ssl_request).returns(successful_refund_response)
+
+ assert response = @gateway.refund(@amount, 'reference', @options)
+ assert_instance_of Response, response
+ assert_success response
+ assert_equal '12204172352310181847426007000#1#100', response.authorization
+ assert response.test?
+ end
+
+ def test_failed_refund
+ @gateway.expects(:ssl_request).returns(failed_refund_response)
+
+ assert response = @gateway.refund(@amount, 'reference', @options)
+ assert_failure response
+ assert response.test?
+ end
+
+ def test_successful_void
+ @gateway.expects(:ssl_request).returns(successful_void_response)
+
+ assert response = @gateway.void('12204172352310181847426007000#1#10', @options)
+ assert_instance_of Response, response
+ assert_success response
+ assert_equal '14204172402310181906166007000#1#10', response.authorization
+ assert response.test?
+ end
+
+ def test_failed_void
+ @gateway.expects(:ssl_request).returns(failed_void_response)
+
+ assert response = @gateway.void('reference', @options)
+ assert_failure response
+ assert response.test?
+ end
+
+ def test_transcript_scrubbing
+ assert_equal scrubbed_transcript, @gateway.scrub(transcript)
+ end
+
+ private
+
+ def transcript
+ "opening connection to tpv.ceca.es:443...\nopened\nstarting SSL for tpv.ceca.es:443...\nSSL established, protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384\n<- \"POST /tpvweb/rest/procesos/compra HTTP/1.1\\r\\nContent-Type: application/json\\r\\nHost: tpv.ceca.es\\r\\nConnection: close\\r\\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\\r\\nAccept: */*\\r\\nUser-Agent: Ruby\\r\\nContent-Length: 1145\\r\\n\\r\\n\"\n<- \"{\\\"parametros\\\":\\\"eyJhY2Npb24iOiJSRVNUX0FVVE9SSVpBQ0lPTiIsIm51bU9wZXJhY2lvbiI6IjcwNDBhYjJhMGFkOTQ5NmM2MjhiMTAyZTgzNzEyMGIxIiwiaW1wb3J0ZSI6IjEwMCIsInRpcG9Nb25lZGEiOiI5NzgiLCJleHBvbmVudGUiOiIyIiwicGFuIjoiNDUwNzY3MDAwMTAwMDAwOSIsImNhZHVjaWRhZCI6IjIwMjMxMiIsImN2djIiOiI5ODkiLCJleGVuY2lvblNDQSI6bnVsbCwiVGhyZWVEc1Jlc3BvbnNlIjoie1wiZXhlbXB0aW9uX3R5cGVcIjpudWxsLFwidGhyZWVfZHNfdmVyc2lvblwiOlwiMi4yLjBcIixcImF1dGhlbnRpY2F0aW9uX3ZhbHVlXCI6XCI0RjgwREY1MEFEQjBGOTUwMkI5MTYxOEU5QjcwNDc5MEVBQkEzNUZERkM5NzJEREREMEJGNDk4QzZBNzVFNDkyXCIsXCJkaXJlY3Rvcnlfc2VydmVyX3RyYW5zYWN0aW9uX2lkXCI6XCJhMmJmMDg5Zi1jZWZjLTRkMmMtODUwZi05MTUzODI3ZmUwNzBcIixcImFjc190cmFuc2FjdGlvbl9pZFwiOlwiMThjMzUzYjAtNzZlMy00YTRjLTgwMzMtZjE0ZmU5Y2UzOWRjXCIsXCJhdXRoZW50aWNhdGlvbl9yZXNwb25zZV9zdGF0dXNcIjpcIllcIixcInRocmVlX2RzX3NlcnZlcl90cmFuc19pZFwiOlwiOWJkOWFhOWMtM2JlYi00MDEyLThlNTItMjE0Y2NjYjI1ZWM1XCIsXCJlY29tbWVyY2VfaW5kaWNhdG9yXCI6XCIwMlwiLFwiZW5yb2xsZWRcIjpudWxsLFwiYW1vdW50XCI6XCIxMDBcIn0iLCJtZXJjaGFudElEIjoiMTA2OTAwNjQwIiwiYWNxdWlyZXJCSU4iOiIwMDAwNTU0MDAwIiwidGVybWluYWxJRCI6IjAwMDAwMDAzIn0=\\\",\\\"cifrado\\\":\\\"SHA2\\\",\\\"firma\\\":\\\"712cc9dcc17af686d220f36d68605f91e27fb0ffee448d2d8701aaa9a5068448\\\"}\"\n-> \"HTTP/1.1 200 OK\\r\\n\"\n-> \"Date: Sat, 04 Nov 2023 00:34:09 GMT\\r\\n\"\n-> \"Server: Apache\\r\\n\"\n-> \"Strict-Transport-Security: max-age=31536000; includeSubDomains\\r\\n\"\n-> \"X-XSS-Protection: 1; mode=block\\r\\n\"\n-> \"X-Content-Type-Options: nosniff\\r\\n\"\n-> \"Content-Length: 300\\r\\n\"\n-> \"Connection: close\\r\\n\"\n-> \"Content-Type: application/json\\r\\n\"\n-> \"\\r\\n\"\nreading 300 bytes...\n-> \"{\\\"cifrado\\\":\\\"SHA2\\\",\\\"parametros\\\":\\\"eyJudW1BdXQiOiIxMDEwMDAiLCJyZWZlcmVuY2lhIjoiMTIwMDQyMjM3MTIzMTEwNDAxMzQxMDYwMDcwMDAiLCJjb2RBdXQiOiIwMDAifQ==\\\",\\\"firma\\\":\\\"6be9465e38a4bd28935688fdd3e34cf703c4f23f0e104eae03824838efa583b5\\\",\\\"fecha\\\":\\\"231104013412182\\\",\\\"idProceso\\\":\\\"106900640-7040ab2a0ad9496c628b102e837120b1\\\"}\"\nread 300 bytes\nConn close\n"
+ end
+
+ def scrubbed_transcript
+ "opening connection to tpv.ceca.es:443...\nopened\nstarting SSL for tpv.ceca.es:443...\nSSL established, protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384\n<- \"POST /tpvweb/rest/procesos/compra HTTP/1.1\\r\\nContent-Type: application/json\\r\\nHost: tpv.ceca.es\\r\\nConnection: close\\r\\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\\r\\nAccept: */*\\r\\nUser-Agent: Ruby\\r\\nContent-Length: 1145\\r\\n\\r\\n\"\n<- \"{\\\"parametros\\\":\\\"eyJhY2Npb24iOiJSRVNUX0FVVE9SSVpBQ0lPTiIsIm51bU9wZXJhY2lvbiI6IjcwNDBhYjJhMGFkOTQ5NmM2MjhiMTAyZTgzNzEyMGIxIiwiaW1wb3J0ZSI6IjEwMCIsInRpcG9Nb25lZGEiOiI5NzgiLCJleHBvbmVudGUiOiIyIiwicGFuIjoiW0ZJTFRFUkVEXSIsImNhZHVjaWRhZCI6IltGSUxURVJFRF0iLCJjdnYyIjoiW0ZJTFRFUkVEXSIsImV4ZW5jaW9uU0NBIjpudWxsLCJUaHJlZURzUmVzcG9uc2UiOiJ7XCJleGVtcHRpb25fdHlwZVwiOm51bGwsXCJ0aHJlZV9kc192ZXJzaW9uXCI6XCIyLjIuMFwiLFwiYXV0aGVudGljYXRpb25fdmFsdWVcIjpcIjRGODBERjUwQURCMEY5NTAyQjkxNjE4RTlCNzA0NzkwRUFCQTM1RkRGQzk3MkREREQwQkY0OThDNkE3NUU0OTJcIixcImRpcmVjdG9yeV9zZXJ2ZXJfdHJhbnNhY3Rpb25faWRcIjpcImEyYmYwODlmLWNlZmMtNGQyYy04NTBmLTkxNTM4MjdmZTA3MFwiLFwiYWNzX3RyYW5zYWN0aW9uX2lkXCI6XCIxOGMzNTNiMC03NmUzLTRhNGMtODAzMy1mMTRmZTljZTM5ZGNcIixcImF1dGhlbnRpY2F0aW9uX3Jlc3BvbnNlX3N0YXR1c1wiOlwiWVwiLFwidGhyZWVfZHNfc2VydmVyX3RyYW5zX2lkXCI6XCI5YmQ5YWE5Yy0zYmViLTQwMTItOGU1Mi0yMTRjY2NiMjVlYzVcIixcImVjb21tZXJjZV9pbmRpY2F0b3JcIjpcIjAyXCIsXCJlbnJvbGxlZFwiOm51bGwsXCJhbW91bnRcIjpcIjEwMFwifSIsIm1lcmNoYW50SUQiOiIxMDY5MDA2NDAiLCJhY3F1aXJlckJJTiI6IjAwMDA1NTQwMDAiLCJ0ZXJtaW5hbElEIjoiMDAwMDAwMDMifQ==\\\",\\\"cifrado\\\":\\\"SHA2\\\",\\\"firma\\\":\\\"712cc9dcc17af686d220f36d68605f91e27fb0ffee448d2d8701aaa9a5068448\\\"}\"\n-> \"HTTP/1.1 200 OK\\r\\n\"\n-> \"Date: Sat, 04 Nov 2023 00:34:09 GMT\\r\\n\"\n-> \"Server: Apache\\r\\n\"\n-> \"Strict-Transport-Security: max-age=31536000; includeSubDomains\\r\\n\"\n-> \"X-XSS-Protection: 1; mode=block\\r\\n\"\n-> \"X-Content-Type-Options: nosniff\\r\\n\"\n-> \"Content-Length: 300\\r\\n\"\n-> \"Connection: close\\r\\n\"\n-> \"Content-Type: application/json\\r\\n\"\n-> \"\\r\\n\"\nreading 300 bytes...\n-> \"{\\\"cifrado\\\":\\\"SHA2\\\",\\\"parametros\\\":\\\"eyJudW1BdXQiOiIxMDEwMDAiLCJyZWZlcmVuY2lhIjoiMTIwMDQyMjM3MTIzMTEwNDAxMzQxMDYwMDcwMDAiLCJjb2RBdXQiOiIwMDAifQ==\\\",\\\"firma\\\":\\\"6be9465e38a4bd28935688fdd3e34cf703c4f23f0e104eae03824838efa583b5\\\",\\\"fecha\\\":\\\"231104013412182\\\",\\\"idProceso\\\":\\\"106900640-7040ab2a0ad9496c628b102e837120b1\\\"}\"\nread 300 bytes\nConn close\n"
+ end
+
+ def successful_authorize_response
+ <<~RESPONSE
+ {
+ "cifrado":"SHA2",
+ "parametros":"eyJudW1BdXQiOiIxMDEwMDAiLCJyZWZlcmVuY2lhIjoiMTIwMDQxNzIyODIzMTAxODE4MDI0NDYwMDcwMDAiLCJjb2RBdXQiOiIwMDAifQ==",
+ "firma":"2271f18614f9e3bf1f1d0bde7c23d2d9b576087564fd6cb4474f14f5727eaff2",
+ "fecha":"231018180245479",
+ "idProceso":"106900640-9da0de26e0e81697f7629566b99a1b73"
+ }
+ RESPONSE
+ end
+
+ def failed_authorize_response
+ <<~RESPONSE
+ {
+ "fecha":"231018180927186",
+ "idProceso":"106900640-9cfe017407164563ca5aa7a0877d2ade",
+ "codResult":"27"
+ }
+ RESPONSE
+ end
+
+ def successful_capture_response
+ <<~RESPONSE
+ {
+ "cifrado":"SHA2",
+ "parametros":"eyJudW1BdXQiOiIxMDEwMDAiLCJyZWZlcmVuY2lhIjoiMTIyMDQxNzIzMjIzMTAxODE4MjY1MTYwMDcwMDAiLCJjb2RBdXQiOiI5MDAifQ==",
+ "firma":"9dead8ef2bf1f82cde1954cefaa9eca67b630effed7f71a5fd3bb3bd2e6e0808",
+ "fecha":"231018182651711",
+ "idProceso":"106900640-5b03c604fd76ecaf8715a29c482f3040"
+ }
+ RESPONSE
+ end
+
+ def failed_capture_response
+ <<~RESPONSE
+ {
+ "fecha":"231018183020560",
+ "idProceso":"106900640-d0cab45d2404960b65fe02445e97b7e2",
+ "codResult":"807"
+ }
+ RESPONSE
+ end
+
+ def successful_purchase_response
+ <<~RESPONSE
+ {
+ "cifrado":"SHA2",
+ "parametros":"eyJudW1BdXQiOiIxMDEwMDAiLCJyZWZlcmVuY2lhIjoiMTIwMDQxNzIxOTIzMTAxODE3MjAwMDYwMDcwMDAiLCJjb2RBdXQiOiIwMDAifQ==",
+ "firma":"da751ff809f54842ff26aed009cdce2d1a3b613cb3be579bb17af2e3ab36aa37",
+ "fecha":"231018172001775",
+ "idProceso":"106900640-bd4bd321774c51ec91cf24ca6bbca913"
+ }
+ RESPONSE
+ end
+
+ def failed_purchase_response
+ <<~RESPONSE
+ {
+ "fecha":"231018174516102",
+ "idProceso":"106900640-29c9d010e2e8c33872a4194df4e7a544",
+ "codResult":"27"
+ }
+ RESPONSE
+ end
+
+ def successful_refund_response
+ <<~RESPONSE
+ {
+ "cifrado":"SHA2",
+ "parametros":"eyJtZXJjaGFudElEIjoiMTA2OTAwNjQwIiwiYWNxdWlyZXJCSU4iOiIwMDAwNTU0MDAwIiwidGVybWluYWxJRCI6IjAwMDAwMDAzIiwibnVtT3BlcmFjaW9uIjoiOGYyOTJiYTcwMmEzMTZmODIwMmEzZGFjY2JhMjFmZWMiLCJpbXBvcnRlIjoiMTAwIiwibnVtQXV0IjoiMTAxMDAwIiwicmVmZXJlbmNpYSI6IjEyMjA0MTcyMzUyMzEwMTgxODQ3NDI2MDA3MDAwIiwidGlwb09wZXJhY2lvbiI6IkQiLCJwYWlzIjoiMDAwIiwiY29kQXV0IjoiOTAwIn0=",
+ "firma":"37591482e4d1dce6317c6d7de6a6c9b030c0618680eaefb4b42b0d8af3854773",
+ "fecha":"231018184743876",
+ "idProceso":"106900640-8f292ba702a316f8202a3daccba21fec"
+ }
+ RESPONSE
+ end
+
+ def failed_refund_response
+ <<~RESPONSE
+ {
+ "fecha":"231018185809202",
+ "idProceso":"106900640-fc93d837dba2003ad767d682e6eb5d5f",
+ "codResult":"15"
+ }
+ RESPONSE
+ end
+
+ def successful_void_response
+ <<~RESPONSE
+ {
+ "cifrado":"SHA2",
+ "parametros":"eyJtZXJjaGFudElEIjoiMTA2OTAwNjQwIiwiYWNxdWlyZXJCSU4iOiIwMDAwNTU0MDAwIiwidGVybWluYWxJRCI6IjAwMDAwMDAzIiwibnVtT3BlcmFjaW9uIjoiMDNlMTkwNTU4NWZlMmFjM2M4N2NiYjY4NGUyMjYwZDUiLCJpbXBvcnRlIjoiMTAwIiwibnVtQXV0IjoiMTAxMDAwIiwicmVmZXJlbmNpYSI6IjE0MjA0MTcyNDAyMzEwMTgxOTA2MTY2MDA3MDAwIiwidGlwb09wZXJhY2lvbiI6IkQiLCJwYWlzIjoiMDAwIiwiY29kQXV0IjoiNDAwIn0=",
+ "firma":"af55904b24cb083e6514b86456b107fdb8ebfc715aed228321ad959b13ef2b23",
+ "fecha":"231018190618224",
+ "idProceso":"106900640-03e1905585fe2ac3c87cbb684e2260d5"
+ }
+ RESPONSE
+ end
+
+ def failed_void_response
+ <<~RESPONSE
+ {
+ "fecha":"231018191116348",
+ "idProceso":"106900640-d7ca10f4fae36b2ad81f330eeb1ce509",
+ "codResult":"15"
+ }
+ RESPONSE
+ end
+end
diff --git a/test/unit/gateways/cecabank_test.rb b/test/unit/gateways/cecabank_test.rb
index 87ad7e20ab5..e2bfe3c749e 100644
--- a/test/unit/gateways/cecabank_test.rb
+++ b/test/unit/gateways/cecabank_test.rb
@@ -4,19 +4,19 @@ class CecabankTest < Test::Unit::TestCase
include CommStub
def setup
- @gateway = CecabankGateway.new(
- :merchant_id => '12345678',
- :acquirer_bin => '12345678',
- :terminal_id => '00000003',
- :key => 'enc_key'
+ @gateway = CecabankXmlGateway.new(
+ merchant_id: '12345678',
+ acquirer_bin: '12345678',
+ terminal_id: '00000003',
+ cypher_key: 'enc_key'
)
@credit_card = credit_card
@amount = 100
@options = {
- :order_id => '1',
- :description => 'Store Purchase'
+ order_id: '1',
+ description: 'Store Purchase'
}
end
@@ -43,7 +43,7 @@ def test_invalid_xml_response_handling
def test_expiration_date_sent_correctly
stub_comms do
@gateway.purchase(@amount, credit_card('4242424242424242', month: 1, year: 2014), @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/Caducidad=201401&/, data, 'Expected expiration date format is yyyymm')
end.respond_with(successful_purchase_response)
end
@@ -81,60 +81,60 @@ def test_transcript_scrubbing
private
def successful_purchase_response
- <<-RESPONSE
-
-
-
- 171.00 Euros
-
- 101000
- 12345678901234567890
- ##PAN##
-
-
+ <<~RESPONSE
+
+
+
+ 171.00 Euros
+
+ 101000
+ 12345678901234567890
+ ##PAN##
+
+
RESPONSE
end
def failed_purchase_response
- <<-RESPONSE
-
-
-
- 27
-
-
-
+ <<~RESPONSE
+
+
+
+ 27
+
+
+
RESPONSE
end
def invalid_xml_purchase_response
- <<-RESPONSE
-
-
-Invalid unparsable xml in the response
+ <<~RESPONSE
+
+
+ Invalid unparsable xml in the response
RESPONSE
end
def successful_refund_response
- <<-RESPONSE
-
-
-
- 1.00 Euros
-
-
+ <<~RESPONSE
+
+
+
+ 1.00 Euros
+
+
RESPONSE
end
def failed_refund_response
- <<-RESPONSE
-
-
-
- 15
- ]]>
-
-
+ <<~RESPONSE
+
+
+
+ 15
+ ]]>
+
+
RESPONSE
end
diff --git a/test/unit/gateways/cenpos_test.rb b/test/unit/gateways/cenpos_test.rb
index 950701578bd..0fd8f452a1b 100644
--- a/test/unit/gateways/cenpos_test.rb
+++ b/test/unit/gateways/cenpos_test.rb
@@ -5,9 +5,9 @@ class CenposTest < Test::Unit::TestCase
def setup
@gateway = CenposGateway.new(
- :merchant_id => 'merchant_id',
- :password => 'password',
- :user_id => 'user_id'
+ merchant_id: 'merchant_id',
+ password: 'password',
+ user_id: 'user_id'
)
@credit_card = credit_card
@@ -115,7 +115,7 @@ def test_successful_authorize_and_capture
capture = stub_comms do
@gateway.capture(@amount, response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/1760035844/, data)
end.respond_with(successful_capture_response)
@@ -151,7 +151,7 @@ def test_successful_void
void = stub_comms do
@gateway.void(response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/1760035844/, data)
end.respond_with(successful_void_response)
@@ -161,7 +161,7 @@ def test_successful_void
def test_failed_void
response = stub_comms do
@gateway.void('1758584451|4242|1.00')
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/1758584451/, data)
end.respond_with(failed_void_response)
@@ -178,7 +178,7 @@ def test_successful_refund
refund = stub_comms do
@gateway.refund(@amount, response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/1609995363/, data)
end.respond_with(successful_refund_response)
diff --git a/test/unit/gateways/checkout_test.rb b/test/unit/gateways/checkout_test.rb
index ab70056694e..d58e55ee55e 100644
--- a/test/unit/gateways/checkout_test.rb
+++ b/test/unit/gateways/checkout_test.rb
@@ -5,8 +5,8 @@ class CheckoutTest < Test::Unit::TestCase
def setup
@gateway = ActiveMerchant::Billing::CheckoutGateway.new(
- :merchant_id => 'SBMTEST', # Merchant Code
- :password => 'Password1!' # Processing Password
+ merchant_id: 'SBMTEST', # Merchant Code
+ password: 'Password1!' # Processing Password
)
@options = {
order_id: generate_unique_id
@@ -72,21 +72,20 @@ def test_unsuccessful_purchase
def test_passes_correct_currency
stub_comms do
- @gateway.purchase(100, credit_card, @options.merge(
- currency: 'EUR'
- ))
- end.check_request do |endpoint, data, headers|
+ @gateway.purchase(100, credit_card, @options.merge(currency: 'EUR'))
+ end.check_request do |_endpoint, data, _headers|
assert_match(/EUR<\/bill_currencycode>/, data)
end.respond_with(successful_purchase_response)
end
def test_passes_descriptors
+ options = @options.merge(
+ descriptor_name: 'ZahName',
+ descriptor_city: 'Oakland'
+ )
stub_comms do
- @gateway.purchase(100, credit_card, @options.merge(
- descriptor_name: 'ZahName',
- descriptor_city: 'Oakland'
- ))
- end.check_request do |endpoint, data, headers|
+ @gateway.purchase(100, credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
assert_match(/ZahName<\/descriptor_name>/, data)
assert_match(/Oakland<\/descriptor_city>/, data)
end.respond_with(successful_purchase_response)
@@ -96,7 +95,7 @@ def test_successful_void
@options['orderid'] = '9c38d0506da258e216fa072197faaf37'
void = stub_comms(@gateway, :ssl_request) do
@gateway.void('36919371|9c38d0506da258e216fa072197faaf37|1|CAD|100', @options)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
# Should only be one pair of track id tags.
assert_equal 2, data.scan(/trackid/).count
end.respond_with(successful_void_response)
diff --git a/test/unit/gateways/checkout_v2_test.rb b/test/unit/gateways/checkout_v2_test.rb
index bb3f1eda89a..f6c33802138 100644
--- a/test/unit/gateways/checkout_v2_test.rb
+++ b/test/unit/gateways/checkout_v2_test.rb
@@ -7,23 +7,37 @@ def setup
@gateway = CheckoutV2Gateway.new(
secret_key: '1111111111111'
)
-
+ @gateway_oauth = CheckoutV2Gateway.new({ client_id: 'abcd', client_secret: '1234', access_token: '12345678' })
+ @gateway_api = CheckoutV2Gateway.new({
+ secret_key: '1111111111111',
+ public_key: '2222222222222'
+ })
@credit_card = credit_card
@amount = 100
+ @token = '2MPedsuenG2o8yFfrsdOBWmOuEf'
+ end
+
+ def test_setup_access_token_should_rise_an_exception_under_bad_request
+ error = assert_raises(ActiveMerchant::OAuthResponseError) do
+ @gateway.expects(:raw_ssl_request).returns(Net::HTTPBadRequest.new(1.0, 400, 'Bad Request'))
+ @gateway.send(:setup_access_token)
+ end
+
+ assert_match(/Failed with 400 Bad Request/, error.message)
end
def test_successful_purchase
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card)
end.respond_with(successful_purchase_response)
assert_success response
- assert_equal 'charge_test_941CA9CE174U76BD29C8', response.authorization
+ assert_equal 'pay_bgv5tmah6fmuzcmcrcro6exe6m', response.authorization
assert response.test?
end
def test_successful_purchase_includes_avs_result
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card)
end.respond_with(successful_purchase_response)
@@ -34,15 +48,228 @@ def test_successful_purchase_includes_avs_result
end
def test_successful_purchase_includes_cvv_result
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card)
end.respond_with(successful_purchase_response)
assert_equal 'Y', response.cvv_result['code']
end
+ def test_successful_purchase_using_vts_network_token_without_eci
+ network_token = network_tokenization_credit_card(
+ '4242424242424242',
+ { source: :network_token, brand: 'visa' }
+ )
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, network_token)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+
+ assert_equal(request_data['source']['type'], 'network_token')
+ assert_equal(request_data['source']['token'], network_token.number)
+ assert_equal(request_data['source']['token_type'], 'vts')
+ assert_equal(request_data['source']['eci'], '05')
+ assert_equal(request_data['source']['cryptogram'], network_token.payment_cryptogram)
+ end.respond_with(successful_purchase_with_network_token_response)
+
+ assert_success response
+ assert_equal '2FCFE326D92D4C27EDD699560F484', response.params['source']['payment_account_reference']
+ assert response.test?
+ end
+
+ def test_successful_passing_processing_channel_id
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, { processing_channel_id: '123456abcde' })
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+ assert_equal(request_data['processing_channel_id'], '123456abcde')
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_successful_passing_incremental_authorization
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.authorize(@amount, @credit_card, { incremental_authorization: 'abcd1234' })
+ end.check_request do |_method, endpoint, _data, _headers|
+ assert_include endpoint, 'abcd1234'
+ end.respond_with(successful_incremental_authorize_response)
+
+ assert_success response
+ end
+
+ def test_successful_passing_authorization_type
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, { authorization_type: 'Estimated' })
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+ assert_equal(request_data['authorization_type'], 'Estimated')
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_successful_passing_exemption_and_challenge_indicator
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, { execute_threed: true, exemption: 'no_preference', challenge_indicator: 'trusted_listing' })
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+ assert_equal(request_data['3ds']['exemption'], 'no_preference')
+ assert_equal(request_data['3ds']['challenge_indicator'], 'trusted_listing')
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_successful_passing_capture_type
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.capture(@amount, 'abc', { capture_type: 'NonFinal' })
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+ assert_equal(request_data['capture_type'], 'NonFinal')
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_successful_purchase_using_vts_network_token_with_eci
+ network_token = network_tokenization_credit_card(
+ '4242424242424242',
+ { source: :network_token, brand: 'visa', eci: '06' }
+ )
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, network_token)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+
+ assert_equal(request_data['source']['type'], 'network_token')
+ assert_equal(request_data['source']['token'], network_token.number)
+ assert_equal(request_data['source']['token_type'], 'vts')
+ assert_equal(request_data['source']['eci'], '06')
+ assert_equal(request_data['source']['cryptogram'], network_token.payment_cryptogram)
+ end.respond_with(successful_purchase_with_network_token_response)
+
+ assert_success response
+ assert_equal '2FCFE326D92D4C27EDD699560F484', response.params['source']['payment_account_reference']
+ assert response.test?
+ end
+
+ def test_successful_purchase_using_mdes_network_token
+ network_token = network_tokenization_credit_card(
+ '5436031030606378',
+ { source: :network_token, brand: 'master' }
+ )
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, network_token)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+
+ assert_equal(request_data['source']['type'], 'network_token')
+ assert_equal(request_data['source']['token'], network_token.number)
+ assert_equal(request_data['source']['token_type'], 'mdes')
+ assert_equal(request_data['source']['eci'], nil)
+ assert_equal(request_data['source']['cryptogram'], network_token.payment_cryptogram)
+ end.respond_with(successful_purchase_with_network_token_response)
+
+ assert_success response
+ assert_equal '2FCFE326D92D4C27EDD699560F484', response.params['source']['payment_account_reference']
+ assert response.test?
+ end
+
+ def test_successful_purchase_using_apple_pay_network_token
+ network_token = network_tokenization_credit_card(
+ '4242424242424242',
+ { source: :apple_pay, eci: '05', payment_cryptogram: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA' }
+ )
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, network_token)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+
+ assert_equal(request_data['source']['type'], 'network_token')
+ assert_equal(request_data['source']['token'], network_token.number)
+ assert_equal(request_data['source']['token_type'], 'applepay')
+ assert_equal(request_data['source']['eci'], '05')
+ assert_equal(request_data['source']['cryptogram'], network_token.payment_cryptogram)
+ end.respond_with(successful_purchase_with_network_token_response)
+
+ assert_success response
+ assert_equal '2FCFE326D92D4C27EDD699560F484', response.params['source']['payment_account_reference']
+ assert response.test?
+ end
+
+ def test_successful_purchase_using_android_pay_network_token
+ network_token = network_tokenization_credit_card(
+ '4242424242424242',
+ { source: :android_pay, eci: '05', payment_cryptogram: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA' }
+ )
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, network_token)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+
+ assert_equal(request_data['source']['type'], 'network_token')
+ assert_equal(request_data['source']['token'], network_token.number)
+ assert_equal(request_data['source']['token_type'], 'googlepay')
+ assert_equal(request_data['source']['eci'], '05')
+ assert_equal(request_data['source']['cryptogram'], network_token.payment_cryptogram)
+ end.respond_with(successful_purchase_with_network_token_response)
+
+ assert_success response
+ assert_equal '2FCFE326D92D4C27EDD699560F484', response.params['source']['payment_account_reference']
+ assert response.test?
+ end
+
+ def test_successful_purchase_using_google_pay_network_token
+ network_token = network_tokenization_credit_card(
+ '4242424242424242',
+ { source: :google_pay, eci: '05', payment_cryptogram: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA' }
+ )
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, network_token)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+
+ assert_equal(request_data['source']['type'], 'network_token')
+ assert_equal(request_data['source']['token'], network_token.number)
+ assert_equal(request_data['source']['token_type'], 'googlepay')
+ assert_equal(request_data['source']['eci'], '05')
+ assert_equal(request_data['source']['cryptogram'], network_token.payment_cryptogram)
+ end.respond_with(successful_purchase_with_network_token_response)
+
+ assert_success response
+ assert_equal '2FCFE326D92D4C27EDD699560F484', response.params['source']['payment_account_reference']
+ assert response.test?
+ end
+
+ def test_successful_purchase_using_google_pay_pan_only_network_token
+ network_token = network_tokenization_credit_card(
+ '4242424242424242',
+ { source: :google_pay }
+ )
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, network_token)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+
+ assert_equal(request_data['source']['type'], 'network_token')
+ assert_equal(request_data['source']['token'], network_token.number)
+ assert_equal(request_data['source']['token_type'], 'googlepay')
+ assert_equal(request_data['source']['eci'], nil)
+ assert_equal(request_data['source']['cryptogram'], nil)
+ end.respond_with(successful_purchase_with_network_token_response)
+
+ assert_success response
+ assert_equal '2FCFE326D92D4C27EDD699560F484', response.params['source']['payment_account_reference']
+ assert response.test?
+ end
+
+ def test_successful_render_for_oauth
+ processing_channel_id = 'abcd123'
+ response = stub_comms(@gateway_oauth, :ssl_request) do
+ @gateway_oauth.purchase(@amount, @credit_card, { processing_channel_id: processing_channel_id })
+ end.check_request do |_method, _endpoint, data, headers|
+ request = JSON.parse(data)
+ assert_equal headers['Authorization'], 'Bearer 12345678'
+ assert_equal request['processing_channel_id'], processing_channel_id
+ end.respond_with(successful_purchase_response)
+ assert_success response
+ end
+
def test_successful_authorize_includes_avs_result
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.authorize(@amount, @credit_card)
end.respond_with(successful_authorize_response)
@@ -53,7 +280,7 @@ def test_successful_authorize_includes_avs_result
end
def test_successful_authorize_includes_cvv_result
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.authorize(@amount, @credit_card)
end.respond_with(successful_authorize_response)
@@ -61,17 +288,28 @@ def test_successful_authorize_includes_cvv_result
end
def test_purchase_with_additional_fields
- response = stub_comms do
- @gateway.purchase(@amount, @credit_card, {descriptor_city: 'london', descriptor_name: 'sherlock'})
- end.check_request do |endpoint, data, headers|
- assert_match(/"descriptor\":{\"name\":\"sherlock\",\"city\":\"london\"}/, data)
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card, { descriptor_city: 'london', descriptor_name: 'sherlock' })
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(/"billing_descriptor\":{\"name\":\"sherlock\",\"city\":\"london\"}/, data)
end.respond_with(successful_purchase_response)
assert_success response
end
+ def test_successful_purchase_passing_metadata_with_mada_card_type
+ @credit_card.brand = 'mada'
+
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, @credit_card)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request_data = JSON.parse(data)
+ assert_equal(request_data['metadata']['udf1'], 'mada')
+ end.respond_with(successful_purchase_response)
+ end
+
def test_failed_purchase
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card)
end.respond_with(failed_purchase_response)
assert_failure response
@@ -79,14 +317,14 @@ def test_failed_purchase
end
def test_successful_authorize_and_capture
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.authorize(@amount, @credit_card)
end.respond_with(successful_authorize_response)
assert_success response
- assert_equal 'charge_test_AF1A29AD350Q748C7EA8', response.authorization
+ assert_equal 'pay_fj3xswqe3emuxckocjx6td73ni', response.authorization
- capture = stub_comms do
+ capture = stub_comms(@gateway, :ssl_request) do
@gateway.capture(@amount, response.authorization)
end.respond_with(successful_capture_response)
@@ -94,23 +332,270 @@ def test_successful_authorize_and_capture
end
def test_successful_authorize_and_capture_with_additional_options
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
options = {
card_on_file: true,
transaction_indicator: 2,
- previous_charge_id: 'charge_123'
+ previous_charge_id: 'pay_123',
+ processing_channel_id: 'pc_123'
+ }
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(%r{"stored":"true"}, data)
+ assert_match(%r{"payment_type":"Recurring"}, data)
+ assert_match(%r{"previous_payment_id":"pay_123"}, data)
+ assert_match(%r{"processing_channel_id":"pc_123"}, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ assert_equal 'pay_fj3xswqe3emuxckocjx6td73ni', response.authorization
+
+ capture = stub_comms(@gateway, :ssl_request) do
+ @gateway.capture(@amount, response.authorization)
+ end.respond_with(successful_capture_response)
+
+ assert_success capture
+ end
+
+ def test_successful_purchase_with_stored_credentials
+ initial_response = stub_comms(@gateway, :ssl_request) do
+ initial_options = {
+ stored_credential: {
+ initiator: 'cardholder',
+ initial_transaction: true,
+ reason_type: 'installment'
+ }
+ }
+ @gateway.purchase(@amount, @credit_card, initial_options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(%r{"payment_type":"Recurring"}, data)
+ assert_match(%r{"merchant_initiated":false}, data)
+ end.respond_with(successful_purchase_initial_stored_credential_response)
+
+ assert_success initial_response
+ assert_equal 'pay_7jcf4ovmwnqedhtldca3fjli2y', initial_response.params['id']
+ network_transaction_id = initial_response.params['id']
+
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ stored_credential: {
+ initial_transaction: false,
+ reason_type: 'recurring',
+ network_transaction_id: network_transaction_id
+ }
+ }
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['previous_payment_id'], 'pay_7jcf4ovmwnqedhtldca3fjli2y'
+ assert_equal request['source']['stored'], true
+ end.respond_with(successful_purchase_using_stored_credential_response)
+
+ assert_success response
+ assert_equal 'Succeeded', response.message
+ end
+
+ def test_successful_purchase_with_stored_credentials_merchant_initiated_transaction_id
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ stored_credential: {
+ initial_transaction: false
+ },
+ merchant_initiated_transaction_id: 'pay_7jcf4ovmwnqedhtldca3fjli2y'
+ }
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['previous_payment_id'], 'pay_7jcf4ovmwnqedhtldca3fjli2y'
+ assert_equal request['source']['stored'], true
+ end.respond_with(successful_purchase_using_stored_credential_response)
+
+ assert_success response
+ assert_equal 'Succeeded', response.message
+ end
+
+ def test_successful_purchase_with_extra_customer_data
+ stub_comms(@gateway, :ssl_request) do
+ options = {
+ phone_country_code: '1',
+ billing_address: address
+ }
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['source']['phone']['number'], '(555)555-5555'
+ assert_equal request['source']['phone']['country_code'], '1'
+ assert_equal request['customer']['name'], 'Longbob Longsen'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_no_customer_name_included_in_token_purchase
+ stub_comms(@gateway, :ssl_request) do
+ options = {
+ phone_country_code: '1',
+ billing_address: address
+ }
+ @gateway.purchase(@amount, @token, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['source']['phone']['number'], '(555)555-5555'
+ assert_equal request['source']['phone']['country_code'], '1'
+ refute_includes data, 'name'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_successful_purchase_with_metadata
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ metadata: {
+ coupon_code: 'NY2018',
+ partner_id: '123989'
+ }
+ }
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(%r{"coupon_code":"NY2018"}, data)
+ assert_match(%r{"partner_id":"123989"}, data)
+ end.respond_with(successful_purchase_using_stored_credential_response)
+
+ assert_success response
+ end
+
+ def test_optional_idempotency_key_header
+ stub_comms(@gateway, :ssl_request) do
+ options = {
+ idempotency_key: 'test123'
+ }
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_method, _url, _data, headers|
+ assert_equal 'test123', headers['Cko-Idempotency-Key']
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_successful_authorize_and_capture_with_metadata
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ metadata: {
+ coupon_code: 'NY2018',
+ partner_id: '123989'
+ }
+ }
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(%r{"coupon_code":"NY2018"}, data)
+ assert_match(%r{"partner_id":"123989"}, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ assert_equal 'pay_fj3xswqe3emuxckocjx6td73ni', response.authorization
+
+ capture = stub_comms(@gateway, :ssl_request) do
+ @gateway.capture(@amount, response.authorization)
+ end.respond_with(successful_capture_response)
+
+ assert_success capture
+ end
+
+ def test_moto_transaction_is_properly_set
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ metadata: {
+ manual_entry: true
+ }
+ }
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(%r{"payment_type":"MOTO"}, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_3ds_passed
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ execute_threed: true,
+ callback_url: 'https://www.example.com'
+ }
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(%r{"success_url"}, data)
+ assert_match(%r{"failure_url"}, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_successful_verify_payment
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.verify_payment('testValue')
+ end.respond_with(successful_verify_payment_response)
+ assert_success response
+ end
+
+ def test_verify_payment_request
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.verify_payment('testValue')
+ end.check_request do |_method, endpoint, data, _headers|
+ assert_equal nil, data
+ assert_equal 'https://api.sandbox.checkout.com/payments/testValue', endpoint
+ end.respond_with(successful_verify_payment_response)
+ assert_success response
+ end
+
+ def test_failed_verify_payment
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.verify_payment('testValue')
+ end.respond_with(failed_verify_payment_response)
+
+ assert_failure response
+ end
+
+ def test_successful_authorize_and_capture_with_3ds
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ execute_threed: true,
+ attempt_n3d: true,
+ three_d_secure: {
+ version: '1.0.2',
+ eci: '05',
+ cryptogram: '1234',
+ xid: '1234',
+ authentication_response_status: 'Y'
+ }
}
@gateway.authorize(@amount, @credit_card, options)
- end.check_request do |endpoint, data, headers|
- assert_match(%r{"cardOnFile":true}, data)
- assert_match(%r{"transactionIndicator":2}, data)
- assert_match(%r{"previousChargeId":"charge_123"}, data)
end.respond_with(successful_authorize_response)
assert_success response
- assert_equal 'charge_test_AF1A29AD350Q748C7EA8', response.authorization
+ assert_equal 'pay_fj3xswqe3emuxckocjx6td73ni', response.authorization
- capture = stub_comms do
+ capture = stub_comms(@gateway, :ssl_request) do
+ @gateway.capture(@amount, response.authorization)
+ end.respond_with(successful_capture_response)
+
+ assert_success capture
+ end
+
+ def test_successful_authorize_and_capture_with_3ds2
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ execute_threed: true,
+ three_d_secure: {
+ version: '2.0.0',
+ eci: '05',
+ cryptogram: '1234',
+ ds_transaction_id: '1234',
+ authentication_response_status: 'Y'
+ }
+ }
+ @gateway.authorize(@amount, @credit_card, options)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ assert_equal 'pay_fj3xswqe3emuxckocjx6td73ni', response.authorization
+
+ capture = stub_comms(@gateway, :ssl_request) do
@gateway.capture(@amount, response.authorization)
end.respond_with(successful_capture_response)
@@ -118,7 +603,7 @@ def test_successful_authorize_and_capture_with_additional_options
end
def test_failed_authorize
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.authorize(@amount, @credit_card)
end.respond_with(failed_authorize_response)
@@ -128,7 +613,7 @@ def test_failed_authorize
end
def test_failed_capture
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.capture(100, '')
end.respond_with(failed_capture_response)
@@ -136,14 +621,38 @@ def test_failed_capture
end
def test_successful_void
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.authorize(@amount, @credit_card)
end.respond_with(successful_authorize_response)
assert_success response
- assert_equal 'charge_test_AF1A29AD350Q748C7EA8', response.authorization
+ assert_equal 'pay_fj3xswqe3emuxckocjx6td73ni', response.authorization
+
+ void = stub_comms(@gateway, :ssl_request) do
+ @gateway.void(response.authorization)
+ end.respond_with(successful_void_response)
+
+ assert_success void
+ end
+
+ def test_successful_void_with_metadata
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ metadata: {
+ coupon_code: 'NY2018',
+ partner_id: '123989'
+ }
+ }
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(%r{"coupon_code":"NY2018"}, data)
+ assert_match(%r{"partner_id":"123989"}, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ assert_equal 'pay_fj3xswqe3emuxckocjx6td73ni', response.authorization
- void = stub_comms do
+ void = stub_comms(@gateway, :ssl_request) do
@gateway.void(response.authorization)
end.respond_with(successful_void_response)
@@ -151,22 +660,173 @@ def test_successful_void
end
def test_failed_void
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.void('5d53a33d960c46d00f5dc061947d998c')
end.respond_with(failed_void_response)
-
assert_failure response
end
+ def test_successfully_passes_fund_type_and_fields
+ options = {
+ funds_transfer_type: 'FD',
+ source_type: 'currency_account',
+ source_id: 'ca_spwmped4qmqenai7hcghquqle4',
+ account_holder_type: 'individual'
+ }
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.credit(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['instruction']['funds_transfer_type'], options[:funds_transfer_type]
+ assert_equal request['source']['type'], options[:source_type]
+ assert_equal request['source']['id'], options[:source_id]
+ assert_equal request['destination']['account_holder']['type'], options[:account_holder_type]
+ assert_equal request['destination']['account_holder']['first_name'], @credit_card.first_name
+ assert_equal request['destination']['account_holder']['last_name'], @credit_card.last_name
+ end.respond_with(successful_credit_response)
+ assert_success response
+ end
+
+ def test_successful_money_transfer_payout_via_credit
+ options = {
+ instruction_purpose: 'leisure',
+ account_holder_type: 'individual',
+ billing_address: address,
+ payout: true,
+ destination: {
+ account_holder: {
+ phone: {
+ number: '9108675309',
+ country_code: '1'
+ },
+ identification: {
+ type: 'passport',
+ number: '1234567890'
+ },
+ email: 'too_many_fields@checkout.com',
+ date_of_birth: '2004-10-27',
+ country_of_birth: 'US'
+ }
+ },
+ sender: {
+ type: 'individual',
+ first_name: 'Jane',
+ middle_name: 'Middle',
+ last_name: 'Doe',
+ reference: '012345',
+ reference_type: 'other',
+ source_of_funds: 'debit',
+ identification: {
+ type: 'passport',
+ number: '0987654321',
+ issuing_country: 'US',
+ date_of_expiry: '2027-07-07'
+ },
+ address: {
+ address1: '205 Main St',
+ address2: 'Apt G',
+ city: 'Winchestertonfieldville',
+ state: 'IA',
+ country: 'US',
+ zip: '12345'
+ },
+ date_of_birth: '2004-10-27',
+ country_of_birth: 'US',
+ nationality: 'US'
+ }
+ }
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.credit(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['instruction']['purpose'], 'leisure'
+ assert_equal request['destination']['account_holder']['phone']['number'], '9108675309'
+ assert_equal request['destination']['account_holder']['phone']['country_code'], '1'
+ assert_equal request['destination']['account_holder']['identification']['number'], '1234567890'
+ assert_equal request['destination']['account_holder']['identification']['type'], 'passport'
+ assert_equal request['destination']['account_holder']['email'], 'too_many_fields@checkout.com'
+ assert_equal request['destination']['account_holder']['date_of_birth'], '2004-10-27'
+ assert_equal request['destination']['account_holder']['country_of_birth'], 'US'
+ assert_equal request['sender']['type'], 'individual'
+ assert_equal request['sender']['first_name'], 'Jane'
+ assert_equal request['sender']['middle_name'], 'Middle'
+ assert_equal request['sender']['last_name'], 'Doe'
+ assert_equal request['sender']['reference'], '012345'
+ assert_equal request['sender']['reference_type'], 'other'
+ assert_equal request['sender']['source_of_funds'], 'debit'
+ assert_equal request['sender']['identification']['type'], 'passport'
+ assert_equal request['sender']['identification']['number'], '0987654321'
+ assert_equal request['sender']['identification']['issuing_country'], 'US'
+ assert_equal request['sender']['identification']['date_of_expiry'], '2027-07-07'
+ assert_equal request['sender']['address']['address_line1'], '205 Main St'
+ assert_equal request['sender']['address']['address_line2'], 'Apt G'
+ assert_equal request['sender']['address']['city'], 'Winchestertonfieldville'
+ assert_equal request['sender']['address']['state'], 'IA'
+ assert_equal request['sender']['address']['country'], 'US'
+ assert_equal request['sender']['address']['zip'], '12345'
+ assert_equal request['sender']['date_of_birth'], '2004-10-27'
+ assert_equal request['sender']['nationality'], 'US'
+ end.respond_with(successful_credit_response)
+ assert_success response
+ end
+
+ def test_transaction_successfully_reverts_to_regular_credit_when_payout_is_nil
+ options = {
+ instruction_purpose: 'leisure',
+ account_holder_type: 'individual',
+ billing_address: address,
+ payout: nil,
+ destination: {
+ account_holder: {
+ email: 'too_many_fields@checkout.com'
+ }
+ },
+ sender: {
+ type: 'individual'
+ }
+ }
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.credit(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ refute_includes data, 'email'
+ refute_includes data, 'sender'
+ end.respond_with(successful_credit_response)
+ assert_success response
+ end
+
def test_successful_refund
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card)
end.respond_with(successful_purchase_response)
assert_success response
- assert_equal 'charge_test_941CA9CE174U76BD29C8', response.authorization
+ assert_equal 'pay_bgv5tmah6fmuzcmcrcro6exe6m', response.authorization
- refund = stub_comms do
+ refund = stub_comms(@gateway, :ssl_request) do
+ @gateway.refund(@amount, response.authorization)
+ end.respond_with(successful_refund_response)
+
+ assert_success refund
+ end
+
+ def test_successful_refund_with_metadata
+ response = stub_comms(@gateway, :ssl_request) do
+ options = {
+ metadata: {
+ coupon_code: 'NY2018',
+ partner_id: '123989'
+ }
+ }
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ assert_match(%r{"coupon_code":"NY2018"}, data)
+ assert_match(%r{"partner_id":"123989"}, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ assert_equal 'pay_bgv5tmah6fmuzcmcrcro6exe6m', response.authorization
+
+ refund = stub_comms(@gateway, :ssl_request) do
@gateway.refund(@amount, response.authorization)
end.respond_with(successful_refund_response)
@@ -174,7 +834,7 @@ def test_successful_refund
end
def test_failed_refund
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.refund(nil, '')
end.respond_with(failed_refund_response)
@@ -182,106 +842,214 @@ def test_failed_refund
end
def test_successful_verify
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.verify(@credit_card)
- end.respond_with(successful_authorize_response, failed_void_response)
+ end.respond_with(successful_verify_response)
assert_success response
assert_equal 'Succeeded', response.message
end
def test_failed_verify
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.verify(@credit_card)
- end.respond_with(failed_authorize_response, successful_void_response)
+ end.respond_with(failed_verify_response)
assert_failure response
- assert_equal 'Invalid Card Number', response.message
+ assert_equal 'request_invalid: card_number_invalid', response.message
+ end
+
+ def test_successful_store
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.store(@credit_card)
+ end.check_request do |_method, endpoint, data, _headers|
+ if /tokens/.match?(endpoint)
+ assert_match(%r{"type":"card"}, data)
+ assert_match(%r{"number":"4242424242424242"}, data)
+ assert_match(%r{"cvv":"123"}, data)
+ assert_match('/tokens', endpoint)
+ elsif /instruments/.match?(endpoint)
+ assert_match(%r{"type":"token"}, data)
+ assert_match(%r{"token":"tok_}, data)
+ end
+ end.respond_with(succesful_token_response, succesful_store_response)
+ end
+
+ def test_successful_tokenize
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.send(:tokenize, @credit_card)
+ end.check_request do |_action, endpoint, data, _headers|
+ assert_match(%r{"type":"card"}, data)
+ assert_match(%r{"number":"4242424242424242"}, data)
+ assert_match(%r{"cvv":"123"}, data)
+ assert_match('/tokens', endpoint)
+ end.respond_with(succesful_token_response)
end
def test_transcript_scrubbing
assert_equal post_scrubbed, @gateway.scrub(pre_scrubbed)
end
+ def test_network_transaction_scrubbing
+ assert_equal network_transaction_post_scrubbed, @gateway.scrub(network_transaction_pre_scrubbed)
+ end
+
def test_invalid_json
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card)
end.respond_with(invalid_json_response)
assert_failure response
- assert_match %r{Invalid JSON response}, response.message
+ assert_match %r{Invalid JSON response received from Checkout.com Unified Payments Gateway. Please contact Checkout.com if you continue to receive this message.}, response.message
end
def test_error_code_returned
- response = stub_comms do
+ response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card)
end.respond_with(error_code_response)
assert_failure response
- assert_match(/70000: 70077/, response.error_code)
+ assert_match(/request_invalid: card_expired/, response.error_code)
+ end
+
+ def test_4xx_error_message
+ @gateway.expects(:ssl_request).raises(error_4xx_response)
+
+ assert response = @gateway.purchase(@amount, @credit_card)
+
+ assert_failure response
+ assert_match(/401: Unauthorized/, response.message)
end
def test_supported_countries
- assert_equal ['AD', 'AE', 'AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FO', 'FI', 'FR', 'GB', 'GI', 'GL', 'GR', 'HR', 'HU', 'IE', 'IS', 'IL', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SM', 'SK', 'SJ', 'TR', 'VA'], @gateway.supported_countries
+ assert_equal %w[AD AE AR AT AU BE BG BH BR CH CL CN CO CY CZ DE DK EE EG ES FI FR GB GR HK HR HU IE IS IT JO JP KW LI LT LU LV MC MT MX MY NL NO NZ OM PE PL PT QA RO SA SE SG SI SK SM TR US], @gateway.supported_countries
+ end
+
+ def test_add_shipping_address
+ options = {
+ shipping_address: address()
+ }
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_method, _endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['shipping']['address']['address_line1'], options[:shipping_address][:address1]
+ assert_equal request['shipping']['address']['address_line2'], options[:shipping_address][:address2]
+ assert_equal request['shipping']['address']['city'], options[:shipping_address][:city]
+ assert_equal request['shipping']['address']['state'], options[:shipping_address][:state]
+ assert_equal request['shipping']['address']['country'], options[:shipping_address][:country]
+ assert_equal request['shipping']['address']['zip'], options[:shipping_address][:zip]
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ assert_equal 'Succeeded', response.message
+ end
+
+ def test_purchase_supports_alternate_credit_card_implementation
+ alternate_credit_card_class = Class.new
+ alternate_credit_card = alternate_credit_card_class.new
+
+ alternate_credit_card.expects(:credit_card?).returns(true)
+ alternate_credit_card.expects(:name).at_least_once.returns(@credit_card.name)
+ alternate_credit_card.expects(:number).returns(@credit_card.number)
+ alternate_credit_card.expects(:verification_value).returns(@credit_card.verification_value)
+ alternate_credit_card.expects(:first_name).at_least_once.returns(@credit_card.first_name)
+ alternate_credit_card.expects(:last_name).at_least_once.returns(@credit_card.first_name)
+
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.purchase(@amount, alternate_credit_card)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_authorize_supports_alternate_credit_card_implementation
+ alternate_credit_card_class = Class.new
+ alternate_credit_card = alternate_credit_card_class.new
+
+ alternate_credit_card.expects(:credit_card?).returns(true)
+ alternate_credit_card.expects(:name).at_least_once.returns(@credit_card.name)
+ alternate_credit_card.expects(:number).returns(@credit_card.number)
+ alternate_credit_card.expects(:verification_value).returns(@credit_card.verification_value)
+ alternate_credit_card.expects(:first_name).at_least_once.returns(@credit_card.first_name)
+ alternate_credit_card.expects(:last_name).at_least_once.returns(@credit_card.first_name)
+
+ stub_comms(@gateway, :ssl_request) do
+ @gateway.authorize(@amount, alternate_credit_card)
+ end.respond_with(successful_authorize_response)
end
private
def pre_scrubbed
%q(
- <- "POST /v2/charges/card HTTP/1.1\r\nContent-Type: application/json;charset=UTF-8\r\nAuthorization: sk_test_ab12301d-e432-4ea7-97d1-569809518aaf\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: api2.checkout.com\r\nContent-Length: 346\r\n\r\n"
- <- "{\"autoCapture\":\"n\",\"value\":\"200\",\"trackId\":\"1\",\"currency\":\"USD\",\"card\":{\"name\":\"Longbob Longsen\",\"number\":\"4242424242424242\",\"cvv\":\"100\",\"expiryYear\":\"2018\"
+ <- "POST /payments HTTP/1.1\r\nContent-Type: application/json;charset=UTF-8\r\nAuthorization: sk_test_ab12301d-e432-4ea7-97d1-569809518aaf\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: api.checkout.com\r\nContent-Length: 346\r\n\r\n"
+ <- "{\"capture\":false,\"amount\":\"200\",\"reference\":\"1\",\"currency\":\"USD\",\"source\":{\"type\":\"card\",\"name\":\"Longbob Longsen\",\"number\":\"4242424242424242\",\"cvv\":\"100\",\"expiry_year\":\"2025\"
+ )
+ end
+
+ def network_transaction_pre_scrubbed
+ %q(
+ <- "POST /payments HTTP/1.1\r\nContent-Type: application/json;charset=UTF-8\r\nAuthorization: sk_test_ab12301d-e432-4ea7-97d1-569809518aaf\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: api.checkout.com\r\nContent-Length: 346\r\n\r\n"
+ <- "{\"amount\":\"100\",\"reference\":\"1\",\"currency\":\"USD\",\"metadata\":{\"udf5\":\"ActiveMerchant\"},\"source\":{\"type\":\"network_token\",\"token\":\"4242424242424242\",\"token_type\":\"applepay\",\"cryptogram\":\"AgAAAAAAAIR8CQrXcIhbQAAAAAA\",\"eci\":\"05\",\"expiry_year\":\"2025\",\"expiry_month\":\"10\",\"billing_address\":{\"address_line1\":\"456 My Street\",\"address_line2\":\"Apt 1\",\"city\":\"Ottawa\",\"state\":\"ON\",\"country\":\"CA\",\"zip\":\"K1C2N6\"}},\"customer\":{\"email\":\"longbob.longsen@example.com\"}}"
+ )
+ end
+
+ def network_transaction_post_scrubbed
+ %q(
+ <- "POST /payments HTTP/1.1\r\nContent-Type: application/json;charset=UTF-8\r\nAuthorization: [FILTERED]\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: api.checkout.com\r\nContent-Length: 346\r\n\r\n"
+ <- "{\"amount\":\"100\",\"reference\":\"1\",\"currency\":\"USD\",\"metadata\":{\"udf5\":\"ActiveMerchant\"},\"source\":{\"type\":\"network_token\",\"token\":\"[FILTERED]\",\"token_type\":\"applepay\",\"cryptogram\":\"[FILTERED]\",\"eci\":\"05\",\"expiry_year\":\"2025\",\"expiry_month\":\"10\",\"billing_address\":{\"address_line1\":\"456 My Street\",\"address_line2\":\"Apt 1\",\"city\":\"Ottawa\",\"state\":\"ON\",\"country\":\"CA\",\"zip\":\"K1C2N6\"}},\"customer\":{\"email\":\"longbob.longsen@example.com\"}}"
)
end
def post_scrubbed
%q(
- <- "POST /v2/charges/card HTTP/1.1\r\nContent-Type: application/json;charset=UTF-8\r\nAuthorization: [FILTERED]\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: api2.checkout.com\r\nContent-Length: 346\r\n\r\n"
- <- "{\"autoCapture\":\"n\",\"value\":\"200\",\"trackId\":\"1\",\"currency\":\"USD\",\"card\":{\"name\":\"Longbob Longsen\",\"number\":\"[FILTERED]\",\"cvv\":\"[FILTERED]\",\"expiryYear\":\"2018\"
+ <- "POST /payments HTTP/1.1\r\nContent-Type: application/json;charset=UTF-8\r\nAuthorization: [FILTERED]\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: api.checkout.com\r\nContent-Length: 346\r\n\r\n"
+ <- "{\"capture\":false,\"amount\":\"200\",\"reference\":\"1\",\"currency\":\"USD\",\"source\":{\"type\":\"card\",\"name\":\"Longbob Longsen\",\"number\":\"[FILTERED]\",\"cvv\":\"[FILTERED]\",\"expiry_year\":\"2025\"
)
end
def successful_purchase_response
%(
- {
- "id":"charge_test_941CA9CE174U76BD29C8",
- "liveMode":false,
- "created":"2015-05-27T20:45:58Z",
- "value":200.0,
- "currency":"USD",
- "trackId":"1",
- "description":null,
- "email":"longbob.longsen@gmail.com",
- "chargeMode":1,
- "transactionIndicator":1,
- "customerIp":null,
- "responseMessage":"Approved",
- "responseAdvancedInfo":"Approved",
- "responseCode":"10000",
- "card": {
- "cvvCheck":"Y",
- "avsCheck":"S"
- }
- }
+ {"id":"pay_bgv5tmah6fmuzcmcrcro6exe6m","action_id":"act_bgv5tmah6fmuzcmcrcro6exe6m","amount":200,"currency":"USD","approved":true,"status":"Authorized","auth_code":"127172","eci":"05","scheme_id":"096091887499308","response_code":"10000","response_summary":"Approved","risk":{"flagged":false},"source":{"id":"src_fzp3cwkf4ygebbmvrxdhyrwmbm","type":"card","billing_address":{"address_line1":"456 My Street","address_line2":"Apt 1","city":"Ottawa","state":"ON","zip":"K1C2N6","country":"CA"},"expiry_month":6,"expiry_year":2025,"name":"Longbob Longsen","scheme":"Visa","last4":"4242","fingerprint":"9F3BAD2E48C6C8579F2F5DC0710B7C11A8ACD5072C3363A72579A6FB227D64BE","bin":"424242","card_type":"Credit","card_category":"Consumer","issuer":"JPMORGAN CHASE BANK NA","issuer_country":"US","product_id":"A","product_type":"Visa Traditional","avs_check":"S","cvv_check":"Y","payouts":true,"fast_funds":"d"},"customer":{"id":"cus_tz76qzbwr44ezdfyzdvrvlwogy","email":"longbob.longsen@example.com","name":"Longbob Longsen"},"processed_on":"2020-09-11T13:58:32Z","reference":"1","processing":{"acquirer_transaction_id":"9819327011","retrieval_reference_number":"861613285622"},"_links":{"self":{"href":"https://api.sandbox.checkout.com/payments/pay_bgv5tmah6fmuzcmcrcro6exe6m"},"actions":{"href":"https://api.sandbox.checkout.com/payments/pay_bgv5tmah6fmuzcmcrcro6exe6m/actions"},"capture":{"href":"https://api.sandbox.checkout.com/payments/pay_bgv5tmah6fmuzcmcrcro6exe6m/captures"},"void":{"href":"https://api.sandbox.checkout.com/payments/pay_bgv5tmah6fmuzcmcrcro6exe6m/voids"}}}
+ )
+ end
+
+ def succesful_store_response
+ %(
+ {"id":"src_vzzqipykt5ke5odazx5d7nikii","type":"card","fingerprint":"9F3BAD2E48C6C8579F2F5DC0710B7C11A8ACD5072C3363A72579A6FB227D64BE","expiry_month":6,"expiry_year":2025,"scheme":"VISA","last4":"4242","bin":"424242","card_type":"CREDIT","card_category":"CONSUMER","issuer_country":"GB","product_id":"F","product_type":"Visa Classic","customer":{"id":"cus_gmthnluatgounpoiyzbmn5fvua", "email":"longbob.longsen@example.com"}}
+ )
+ end
+
+ def successful_purchase_with_network_token_response
+ purchase_response = JSON.parse(successful_purchase_response)
+ purchase_response['source']['payment_account_reference'] = '2FCFE326D92D4C27EDD699560F484'
+ purchase_response.to_json
+ end
+
+ def successful_purchase_initial_stored_credential_response
+ %(
+ {"id":"pay_7jcf4ovmwnqedhtldca3fjli2y","action_id":"act_7jcf4ovmwnqedhtldca3fjli2y","amount":200,"currency":"USD","approved":true,"status":"Authorized","auth_code":"587541","eci":"05","scheme_id":"776561034288791","response_code":"10000","response_summary":"Approved","risk":{"flagged":false},"source":{"id":"src_m2ooveyd2dxuzh277ft4obgkwm","type":"card","billing_address":{"address_line1":"456 My Street","address_line2":"Apt 1","city":"Ottawa","state":"ON","zip":"K1C2N6","country":"CA"},"expiry_month":6,"expiry_year":2025,"name":"Longbob Longsen","scheme":"Visa","last4":"4242","fingerprint":"9F3BAD2E48C6C8579F2F5DC0710B7C11A8ACD5072C3363A72579A6FB227D64BE","bin":"424242","card_type":"Credit","card_category":"Consumer","issuer":"JPMORGAN CHASE BANK NA","issuer_country":"US","product_id":"A","product_type":"Visa Traditional","avs_check":"S","cvv_check":"Y","payouts":true,"fast_funds":"d"},"customer":{"id":"cus_tr53e5z2dlmetpo2ehbsuk76yu","email":"longbob.longsen@example.com","name":"Longbob Longsen"},"processed_on":"2021-03-29T20:22:48Z","reference":"1","processing":{"acquirer_transaction_id":"8266949399","retrieval_reference_number":"731420439000"},"_links":{"self":{"href":"https://api.sandbox.checkout.com/payments/pay_7jcf4ovmwnqedhtldca3fjli2y"},"actions":{"href":"https://api.sandbox.checkout.com/payments/pay_7jcf4ovmwnqedhtldca3fjli2y/actions"},"capture":{"href":"https://api.sandbox.checkout.com/payments/pay_7jcf4ovmwnqedhtldca3fjli2y/captures"},"void":{"href":"https://api.sandbox.checkout.com/payments/pay_7jcf4ovmwnqedhtldca3fjli2y/voids"}}}
+ )
+ end
+
+ def successful_purchase_using_stored_credential_response
+ %(
+ {"id":"pay_udodtu4ogljupp2jvy2cxf4jme","action_id":"act_udodtu4ogljupp2jvy2cxf4jme","amount":200,"currency":"USD","approved":true,"status":"Authorized","auth_code":"680745","eci":"05","scheme_id":"491049486700108","response_code":"10000","response_summary":"Approved","risk":{"flagged":false},"source":{"id":"src_m2ooveyd2dxuzh277ft4obgkwm","type":"card","billing_address":{"address_line1":"456 My Street","address_line2":"Apt 1","city":"Ottawa","state":"ON","zip":"K1C2N6","country":"CA"},"expiry_month":6,"expiry_year":2025,"name":"Longbob Longsen","scheme":"Visa","last4":"4242","fingerprint":"9F3BAD2E48C6C8579F2F5DC0710B7C11A8ACD5072C3363A72579A6FB227D64BE","bin":"424242","card_type":"Credit","card_category":"Consumer","issuer":"JPMORGAN CHASE BANK NA","issuer_country":"US","product_id":"A","product_type":"Visa Traditional","avs_check":"S","cvv_check":"Y","payouts":true,"fast_funds":"d"},"customer":{"id":"cus_tr53e5z2dlmetpo2ehbsuk76yu","email":"longbob.longsen@example.com","name":"Longbob Longsen"},"processed_on":"2021-03-29T20:22:49Z","reference":"1","processing":{"acquirer_transaction_id":"4026777708","retrieval_reference_number":"633985559433"},"_links":{"self":{"href":"https://api.sandbox.checkout.com/payments/pay_udodtu4ogljupp2jvy2cxf4jme"},"actions":{"href":"https://api.sandbox.checkout.com/payments/pay_udodtu4ogljupp2jvy2cxf4jme/actions"},"capture":{"href":"https://api.sandbox.checkout.com/payments/pay_udodtu4ogljupp2jvy2cxf4jme/captures"},"void":{"href":"https://api.sandbox.checkout.com/payments/pay_udodtu4ogljupp2jvy2cxf4jme/voids"}}}
)
end
def failed_purchase_response
%(
{
- "id":"charge_test_941CA9CE174U76BD29C8",
- "liveMode":false,
- "created":"2015-05-27T20:45:58Z",
- "value":200.0,
+ "id":"pay_awjzhfj776gulbp2nuslj4agbu",
+ "amount":200,
"currency":"USD",
- "trackId":"1",
- "description":null,
- "email":"longbob.longsen@gmail.com",
- "chargeMode":1,
- "transactionIndicator":1,
- "customerIp":null,
- "responseMessage":"Invalid Card Number",
- "responseAdvancedInfo":"If credit card number contains characters other digits, or bank does not recognize this number as a valid credit card number",
- "responseCode":"20014",
- "card": {
+ "reference":"1",
+ "response_summary": "Invalid Card Number",
+ "response_code":"20014",
+ "customer": {
+ "id": "cus_zvnv7gsblfjuxppycd7bx4erue",
+ "email": "longbob.longsen@example.com",
+ "name": "Sarah Mitchell"
+ },
+ "source": {
"cvvCheck":"Y",
"avsCheck":"S"
}
@@ -291,66 +1059,61 @@ def failed_purchase_response
def successful_authorize_response
%(
- {
- "id":"charge_test_AF1A29AD350Q748C7EA8",
- "liveMode":false,
- "created":"2017-11-13T14:05:27Z",
- "value":200,
- "currency":"USD",
- "trackId":"1",
- "description":null,
- "email":"longbob.longsen@example.com",
- "chargeMode":1,
- "transactionIndicator":1,
- "customerIp":null,
- "responseMessage":"Approved",
- "responseAdvancedInfo":"Approved",
- "responseCode":"10000",
- "status":"Authorised",
- "authCode":"923189",
- "isCascaded":false,
- "autoCapture":"N",
- "autoCapTime":0.0,
- "card":{"customerId":
- "cust_12DCEB24-ACEA-48AB-BEF2-35A3C09BE581",
- "expiryMonth":"06",
- "expiryYear":"2018",
- "billingDetails":{
- "addressLine1":"456 My Street",
- "addressLine2":"Apt 1",
- "postcode":"K1C2N6",
- "country":"CA",
- "city":"Ottawa",
- "state":"ON",
- "phone":{"number":"(555)555-5555"}
- },
- "id":"card_CFA314F4-388D-4CF4-BE6F-940D894C9E64",
- "last4":"4242",
- "bin":"424242",
- "paymentMethod":"Visa",
- "fingerprint":"F639CAB2745BEE4140BF86DF6B6D6E255C5945AAC3788D923FA047EA4C208622",
- "name":"Longbob Longsen",
- "cvvCheck":"Y",
- "avsCheck":"S"
+ {
+ "id": "pay_fj3xswqe3emuxckocjx6td73ni",
+ "action_id": "act_fj3xswqe3emuxckocjx6td73ni",
+ "amount": 200,
+ "currency": "USD",
+ "approved": true,
+ "status": "Authorized",
+ "auth_code": "858188",
+ "eci": "05",
+ "scheme_id": "638284745624527",
+ "response_code": "10000",
+ "response_summary": "Approved",
+ "risk": {
+ "flagged": false
},
- "riskCheck":true,
- "customerPaymentPlans":null,
- "metadata":{},
- "shippingDetails":{
- "addressLine1":null,
- "addressLine2":null,
- "postcode":null,
- "country":null,
- "city":null,
- "state":null,
- "phone":{}
+ "source": {
+ "id": "src_nq6m5dqvxmsunhtzf7adymbq3i",
+ "type": "card",
+ "expiry_month": 8,
+ "expiry_year": 2025,
+ "name": "Sarah Mitchell",
+ "scheme": "Visa",
+ "last4": "4242",
+ "fingerprint": "5CD3B9CB15338683110959D165562D23084E1FF564F420FE9A990DF0BCD093FC",
+ "bin": "424242",
+ "card_type": "Credit",
+ "card_category": "Consumer",
+ "issuer": "JPMORGAN CHASE BANK NA",
+ "issuer_country": "US",
+ "product_id": "A",
+ "product_type": "Visa Traditional",
+ "avs_check": "S",
+ "cvv_check": "Y"
},
- "products":[],
- "udf1":null,
- "udf2":null,
- "udf3":null,
- "udf4":null,
- "udf5":null
+ "customer": {
+ "id": "cus_ssxcidkqvfde7lfn5n7xzmgv2a",
+ "email": "longbob.longsen@example.com",
+ "name": "Sarah Mitchell"
+ },
+ "processed_on": "2019-03-24T10:14:32Z",
+ "reference": "ORD-5023-4E89",
+ "_links": {
+ "self": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_fj3xswqe3emuxckocjx6td73ni"
+ },
+ "actions": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_fj3xswqe3emuxckocjx6td73ni/actions"
+ },
+ "capture": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_fj3xswqe3emuxckocjx6td73ni/captures"
+ },
+ "void": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_fj3xswqe3emuxckocjx6td73ni/voids"
+ }
+ }
}
)
end
@@ -358,126 +1121,177 @@ def successful_authorize_response
def failed_authorize_response
%(
{
- "id":"charge_test_941CA9CE174U76BD29C8",
- "liveMode":false,
- "created":"2015-05-27T20:45:58Z",
- "value":200.0,
+ "id":"pay_awjzhfj776gulbp2nuslj4agbu",
+ "amount":200,
"currency":"USD",
- "trackId":"1",
- "description":null,
- "email":"longbob.longsen@gmail.com",
- "chargeMode":1,
- "transactionIndicator":1,
- "customerIp":null,
- "responseMessage":"Invalid Card Number",
- "responseAdvancedInfo":"If credit card number contains characters other digits, or bank does not recognize this number as a valid credit card number",
- "responseCode":"20014"
+ "reference":"1",
+ "customer": {
+ "id": "cus_zvnv7gsblfjuxppycd7bx4erue",
+ "email": "longbob.longsen@example.com",
+ "name": "Sarah Mitchell"
+ },
+ "response_summary": "Invalid Card Number",
+ "response_code":"20014"
}
)
end
- def successful_capture_response
+ def successful_incremental_authorize_response
%(
- {
- "id":"charge_test_941CA9CE174U76BD29C8",
- "liveMode":false,
- "created":"2015-05-27T20:45:58Z",
- "value":200.0,
- "currency":"USD",
- "trackId":"1",
- "description":null,
- "email":"longbob.longsen@gmail.com",
- "chargeMode":1,
- "transactionIndicator":1,
- "customerIp":null,
- "responseMessage":"Captured",
- "responseAdvancedInfo":"Captured",
- "responseCode":"10000"
+ {
+ "action_id": "act_q4dbxom5jbgudnjzjpz7j2z6uq",
+ "amount": 50,
+ "currency": "USD",
+ "approved": true,
+ "status": "Authorized",
+ "auth_code": "503198",
+ "expires_on": "2020-04-20T10:11:12Z",
+ "eci": "05",
+ "scheme_id": "511129554406717",
+ "response_code": "10000",
+ "response_summary": "Approved",
+ "balances": {
+ "total_authorized": 150,
+ "total_voided": 0,
+ "available_to_void": 150,
+ "total_captured": 0,
+ "available_to_capture": 150,
+ "total_refunded": 0,
+ "available_to_refund": 0
+ },
+ "processed_on": "2020-03-16T22:11:24Z",
+ "reference": "ORD-752-814",
+ "processing": {
+ "acquirer_transaction_id": "8367314942",
+ "retrieval_reference_number": "162588399162"
+ },
+ "_links": {
+ "self": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_tqgk5c6k2nnexagtcuom5ktlua"
+ },
+ "actions": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_tqgk5c6k2nnexagtcuom5ktlua/actions"
+ },
+ "authorize": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_tqgk5c6k2nnexagtcuom5ktlua/authorizations"
+ },
+ "capture": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_tqgk5c6k2nnexagtcuom5ktlua/captures"
+ },
+ "void": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_tqgk5c6k2nnexagtcuom5ktlua/voids"
+ }
+ }
}
)
end
- def failed_capture_response
+ def successful_capture_response
%(
{
- "errorCode":"405",
- "message":"You tried to access the endpoint with an invalid method",
+ "action_id": "act_2f56bhkau5dubequbv5aa6w4qi",
+ "reference": "1"
}
)
end
+ def failed_capture_response
+ %(
+ )
+ end
+
def successful_refund_response
%(
- {
- "id":"charge_test_941CA9CE174U76BD29C8",
- "liveMode":false,
- "created":"2015-05-27T20:45:58Z",
- "value":200.0,
- "currency":"USD",
- "trackId":"1",
- "description":null,
- "email":"longbob.longsen@gmail.com",
- "chargeMode":1,
- "transactionIndicator":1,
- "customerIp":null,
- "responseMessage":"Refunded",
- "responseAdvancedInfo":"Refunded",
- "responseCode":"10000"
- }
+ {
+ "action_id": "act_2f56bhkau5dubequbv5aa6w4qi",
+ "reference": "1"
+ }
)
end
def failed_refund_response
+ %(
+ )
+ end
+
+ def successful_void_response
%(
{
- "errorCode":"405",
- "message":"You tried to access the endpoint with an invalid method",
+ "action_id": "act_2f56bhkau5dubequbv5aa6w4qi",
+ "reference": "1"
}
)
end
- def successful_void_response
+ def successful_credit_response
%(
- {
- "id":"charge_test_941CA9CE174U76BD29C8",
- "liveMode":false,
- "created":"2015-05-27T20:45:58Z",
- "value":200.0,
- "currency":"USD",
- "trackId":"1",
- "description":null,
- "email":"longbob.longsen@gmail.com",
- "chargeMode":1,
- "transactionIndicator":1,
- "customerIp":null,
- "responseMessage":"Voided",
- "responseAdvancedInfo":"Voided",
- "responseCode":"10000"
+ {
+ "id": "pay_jhzh3u7vxcgezlcek7ymzyy6be",
+ "status": "Pending",
+ "reference": "ORD-5023-4E89",
+ "instruction": {
+ "value_date": "2022-08-09T06:11:37.2306547+00:00"
+ },
+ "_links": {
+ "self": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_jhzh3u7vxcgezlcek7ymzyy6be"
+ },
+ "actions": {
+ "href": "https://api.sandbox.checkout.com/payments/pay_jhzh3u7vxcgezlcek7ymzyy6be/actions"
+ }
}
+ }
)
end
def failed_void_response
%(
- {
- "errorCode":"405",
- "message":"You tried to access the endpoint with an invalid method",
- }
)
end
def invalid_json_response
%(
{
- "id": "charge_test_123456",
+ "id": "pay_123",
)
end
def error_code_response
%(
{
- "eventId":"1b206f69-b4db-4259-9713-b72dfe0f19da","errorCode":"70000","message":"Validation error","errorMessageCodes":["70077"],"errors":["Expired Card"]
+ "request_id": "e5a3ce6f-a4e9-4445-9ec7-e5975e9a6213","error_type": "request_invalid","error_codes": ["card_expired"]
}
)
end
+
+ def error_4xx_response
+ mock_response = Net::HTTPUnauthorized.new('1.1', '401', 'Unauthorized')
+ mock_response.stubs(:body).returns('')
+
+ ActiveMerchant::ResponseError.new(mock_response)
+ end
+
+ def successful_verify_payment_response
+ %(
+ {"id":"pay_tkvif5mf54eerhd3ysuawfcnt4","requested_on":"2019-08-14T18:13:54Z","source":{"id":"src_lot2ch4ygk3ehi4fugxmk7r2di","type":"card","expiry_month":12,"expiry_year":2020,"name":"Jane Doe","scheme":"Visa","last4":"0907","fingerprint":"E4048195442B0059D73FD47F6E1961A02CD085B0B34B7703CE4A93750DB5A0A1","bin":"457382","avs_check":"S","cvv_check":"Y"},"amount":100,"currency":"USD","payment_type":"Regular","reference":"Dvy8EMaEphrMWolKsLVHcUqPsyx","status":"Authorized","approved":true,"3ds":{"downgraded":false,"enrolled":"Y","authentication_response":"Y","cryptogram":"ce49b5c1-5d3c-4864-bd16-2a8c","xid":"95202312-f034-48b4-b9b2-54254a2b49fb","version":"2.1.0"},"risk":{"flagged":false},"customer":{"id":"cus_zt5pspdtkypuvifj7g6roy7p6y","name":"Jane Doe"},"billing_descriptor":{"name":"","city":"London"},"payment_ip":"127.0.0.1","metadata":{"Udf5":"ActiveMerchant"},"eci":"05","scheme_id":"638284745624527","actions":[{"id":"act_tkvif5mf54eerhd3ysuawfcnt4","type":"Authorization","response_code":"10000","response_summary":"Approved"}],"_links":{"self":{"href":"https://api.sandbox.checkout.com/payments/pay_tkvif5mf54eerhd3ysuawfcnt4"},"actions":{"href":"https://api.sandbox.checkout.com/payments/pay_tkvif5mf54eerhd3ysuawfcnt4/actions"},"capture":{"href":"https://api.sandbox.checkout.com/payments/pay_tkvif5mf54eerhd3ysuawfcnt4/captures"},"void":{"href":"https://api.sandbox.checkout.com/payments/pay_tkvif5mf54eerhd3ysuawfcnt4/voids"}}}
+ )
+ end
+
+ def succesful_token_response
+ %({"type":"card","token":"tok_267wy4hwrpietkmbbp5iswwhvm","expires_on":"2023-01-03T20:18:49.0006481Z","expiry_month":6,"expiry_year":2025,"name":"Longbob Longsen","scheme":"VISA","last4":"4242","bin":"424242","card_type":"CREDIT","card_category":"CONSUMER","issuer_country":"GB","product_id":"F","product_type":"Visa Classic"})
+ end
+
+ def failed_verify_payment_response
+ %(
+ {"id":"pay_xrwmaqlar73uhjtyoghc7bspa4","requested_on":"2019-08-14T18:32:50Z","source":{"type":"card","expiry_month":12,"expiry_year":2020,"name":"Jane Doe","scheme":"Visa","last4":"7863","fingerprint":"DC20145B78E242C561A892B83CB64471729D7A5063E5A5B341035713B8FDEC92","bin":"453962"},"amount":100,"currency":"USD","payment_type":"Regular","reference":"EuyOZtgt8KI4tolEH8lqxCclWqz","status":"Declined","approved":false,"3ds":{"downgraded":false,"enrolled":"Y","version":"2.1.0"},"risk":{"flagged":false},"customer":{"id":"cus_bb4b7eu35sde7o33fq2xchv7oq","name":"Jane Doe"},"payment_ip":"127.0.0.1","metadata":{"Udf5":"ActiveMerchant"},"_links":{"self":{"href":"https://api.sandbox.checkout.com/payments/pay_xrwmaqlar73uhjtyoghc7bspa4"},"actions":{"href":"https://api.sandbox.checkout.com/payments/pay_xrwmaqlar73uhjtyoghc7bspa4/actions"}}}
+ )
+ end
+
+ def successful_verify_response
+ %({"id":"pay_ij6bctwxpzdulm53xyksio7gm4","action_id":"act_ij6bctwxpzdulm53xyksio7gm4","amount":0,"currency":"USD","approved":true,"status":"Card Verified","auth_code":"881790","eci":"05","scheme_id":"305756859646779","response_code":"10000","response_summary":"Approved","risk":{"flagged":false},"source":{"id":"src_nica37p5k7aufhs3rsv2te7xye","type":"card","billing_address":{"address_line1":"456 My Street","address_line2":"Apt 1","city":"Ottawa","state":"ON","zip":"K1C2N6","country":"CA"},"expiry_month":6,"expiry_year":2025,"name":"Longbob Longsen","scheme":"Visa","last4":"4242","fingerprint":"9F3BAD2E48C6C8579F2F5DC0710B7C11A8ACD5072C3363A72579A6FB227D64BE","bin":"424242","card_type":"Credit","card_category":"Consumer","issuer":"JPMORGAN CHASE BANK NA","issuer_country":"US","product_id":"A","product_type":"Visa Traditional","avs_check":"S","cvv_check":"Y","payouts":true,"fast_funds":"d"},"customer":{"id":"cus_r2yb7f2upmsuhm6nbruoqn657y","email":"longbob.longsen@example.com","name":"Longbob Longsen"},"processed_on":"2020-09-18T18:17:45Z","reference":"1","processing":{"acquirer_transaction_id":"4932795322","retrieval_reference_number":"954188232380"},"_links":{"self":{"href":"https://api.sandbox.checkout.com/payments/pay_ij6bctwxpzdulm53xyksio7gm4"},"actions":{"href":"https://api.sandbox.checkout.com/payments/pay_ij6bctwxpzdulm53xyksio7gm4/actions"}}})
+ end
+
+ def failed_verify_response
+ %({"request_id":"911829c3-519a-47e8-bbc1-17337789fda0","error_type":"request_invalid","error_codes":["card_number_invalid"]})
+ end
end
diff --git a/test/unit/gateways/citrus_pay_test.rb b/test/unit/gateways/citrus_pay_test.rb
index 40b126e3782..bc39c2034bd 100644
--- a/test/unit/gateways/citrus_pay_test.rb
+++ b/test/unit/gateways/citrus_pay_test.rb
@@ -48,7 +48,7 @@ def test_authorize_and_capture
capture = stub_comms(@gateway, :ssl_request) do
@gateway.capture(@amount, response.authorization)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/f3d100a7-18d9-4609-aabc-8a710ad0e210/, data)
end.respond_with(successful_capture_response)
@@ -65,7 +65,7 @@ def test_refund
refund = stub_comms(@gateway, :ssl_request) do
@gateway.refund(@amount, response.authorization)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/ce61e06e-8c92-4a0f-a491-6eb473d883dd/, data)
end.respond_with(successful_refund_response)
@@ -82,7 +82,7 @@ def test_void
void = stub_comms(@gateway, :ssl_request) do
@gateway.void(response.authorization)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/ce61e06e-8c92-4a0f-a491-6eb473d883dd/, data)
end.respond_with(successful_void_response)
@@ -91,16 +91,16 @@ def test_void
def test_passing_alpha3_country_code
stub_comms(@gateway, :ssl_request) do
- @gateway.authorize(@amount, @credit_card, :billing_address => {country: 'US'})
- end.check_request do |method, endpoint, data, headers|
+ @gateway.authorize(@amount, @credit_card, billing_address: { country: 'US' })
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/USA/, data)
end.respond_with(successful_authorize_response)
end
def test_non_existent_country
stub_comms(@gateway, :ssl_request) do
- @gateway.authorize(@amount, @credit_card, :billing_address => {country: 'Blah'})
- end.check_request do |method, endpoint, data, headers|
+ @gateway.authorize(@amount, @credit_card, billing_address: { country: 'Blah' })
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/"country":null/, data)
end.respond_with(successful_authorize_response)
end
@@ -108,15 +108,15 @@ def test_non_existent_country
def test_passing_cvv
stub_comms(@gateway, :ssl_request) do
@gateway.authorize(@amount, @credit_card)
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match(/#{@credit_card.verification_value}/, data)
end.respond_with(successful_authorize_response)
end
def test_passing_billing_address
stub_comms(@gateway, :ssl_request) do
- @gateway.authorize(@amount, @credit_card, :billing_address => address)
- end.check_request do |method, endpoint, data, headers|
+ @gateway.authorize(@amount, @credit_card, billing_address: address)
+ end.check_request do |_method, _endpoint, data, _headers|
parsed = JSON.parse(data)
assert_equal('456 My Street', parsed['billing']['address']['street'])
assert_equal('K1C2N6', parsed['billing']['address']['postcodeZip'])
@@ -125,8 +125,8 @@ def test_passing_billing_address
def test_passing_shipping_name
stub_comms(@gateway, :ssl_request) do
- @gateway.authorize(@amount, @credit_card, :shipping_address => address)
- end.check_request do |method, endpoint, data, headers|
+ @gateway.authorize(@amount, @credit_card, shipping_address: address)
+ end.check_request do |_method, _endpoint, data, _headers|
parsed = JSON.parse(data)
assert_equal('Jim', parsed['shipping']['firstName'])
assert_equal('Smith', parsed['shipping']['lastName'])
@@ -157,7 +157,7 @@ def test_unsuccessful_verify
assert_equal 'FAILURE - DECLINED', response.message
end
- def test_north_america_region_url
+ def test_url
@gateway = TnsGateway.new(
userid: 'userid',
password: 'password',
@@ -166,24 +166,8 @@ def test_north_america_region_url
response = stub_comms(@gateway, :ssl_request) do
@gateway.purchase(@amount, @credit_card, @options)
- end.check_request do |method, endpoint, data, headers|
- assert_match(/secure.na.tnspayments.com/, endpoint)
- end.respond_with(successful_capture_response)
-
- assert_success response
- end
-
- def test_asia_pacific_region_url
- @gateway = TnsGateway.new(
- userid: 'userid',
- password: 'password',
- region: 'asia_pacific'
- )
-
- response = stub_comms(@gateway, :ssl_request) do
- @gateway.purchase(@amount, @credit_card, @options)
- end.check_request do |method, endpoint, data, headers|
- assert_match(/secure.ap.tnspayments.com/, endpoint)
+ end.check_request do |_method, endpoint, _data, _headers|
+ assert_match(/secure.uat.tnspayments.com/, endpoint)
end.respond_with(successful_capture_response)
assert_success response
diff --git a/test/unit/gateways/clearhaus_test.rb b/test/unit/gateways/clearhaus_test.rb
index b877de05e4f..b5d74ff46ec 100644
--- a/test/unit/gateways/clearhaus_test.rb
+++ b/test/unit/gateways/clearhaus_test.rb
@@ -55,7 +55,7 @@ def test_successful_authorize_with_threed
response = @gateway.authorize(@amount, @credit_card, @options.merge(pares: '123'))
assert_success response
assert response.test?
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
expr = { card: { pares: '123' } }.to_query
assert_match expr, data
end.respond_with(successful_authorize_response)
@@ -66,9 +66,9 @@ def test_additional_params
response = @gateway.authorize(@amount, @credit_card, @options.merge(order_id: '123', text_on_statement: 'test'))
assert_success response
assert response.test?
- end.check_request do |endpoint, data, headers|
- order_expr = { reference: '123'}.to_query
- tos_expr = { text_on_statement: 'test'}.to_query
+ end.check_request do |_endpoint, data, _headers|
+ order_expr = { reference: '123' }.to_query
+ tos_expr = { text_on_statement: 'test' }.to_query
assert_match order_expr, data
assert_match tos_expr, data
@@ -82,7 +82,7 @@ def test_successful_authorize_with_card
assert_equal '84412a34-fa29-4369-a098-0165a80e8fda', response.authorization
assert response.test?
- end.check_request do |endpoint, data, headers|
+ end.check_request do |endpoint, _data, _headers|
assert_match %r{/cards/4110/authorizations}, endpoint
end.respond_with(successful_authorize_response)
end
@@ -222,7 +222,7 @@ def test_signing_request
assert_equal '84412a34-fa29-4369-a098-0165a80e8fda', response.authorization
assert response.test?
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, _data, headers|
assert headers['Signature']
assert_match %r{7e51b92e-ca7e-48e3-8a96-7d66cf1f2da2 RS256-hex}, headers['Signature']
assert_match %r{25f8283c3cc43911d7$}, headers['Signature']
@@ -241,7 +241,7 @@ def test_cleans_whitespace_from_private_key
assert_equal '84412a34-fa29-4369-a098-0165a80e8fda', response.authorization
assert response.test?
- end.check_request do |method, endpoint, data, headers|
+ end.check_request do |_method, _endpoint, _data, headers|
assert headers['Signature']
assert_match %r{7e51b92e-ca7e-48e3-8a96-7d66cf1f2da2 RS256-hex}, headers['Signature']
assert_match %r{25f8283c3cc43911d7$}, headers['Signature']
@@ -249,7 +249,7 @@ def test_cleans_whitespace_from_private_key
end
def test_unsuccessful_signing_request_with_invalid_key
- gateway = ClearhausGateway.new(api_key: 'test_key', signing_key: @test_signing_key, private_key: 'foo')
+ gateway = ClearhausGateway.new(api_key: 'test_key', signing_key: @test_signing_key, private_key: 'foo')
# stub actual network access, but this shouldn't be reached
gateway.stubs(:ssl_post).returns(nil)
@@ -266,6 +266,14 @@ def test_scrub
assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed
end
+ def test_nonfractional_currency_handling
+ stub_comms do
+ @gateway.authorize(200, @credit_card, @options.merge(currency: 'JPY'))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/amount=2&card/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
private
def pre_scrubbed
@@ -366,11 +374,11 @@ def successful_authorize_response
{
'id' => '84412a34-fa29-4369-a098-0165a80e8fda',
'status' => {
- 'code' => 20000
+ 'code' => 20000
},
'processed_at' => '2014-07-09T09:53:41+00:00',
'_links' => {
- 'captures' => { 'href' => '/authorizations/84412a34-fa29-4369-a098-0165a80e8fda/captures' }
+ 'captures' => { 'href' => '/authorizations/84412a34-fa29-4369-a098-0165a80e8fda/captures' }
}
}.to_json
end
@@ -381,20 +389,20 @@ def failed_authorize_response
def successful_capture_response
{
- 'id' => 'd8e92a70-3030-4d4d-8ad2-684b230c1bed',
- 'status' => {
- 'code' => 20000
+ 'id' => 'd8e92a70-3030-4d4d-8ad2-684b230c1bed',
+ 'status' => {
+ 'code' => 20000
+ },
+ 'processed_at' => '2014-07-09T11:47:28+00:00',
+ 'amount' => 1000,
+ '_links' => {
+ 'authorization' => {
+ 'href' => '/authorizations/84412a34-fa29-4369-a098-0165a80e8fda'
},
- 'processed_at' => '2014-07-09T11:47:28+00:00',
- 'amount' => 1000,
- '_links' => {
- 'authorization' => {
- 'href' => '/authorizations/84412a34-fa29-4369-a098-0165a80e8fda'
- },
- 'refunds' => {
- 'href' => '/authorizations/84412a34-fa29-4369-a098-0165a80e8fda/refunds'
- }
+ 'refunds' => {
+ 'href' => '/authorizations/84412a34-fa29-4369-a098-0165a80e8fda/refunds'
}
+ }
}.to_json
end
@@ -406,12 +414,12 @@ def successful_refund_response
{
'id' => 'f04c0872-47ce-4683-8d8c-e154221bba14',
'status' => {
- 'code' => 20000
+ 'code' => 20000
},
'processed_at' => '2014-07-09T11:57:58+00:00',
'amount' => 500,
'_links' => {
- 'authorization' => { 'href' => '/authorizations/84412a34-fa29-4369-a098-0165a80e8fda' }
+ 'authorization' => { 'href' => '/authorizations/84412a34-fa29-4369-a098-0165a80e8fda' }
}
}.to_json
end
@@ -437,8 +445,8 @@ def successful_void_response
'captures' => {
'href' => '/authorizations/77d08c40-cfa9-42e3-993d-795f772b70a4/captures'
},
- 'voids' => { 'href' => '/authorizations/77d08c40-cfa9-42e3-993d-795f772b70a4/voids'},
- 'refunds' => { 'href' => '/authorizations/77d08c40-cfa9-42e3-993d-795f772b70a4/refunds'}
+ 'voids' => { 'href' => '/authorizations/77d08c40-cfa9-42e3-993d-795f772b70a4/voids' },
+ 'refunds' => { 'href' => '/authorizations/77d08c40-cfa9-42e3-993d-795f772b70a4/refunds' }
}
}
end
@@ -451,14 +459,14 @@ def successful_store_response
{
'id' => '58dabba0-e9ea-4133-8c38-bfa1028c1ed2',
'status' => {
- 'code'=> 20000
+ 'code' => 20000
},
'processed_at' => '2014-07-09T12:14:31+00:00',
'last4' => '0004',
'scheme' => 'mastercard',
'_links' => {
- 'authorizations' => { 'href' => '/cards/58dabba0-e9ea-4133-8c38-bfa1028c1ed2/authorizations' },
- 'credits'=> { 'href' => '/cards/58dabba0-e9ea-4133-8c38-bfa1028c1ed2/credits' }
+ 'authorizations' => { 'href' => '/cards/58dabba0-e9ea-4133-8c38-bfa1028c1ed2/authorizations' },
+ 'credits' => { 'href' => '/cards/58dabba0-e9ea-4133-8c38-bfa1028c1ed2/credits' }
}
}.to_json
end
@@ -468,7 +476,6 @@ def failed_store_response
end
def failed_ch_response
- { 'status' => { 'code' => 40000, 'message' => 'General input error' }}.to_json
+ { 'status' => { 'code' => 40000, 'message' => 'General input error' } }.to_json
end
-
end
diff --git a/test/unit/gateways/commerce_hub_test.rb b/test/unit/gateways/commerce_hub_test.rb
new file mode 100644
index 00000000000..b2b085be356
--- /dev/null
+++ b/test/unit/gateways/commerce_hub_test.rb
@@ -0,0 +1,806 @@
+require 'test_helper'
+
+class CommerceHubTest < Test::Unit::TestCase
+ include CommStub
+
+ def setup
+ @gateway = CommerceHubGateway.new(api_key: 'login', api_secret: 'password', merchant_id: '12345', terminal_id: '0001')
+
+ @amount = 1204
+ @credit_card = credit_card('4005550000000019', month: '02', year: '2035', verification_value: '123')
+ @google_pay = network_tokenization_credit_card(
+ '4005550000000019',
+ brand: 'visa',
+ eci: '05',
+ month: '02',
+ year: '2035',
+ source: :google_pay,
+ payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=',
+ transaction_id: '13456789'
+ )
+ @apple_pay = network_tokenization_credit_card(
+ '4005550000000019',
+ brand: 'visa',
+ eci: '05',
+ month: '02',
+ year: '2035',
+ source: :apple_pay,
+ payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=',
+ transaction_id: '13456789'
+ )
+ @no_supported_source = network_tokenization_credit_card(
+ '4005550000000019',
+ brand: 'visa',
+ eci: '05',
+ month: '02',
+ year: '2035',
+ source: :no_source,
+ payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk='
+ )
+ @declined_card = credit_card('4000300011112220', month: '02', year: '2035', verification_value: '123')
+ @options = {}
+ @post = {}
+ end
+
+ def test_successful_authorize_with_full_headers
+ @options.merge!(
+ headers_identifiers: {
+ 'x-originator' => 'CommerceHub-Partners-Spreedly',
+ 'user-agent' => 'CommerceHub-Partners-Spreedly-V1.00'
+ }
+ )
+
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, _data, headers|
+ assert_not_nil headers['Client-Request-Id']
+ assert_equal 'login', headers['Api-Key']
+ assert_not_nil headers['Timestamp']
+ assert_equal 'application/json', headers['Accept-Language']
+ assert_equal 'application/json', headers['Content-Type']
+ assert_equal 'application/json', headers['Accept']
+ assert_equal 'HMAC', headers['Auth-Token-Type']
+ assert_not_nil headers['Authorization']
+ assert_equal 'CommerceHub-Partners-Spreedly', headers['x-originator']
+ assert_equal 'CommerceHub-Partners-Spreedly-V1.00', headers['user-agent']
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_successful_purchase
+ @options[:order_id] = 'abc123'
+
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['transactionDetails']['captureFlag'], true
+ assert_equal request['transactionDetails']['createToken'], false
+ assert_equal request['transactionDetails']['merchantOrderId'], 'abc123'
+ assert_equal request['merchantDetails']['terminalId'], @gateway.options[:terminal_id]
+ assert_equal request['merchantDetails']['merchantId'], @gateway.options[:merchant_id]
+ assert_equal request['amount']['total'], (@amount / 100.0).to_f
+ assert_equal request['source']['card']['cardData'], @credit_card.number
+ assert_equal request['source']['card']['securityCode'], @credit_card.verification_value
+ assert_equal request['transactionInteraction']['posEntryMode'], 'MANUAL'
+ assert_equal request['source']['card']['securityCodeIndicator'], 'PROVIDED'
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ def test_successful_purchase_with_google_pay
+ response = stub_comms do
+ @gateway.purchase(@amount, @google_pay, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['transactionDetails']['captureFlag'], true
+ assert_equal request['merchantDetails']['terminalId'], @gateway.options[:terminal_id]
+ assert_equal request['merchantDetails']['merchantId'], @gateway.options[:merchant_id]
+ assert_equal request['amount']['total'], (@amount / 100.0).to_f
+ assert_equal request['source']['card']['cardData'], @google_pay.number
+ assert_equal request['source']['cavv'], @google_pay.payment_cryptogram
+ assert_equal request['source']['walletType'], 'GOOGLE_PAY'
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ def test_successful_purchase_with_apple_pay
+ response = stub_comms do
+ @gateway.purchase(@amount, @apple_pay, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['transactionDetails']['captureFlag'], true
+ assert_equal request['merchantDetails']['terminalId'], @gateway.options[:terminal_id]
+ assert_equal request['merchantDetails']['merchantId'], @gateway.options[:merchant_id]
+ assert_equal request['amount']['total'], (@amount / 100.0).to_f
+ assert_equal request['source']['card']['cardData'], @apple_pay.number
+ assert_equal request['source']['cavv'], @apple_pay.payment_cryptogram
+ assert_equal request['source']['walletType'], 'APPLE_PAY'
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ def test_successful_purchase_with_no_supported_source_as_apple_pay
+ response = stub_comms do
+ @gateway.purchase(@amount, @no_supported_source, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['transactionDetails']['captureFlag'], true
+ assert_equal request['merchantDetails']['terminalId'], @gateway.options[:terminal_id]
+ assert_equal request['merchantDetails']['merchantId'], @gateway.options[:merchant_id]
+ assert_equal request['amount']['total'], (@amount / 100.0).to_f
+ assert_equal request['source']['card']['cardData'], @apple_pay.number
+ assert_equal request['source']['cavv'], @apple_pay.payment_cryptogram
+ assert_equal request['source']['walletType'], 'APPLE_PAY'
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ def test_successful_authorize
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['transactionDetails']['captureFlag'], false
+ assert_equal request['merchantDetails']['terminalId'], @gateway.options[:terminal_id]
+ assert_equal request['merchantDetails']['merchantId'], @gateway.options[:merchant_id]
+ assert_equal request['amount']['total'], (@amount / 100.0).to_f
+ assert_equal request['source']['card']['cardData'], @credit_card.number
+ assert_equal request['source']['card']['securityCode'], @credit_card.verification_value
+ assert_equal request['source']['card']['securityCodeIndicator'], 'PROVIDED'
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_failed_purchase_and_authorize
+ @gateway.expects(:ssl_post).returns(failed_purchase_and_authorize_response)
+
+ response = @gateway.authorize(@amount, @credit_card, @options)
+ assert_failure response
+ assert_equal 'string', response.error_code
+ end
+
+ def test_successful_parsing_of_billing_and_shipping_addresses
+ address_with_phone = address.merge({ phone_number: '000-000-00-000' })
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options.merge({ billing_address: address_with_phone, shipping_address: address_with_phone }))
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ %w(shipping billing).each do |key|
+ assert_equal request[key + 'Address']['address']['street'], address_with_phone[:address1]
+ assert_equal request[key + 'Address']['address']['houseNumberOrName'], address_with_phone[:address2]
+ assert_equal request[key + 'Address']['address']['recipientNameOrAddress'], address_with_phone[:name]
+ assert_equal request[key + 'Address']['address']['city'], address_with_phone[:city]
+ assert_equal request[key + 'Address']['address']['stateOrProvince'], address_with_phone[:state]
+ assert_equal request[key + 'Address']['address']['postalCode'], address_with_phone[:zip]
+ assert_equal request[key + 'Address']['address']['country'], address_with_phone[:country]
+ assert_equal request[key + 'Address']['phone']['phoneNumber'], address_with_phone[:phone_number]
+ end
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_successful_void
+ response = stub_comms do
+ @gateway.void('abc123|authorization123', @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal 'authorization123', request['referenceTransactionDetails']['referenceTransactionId']
+ assert_equal 'CHARGES', request['referenceTransactionDetails']['referenceTransactionType']
+ assert_nil request['transactionDetails']['captureFlag']
+ end.respond_with(successful_void_and_refund_response)
+
+ assert_success response
+ end
+
+ def test_successful_refund
+ response = stub_comms do
+ @gateway.refund(nil, 'abc123|authorization123', @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['referenceTransactionDetails']['referenceTransactionId'], 'authorization123'
+ assert_equal request['referenceTransactionDetails']['referenceTransactionType'], 'CHARGES'
+ assert_nil request['transactionDetails']['captureFlag']
+ assert_nil request['amount']
+ end.respond_with(successful_void_and_refund_response)
+
+ assert_success response
+ end
+
+ def test_successful_partial_refund
+ response = stub_comms do
+ @gateway.refund(@amount - 1, 'abc123|authorization123', @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['referenceTransactionDetails']['referenceTransactionId'], 'authorization123'
+ assert_equal request['referenceTransactionDetails']['referenceTransactionType'], 'CHARGES'
+ assert_nil request['transactionDetails']['captureFlag']
+ assert_equal request['amount']['total'], ((@amount - 1) / 100.0).to_f
+ assert_equal request['amount']['currency'], 'USD'
+ end.respond_with(successful_void_and_refund_response)
+
+ assert_success response
+ end
+
+ def test_successful_purchase_cit_with_gsf
+ options = stored_credential_options(:cardholder, :unscheduled, :initial)
+ options[:data_entry_source] = 'MOBILE_WEB'
+ options[:pos_entry_mode] = 'MANUAL'
+ options[:pos_condition_code] = 'CARD_PRESENT'
+ response = stub_comms do
+ @gateway.purchase(@amount, 'authorization123', options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['transactionInteraction']['origin'], 'ECOM'
+ assert_equal request['transactionInteraction']['eciIndicator'], 'CHANNEL_ENCRYPTED'
+ assert_equal request['transactionInteraction']['posConditionCode'], 'CARD_PRESENT'
+ assert_equal request['transactionInteraction']['posEntryMode'], 'MANUAL'
+ assert_equal request['transactionInteraction']['additionalPosInformation']['dataEntrySource'], 'MOBILE_WEB'
+ end.respond_with(successful_purchase_response)
+ assert_success response
+ end
+
+ def test_successful_purchase_mit_with_gsf
+ options = stored_credential_options(:merchant, :recurring)
+ options[:origin] = 'POS'
+ options[:pos_entry_mode] = 'MANUAL'
+ options[:data_entry_source] = 'MOBILE_WEB'
+ response = stub_comms do
+ @gateway.purchase(@amount, 'authorization123', options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['transactionInteraction']['origin'], 'POS'
+ assert_equal request['transactionInteraction']['eciIndicator'], 'CHANNEL_ENCRYPTED'
+ assert_equal request['transactionInteraction']['posConditionCode'], 'CARD_NOT_PRESENT_ECOM'
+ assert_equal request['transactionInteraction']['posEntryMode'], 'MANUAL'
+ assert_equal request['transactionInteraction']['additionalPosInformation']['dataEntrySource'], 'MOBILE_WEB'
+ end.respond_with(successful_purchase_response)
+ assert_success response
+ end
+
+ def test_successful_purchase_with_gsf_scheme_reference_transaction_id
+ @options = stored_credential_options(:cardholder, :unscheduled, :initial)
+ @options[:physical_goods_indicator] = true
+ @options[:scheme_reference_transaction_id] = '12345'
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['storedCredentials']['schemeReferenceTransactionId'], '12345'
+ assert_equal request['transactionDetails']['physicalGoodsIndicator'], true
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ def stored_credential_options(*args, ntid: nil)
+ {
+ order_id: '#1001',
+ stored_credential: stored_credential(*args, ntid: ntid)
+ }
+ end
+
+ def test_successful_store
+ response = stub_comms do
+ @gateway.store(@credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal request['merchantDetails']['terminalId'], @gateway.options[:terminal_id]
+ assert_equal request['merchantDetails']['merchantId'], @gateway.options[:merchant_id]
+ assert_equal request['source']['card']['cardData'], @credit_card.number
+ assert_equal request['source']['card']['securityCode'], @credit_card.verification_value
+ assert_equal request['source']['card']['securityCodeIndicator'], 'PROVIDED'
+ end.respond_with(successful_store_response)
+
+ assert_success response
+ assert_equal response.params['paymentTokens'].first['tokenData'], response.authorization
+ end
+
+ def test_successful_verify
+ stub_comms do
+ @gateway.verify(@credit_card, @options)
+ end.check_request do |endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_match %r{verification}, endpoint
+ assert_equal request['source']['sourceType'], 'PaymentCard'
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_getting_avs_cvv_from_response
+ gateway_resp = {
+ 'paymentReceipt' => {
+ 'processorResponseDetails' => {
+ 'bankAssociationDetails' => {
+ 'associationResponseCode' => 'V000',
+ 'avsSecurityCodeResponse' => {
+ 'streetMatch' => 'NONE',
+ 'postalCodeMatch' => 'NONE',
+ 'securityCodeMatch' => 'NOT_CHECKED',
+ 'association' => {
+ 'securityCodeResponse' => 'X',
+ 'avsCode' => 'Y'
+ }
+ }
+ }
+ }
+ }
+ }
+
+ assert_equal 'X', @gateway.send(:get_avs_cvv, gateway_resp, 'cvv')
+ assert_equal 'Y', @gateway.send(:get_avs_cvv, gateway_resp, 'avs')
+ end
+
+ def test_successful_scrub
+ assert @gateway.supports_scrubbing?
+ assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed
+ end
+
+ def test_uses_order_id_to_keep_transaction_references_when_provided
+ @options[:order_id] = 'abc123'
+
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ assert_equal 'abc123|6304d53be8d94312a620962afc9c012d', response.authorization
+ end
+
+ def test_detect_success_state_for_verify_on_success_transaction
+ gateway_resp = {
+ 'gatewayResponse' => {
+ 'transactionState' => 'VERIFIED'
+ }
+ }
+
+ assert @gateway.send :success_from, gateway_resp, 'verify'
+ end
+
+ def test_detect_success_state_for_verify_on_failure_transaction
+ gateway_resp = {
+ 'gatewayResponse' => {
+ 'transactionState' => 'NOT_VERIFIED'
+ }
+ }
+
+ refute @gateway.send :success_from, gateway_resp, 'verify'
+ end
+
+ def test_add_reference_transaction_details_capture_reference_id
+ authorization = '|922e-59fc86a36c03'
+
+ @gateway.send :add_reference_transaction_details, @post, authorization, {}, :capture
+ assert_equal '922e-59fc86a36c03', @post[:referenceTransactionDetails][:referenceTransactionId]
+ assert_nil @post[:referenceTransactionDetails][:referenceTransactionType]
+ end
+
+ def test_add_reference_transaction_details_void_reference_id
+ authorization = '|922e-59fc86a36c03'
+
+ @gateway.send :add_reference_transaction_details, @post, authorization, {}, :void
+ assert_equal '922e-59fc86a36c03', @post[:referenceTransactionDetails][:referenceTransactionId]
+ assert_equal 'CHARGES', @post[:referenceTransactionDetails][:referenceTransactionType]
+ end
+
+ def test_add_reference_transaction_details_refund_reference_id
+ authorization = '|922e-59fc86a36c03'
+
+ @gateway.send :add_reference_transaction_details, @post, authorization, {}, :refund
+ assert_equal '922e-59fc86a36c03', @post[:referenceTransactionDetails][:referenceTransactionId]
+ assert_equal 'CHARGES', @post[:referenceTransactionDetails][:referenceTransactionType]
+ end
+
+ def test_successful_purchase_when_encrypted_credit_card_present
+ @options[:order_id] = 'abc123'
+ @options[:encryption_data] = {
+ keyId: SecureRandom.uuid,
+ encryptionType: 'RSA',
+ encryptionBlock: SecureRandom.alphanumeric(20),
+ encryptionBlockFields: 'card.cardData:16,card.nameOnCard:8,card.expirationMonth:2,card.expirationYear:4,card.securityCode:3',
+ encryptionTarget: 'MANUAL'
+ }
+
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ refute_nil request['source']['encryptionData']
+ assert_equal request['source']['sourceType'], 'PaymentCard'
+ assert_equal request['source']['encryptionData']['keyId'], @options[:encryption_data][:keyId]
+ assert_equal request['source']['encryptionData']['encryptionType'], 'RSA'
+ assert_equal request['source']['encryptionData']['encryptionBlock'], @options[:encryption_data][:encryptionBlock]
+ assert_equal request['source']['encryptionData']['encryptionBlockFields'], @options[:encryption_data][:encryptionBlockFields]
+ assert_equal request['source']['encryptionData']['encryptionTarget'], 'MANUAL'
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ private
+
+ def successful_purchase_response
+ <<~RESPONSE
+ {
+ "gatewayResponse": {
+ "transactionType": "CHARGE",
+ "transactionState": "CAPTURED",
+ "transactionOrigin": "ECOM",
+ "transactionProcessingDetails": {
+ "orderId": "CHG018048a66aafc64d789cb018a53c30fd74",
+ "transactionTimestamp": "2022-10-06T11:27:45.593359Z",
+ "apiTraceId": "6304d53be8d94312a620962afc9c012d",
+ "clientRequestId": "5106241",
+ "transactionId": "6304d53be8d94312a620962afc9c012d"
+ }
+ },
+ "source": {
+ "sourceType": "PaymentCard",
+ "card": {
+ "expirationMonth": "02",
+ "expirationYear": "2035",
+ "securityCodeIndicator": "PROVIDED",
+ "bin": "400555",
+ "last4": "0019",
+ "scheme": "VISA"
+ }
+ },
+ "paymentReceipt": {
+ "approvedAmount": {
+ "total": 12.04,
+ "currency": "USD"
+ },
+ "processorResponseDetails": {
+ "approvalStatus": "APPROVED",
+ "approvalCode": "000238",
+ "referenceNumber": "962afc9c012d",
+ "processor": "FISERV",
+ "host": "NASHVILLE",
+ "networkInternationalId": "0001",
+ "responseCode": "000",
+ "responseMessage": "Approved",
+ "hostResponseCode": "00",
+ "additionalInfo": [
+ {
+ "name": "HOST_RAW_PROCESSOR_RESPONSE",
+ "value": "ARAyIAHvv70O77+9AAAAAAAAAAAAEgQQBhAnRQE1JAABWTk2MmFmYzljMDEyZDAwMDIzODAwMDk5OTk5OTk="
+ }
+ ]
+ }
+ },
+ "transactionDetails": {
+ "captureFlag": true,
+ "transactionCaptureType": "hcs",
+ "processingCode": "000000",
+ "merchantInvoiceNumber": "123456789012",
+ "createToken": true,
+ "retrievalReferenceNumber": "962afc9c012d"
+ },
+ "transactionInteraction": {
+ "posEntryMode": "UNSPECIFIED",
+ "posConditionCode": "CARD_NOT_PRESENT_ECOM",
+ "additionalPosInformation": {
+ "dataEntrySource": "UNSPECIFIED",
+ "posFeatures": {
+ "pinAuthenticationCapability": "UNSPECIFIED",
+ "terminalEntryCapability": "UNSPECIFIED"
+ }
+ },
+ "hostPosConditionCode": "59"
+ },
+ "merchantDetails": {
+ "tokenType": "BBY0",
+ "terminalId": "10000001",
+ "merchantId": "100008000003683"
+ },
+ "networkDetails": {
+ "network": {
+ "network": "Visa"
+ }
+ }
+ }
+ RESPONSE
+ end
+
+ def successful_authorize_response
+ <<~RESPONSE
+ {
+ "gatewayResponse": {
+ "transactionType": "CHARGE",
+ "transactionState": "AUTHORIZED",
+ "transactionOrigin": "ECOM",
+ "transactionProcessingDetails": {
+ "orderId": "CHG01fb29348b9f8a48ed875e6bea3af41744",
+ "transactionTimestamp": "2022-10-06T11:28:27.131701Z",
+ "apiTraceId": "000bc22420f448288f1226d28dfdf275",
+ "clientRequestId": "9573527",
+ "transactionId": "000bc22420f448288f1226d28dfdf275"
+ }
+ },
+ "source": {
+ "sourceType": "PaymentCard",
+ "card": {
+ "expirationMonth": "02",
+ "expirationYear": "2035",
+ "bin": "400555",
+ "last4": "0019",
+ "scheme": "VISA"
+ }
+ },
+ "paymentReceipt": {
+ "approvedAmount": {
+ "total": 12.04,
+ "currency": "USD"
+ },
+ "processorResponseDetails": {
+ "approvalStatus": "APPROVED",
+ "approvalCode": "000239",
+ "referenceNumber": "26d28dfdf275",
+ "processor": "FISERV",
+ "host": "NASHVILLE",
+ "networkInternationalId": "0001",
+ "responseCode": "000",
+ "responseMessage": "Approved",
+ "hostResponseCode": "00",
+ "additionalInfo": [
+ {
+ "name": "HOST_RAW_PROCESSOR_RESPONSE",
+ "value": "ARAyIAHvv70O77+9AAAAAAAAAAAAEgQQBhAoJzQ2aAABWTI2ZDI4ZGZkZjI3NTAwMDIzOTAwMDk5OTk5OTk="
+ }
+ ]
+ }
+ },
+ "transactionDetails": {
+ "captureFlag": false,
+ "transactionCaptureType": "hcs",
+ "processingCode": "000000",
+ "merchantInvoiceNumber": "123456789012",
+ "createToken": true,
+ "retrievalReferenceNumber": "26d28dfdf275"
+ },
+ "transactionInteraction": {
+ "posEntryMode": "UNSPECIFIED",
+ "posConditionCode": "CARD_NOT_PRESENT_ECOM",
+ "additionalPosInformation": {
+ "dataEntrySource": "UNSPECIFIED",
+ "posFeatures": {
+ "pinAuthenticationCapability": "UNSPECIFIED",
+ "terminalEntryCapability": "UNSPECIFIED"
+ }
+ },
+ "hostPosConditionCode": "59"
+ },
+ "merchantDetails": {
+ "tokenType": "BBY0",
+ "terminalId": "10000001",
+ "merchantId": "100008000003683"
+ },
+ "networkDetails": {
+ "network": {
+ "network": "Visa"
+ }
+ }
+ }
+ RESPONSE
+ end
+
+ def failed_purchase_and_authorize_response
+ <<~RESPONSE
+ {
+ "gatewayResponse": {
+ "transactionType": "CHARGE",
+ "transactionState": "AUTHORIZED",
+ "transactionOrigin": "ECOM",
+ "transactionProcessingDetails": {
+ "orderId": "R-3b83fca8-2f9c-4364-86ae-12c91f1fcf16",
+ "transactionTimestamp": "2016-04-16T16:06:05Z",
+ "apiTraceId": "1234567a1234567b1234567c1234567d",
+ "clientRequestId": "30dd879c-ee2f-11db-8314-0800200c9a66",
+ "transactionId": "838916029301"
+ }
+ },
+ "error": [
+ {
+ "type": "HOST",
+ "code": "string",
+ "field": "source.sourceType",
+ "message": "Missing type ID property.",
+ "additionalInfo": "The Reauthorization request was not successful and the Cancel of referenced authorization transaction was not processed, per Auth_before_Cancel configuration"
+ }
+ ]
+ }
+ RESPONSE
+ end
+
+ def successful_void_and_refund_response
+ <<~RESPONSE
+ {
+ "gatewayResponse": {
+ "transactionType": "CANCEL",
+ "transactionState": "AUTHORIZED",
+ "transactionOrigin": "ECOM",
+ "transactionProcessingDetails": {
+ "transactionTimestamp": "2021-06-20T23:42:48Z",
+ "orderId": "RKOrdID-525133851837",
+ "apiTraceId": "362866ac81864d7c9d1ff8b5aa6e98db",
+ "clientRequestId": "4345791",
+ "transactionId": "84356531338"
+ }
+ },
+ "source": {
+ "sourceType": "PaymentCard",
+ "card": {
+ "bin": "40055500",
+ "last4": "0019",
+ "scheme": "VISA",
+ "expirationMonth": "10",
+ "expirationYear": "2030"
+ }
+ },
+ "paymentReceipt": {
+ "approvedAmount": {
+ "total": 12.04,
+ "currency": "USD"
+ },
+ "merchantName": "Merchant Name",
+ "merchantAddress": "123 Peach Ave",
+ "merchantCity": "Atlanta",
+ "merchantStateOrProvince": "GA",
+ "merchantPostalCode": "12345",
+ "merchantCountry": "US",
+ "merchantURL": "https://www.somedomain.com",
+ "processorResponseDetails": {
+ "approvalStatus": "APPROVED",
+ "approvalCode": "OK5882",
+ "schemeTransactionId": "0225MCC625628",
+ "processor": "FISERV",
+ "host": "NASHVILLE",
+ "responseCode": "000",
+ "responseMessage": "APPROVAL",
+ "hostResponseCode": "00",
+ "hostResponseMessage": "APPROVAL",
+ "localTimestamp": "2021-06-20T23:42:48Z",
+ "bankAssociationDetails": {
+ "associationResponseCode": "000",
+ "transactionTimestamp": "2021-06-20T23:42:48Z"
+ }
+ }
+ },
+ "transactionDetails": {
+ "merchantInvoiceNumber": "123456789012"
+ }
+ }
+ RESPONSE
+ end
+
+ def successful_store_response
+ <<~RESPONSE
+ {
+ "gatewayResponse": {
+ "transactionType": "TOKENIZE",
+ "transactionState": "AUTHORIZED",
+ "transactionOrigin": "ECOM",
+ "transactionProcessingDetails": {
+ "transactionTimestamp": "2021-06-20T23:42:48Z",
+ "orderId": "RKOrdID-525133851837",
+ "apiTraceId": "362866ac81864d7c9d1ff8b5aa6e98db",
+ "clientRequestId": "4345791",
+ "transactionId": "84356531338"
+ }
+ },
+ "source": {
+ "sourceType": "PaymentCard",
+ "card": {
+ "bin": "40055500",
+ "last4": "0019",
+ "scheme": "VISA",
+ "expirationMonth": "10",
+ "expirationYear": "2030"
+ }
+ },
+ "paymentTokens": [
+ {
+ "tokenData": "8519371934460009",
+ "tokenSource": "TRANSARMOR",
+ "tokenResponseCode": "000",
+ "tokenResponseDescription": "SUCCESS"
+ },
+ {
+ "tokenData": "8519371934460010",
+ "tokenSource": "CHASE",
+ "tokenResponseCode": "000",
+ "tokenResponseDescription": "SUCCESS"
+ }
+ ],
+ "processorResponseDetails": {
+ "approvalStatus": "APPROVED",
+ "approvalCode": "OK5882",
+ "schemeTransactionId": "0225MCC625628",
+ "processor": "FISERV",
+ "host": "NASHVILLE",
+ "responseCode": "000",
+ "responseMessage": "APPROVAL",
+ "hostResponseCode": "00",
+ "hostResponseMessage": "APPROVAL",
+ "localTimestamp": "2021-06-20T23:42:48Z",
+ "bankAssociationDetails": {
+ "associationResponseCode": "000",
+ "transactionTimestamp": "2021-06-20T23:42:48Z"
+ }
+ }
+ }
+ RESPONSE
+ end
+
+ def pre_scrubbed
+ <<~PRE_SCRUBBED
+ opening connection to cert.api.fiservapps.com:443...
+ opened
+ starting SSL for cert.api.fiservapps.com:443...
+ SSL established
+ <- "POST /ch/payments/v1/charges HTTP/1.1\r\nContent-Type: application/json\r\nClient-Request-Id: 3473900\r\nApi-Key: nEcoHEQZjKtkKW9dN6yH7x4gO2EIARKe\r\nTimestamp: 1670258885014\r\nAccept-Language: application/json\r\nAuth-Token-Type: HMAC\r\nAccept: application/json\r\nAuthorization: TQh0nE38Mv7cbxbX3oSIUxZ4RzMkTmS2hpUSd6Rgi98=\r\nConnection: close\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nUser-Agent: Ruby\r\nHost: cert.api.fiservapps.com\r\nContent-Length: 500\r\n\r\n"
+ <- "{\"transactionDetails\":{\"captureFlag\":true,\"merchantInvoiceNumber\":\"995952121195\"},\"amount\":{\"total\":12.04,\"currency\":\"USD\"},\"source\":{\"sourceType\":\"PaymentCard\",\"card\":{\"cardData\":\"4005550000000019\",\"expirationMonth\":\"02\",\"expirationYear\":\"2035\",\"securityCode\":\"123\",\"securityCodeIndicator\":\"PROVIDED\"}},\"transactionInteraction\":{\"origin\":\"ECOM\",\"eciIndicator\":\"CHANNEL_ENCRYPTED\",\"posConditionCode\":\"CARD_NOT_PRESENT_ECOM\"},\"merchantDetails\":{\"terminalId\":\"10000001\",\"merchantId\":\"100008000003683\"}}"
+ -> "HTTP/1.1 201 Created\r\n"
+ -> "Date: Mon, 05 Dec 2022 16:48:06 GMT\r\n"
+ -> "Content-Type: application/json\r\n"
+ -> "Content-Length: 1709\r\n"
+ -> "Connection: close\r\n"
+ -> "Expires: 0\r\n"
+ -> "Referrer-Policy: no-referrer\r\n"
+ -> "X-Frame-Options: DENY\r\n"
+ -> "X-Vcap-Request-Id: 30397096-5cb9-46e1-7c63-3ac2494ca38e\r\n"
+ -> "targetServerReceivedEndTimestamp: 1670258886388\r\n"
+ -> "targetServerSentStartTimestamp: 1670258885212\r\n"
+ -> "X-Xss-Protection: 1; mode=block\r\n"
+ -> "X-Content-Type-Options: nosniff\r\n"
+ -> "Strict-Transport-Security: max-age=31536000; includeSubDomains\r\n"
+ -> "Cache-Control: no-store, no-cache, must-revalidate\r\n"
+ -> "Pragma: no-cache\r\n"
+ -> "Access-Control-Max-Age: 86400\r\n"
+ -> "ApiTraceId: 19d178570f274a2196540af6e2e0bf55\r\n"
+ -> "Via: 1.1 dca1-bit16021\r\n"
+ -> "\r\n"
+ reading 1709 bytes...
+ -> "{\"gatewayResponse\":{\"transactionType\":\"CHARGE\",\"transactionState\":\"CAPTURED\",\"transactionOrigin\":\"ECOM\",\"transactionProcessingDetails\":{\"orderId\":\"CHG0147086beb95194e808a3bf88e052285d7\",\"transactionTimestamp\":\"2022-12-05T16:48:05.358725Z\",\"apiTraceId\":\"19d178570f274a2196540af6e2e0bf55\",\"clientRequestId\":\"3473900\",\"transactionId\":\"19d178570f274a2196540af6e2e0bf55\"}},\"source\":{\"sourceType\":\"PaymentCard\",\"card\":{\"expirationMonth\":\"02\",\"expirationYear\":\"2035\",\"securityCodeIndicator\":\"PROVIDED\",\"bin\":\"400555\",\"last4\":\"0019\",\"scheme\":\"VISA\"}},\"paymentReceipt\":{\"approvedAmount\":{\"total\":12.04,\"currency\":\"USD\"},\"processorResponseDetails\":{\"approvalStatus\":\"APPROVED\",\"approvalCode\":\"000119\",\"referenceNumber\":\"0af6e2e0bf55\",\"processor\":\"FISERV\",\"host\":\"NASHVILLE\",\"networkInternationalId\":\"0001\",\"responseCode\":\"000\",\"responseMessage\":\"Approved\",\"hostResponseCode\":\"00\",\"additionalInfo\":[{\"name\":\"HOST_RAW_PROCESSOR_RESPONSE\",\"value\":\"ARAyIAHvv70O77+9AAIAAAAAAAAAEgQSBRZIBTNCVQABWTBhZjZlMmUwYmY1NTAwMDExOTAwMDk5OTk5OTkABAACMTQ=\"}]}},\"transactionDetails\":{\"captureFlag\":true,\"transactionCaptureType\":\"hcs\",\"processingCode\":\"000000\",\"merchantInvoiceNumber\":\"995952121195\",\"createToken\":true,\"retrievalReferenceNumber\":\"0af6e2e0bf55\",\"cavvInPrimary\":false},\"transactionInteraction\":{\"posEntryMode\":\"UNSPECIFIED\",\"posConditionCode\":\"CARD_NOT_PRESENT_ECOM\",\"additionalPosInformation\":{\"dataEntrySource\":\"UNSPECIFIED\",\"posFeatures\":{\"pinAuthenticationCapability\":\"UNSPECIFIED\",\"terminalEntryCapability\":\"UNSPECIFIED\"}},\"hostPosEntryMode\":\"000\",\"hostPosConditionCode\":\"59\"},\"merchantDetails\":{\"tokenType\":\"BBY0\",\"terminalId\":\"10000001\",\"merchantId\":\"100008000003683\"},\"networkDetails\":{\"network\":{\"network\":\"Visa\"}}}"
+ read 1709 bytes
+ Conn close
+ PRE_SCRUBBED
+ end
+
+ def post_scrubbed
+ <<~POST_SCRUBBED
+ opening connection to cert.api.fiservapps.com:443...
+ opened
+ starting SSL for cert.api.fiservapps.com:443...
+ SSL established
+ <- "POST /ch/payments/v1/charges HTTP/1.1\r\nContent-Type: application/json\r\nClient-Request-Id: 3473900\r\nApi-Key: [FILTERED]\r\nTimestamp: 1670258885014\r\nAccept-Language: application/json\r\nAuth-Token-Type: HMAC\r\nAccept: application/json\r\nAuthorization: [FILTERED]\r\nConnection: close\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nUser-Agent: Ruby\r\nHost: cert.api.fiservapps.com\r\nContent-Length: 500\r\n\r\n"
+ <- "{\"transactionDetails\":{\"captureFlag\":true,\"merchantInvoiceNumber\":\"995952121195\"},\"amount\":{\"total\":12.04,\"currency\":\"USD\"},\"source\":{\"sourceType\":\"PaymentCard\",\"card\":{\"cardData\":\"[FILTERED]\",\"expirationMonth\":\"02\",\"expirationYear\":\"2035\",\"securityCode\":\"[FILTERED]\",\"securityCodeIndicator\":\"PROVIDED\"}},\"transactionInteraction\":{\"origin\":\"ECOM\",\"eciIndicator\":\"CHANNEL_ENCRYPTED\",\"posConditionCode\":\"CARD_NOT_PRESENT_ECOM\"},\"merchantDetails\":{\"terminalId\":\"10000001\",\"merchantId\":\"100008000003683\"}}"
+ -> "HTTP/1.1 201 Created\r\n"
+ -> "Date: Mon, 05 Dec 2022 16:48:06 GMT\r\n"
+ -> "Content-Type: application/json\r\n"
+ -> "Content-Length: 1709\r\n"
+ -> "Connection: close\r\n"
+ -> "Expires: 0\r\n"
+ -> "Referrer-Policy: no-referrer\r\n"
+ -> "X-Frame-Options: DENY\r\n"
+ -> "X-Vcap-Request-Id: 30397096-5cb9-46e1-7c63-3ac2494ca38e\r\n"
+ -> "targetServerReceivedEndTimestamp: 1670258886388\r\n"
+ -> "targetServerSentStartTimestamp: 1670258885212\r\n"
+ -> "X-Xss-Protection: 1; mode=block\r\n"
+ -> "X-Content-Type-Options: nosniff\r\n"
+ -> "Strict-Transport-Security: max-age=31536000; includeSubDomains\r\n"
+ -> "Cache-Control: no-store, no-cache, must-revalidate\r\n"
+ -> "Pragma: no-cache\r\n"
+ -> "Access-Control-Max-Age: 86400\r\n"
+ -> "ApiTraceId: 19d178570f274a2196540af6e2e0bf55\r\n"
+ -> "Via: 1.1 dca1-bit16021\r\n"
+ -> "\r\n"
+ reading 1709 bytes...
+ -> "{\"gatewayResponse\":{\"transactionType\":\"CHARGE\",\"transactionState\":\"CAPTURED\",\"transactionOrigin\":\"ECOM\",\"transactionProcessingDetails\":{\"orderId\":\"CHG0147086beb95194e808a3bf88e052285d7\",\"transactionTimestamp\":\"2022-12-05T16:48:05.358725Z\",\"apiTraceId\":\"19d178570f274a2196540af6e2e0bf55\",\"clientRequestId\":\"3473900\",\"transactionId\":\"19d178570f274a2196540af6e2e0bf55\"}},\"source\":{\"sourceType\":\"PaymentCard\",\"card\":{\"expirationMonth\":\"02\",\"expirationYear\":\"2035\",\"securityCodeIndicator\":\"PROVIDED\",\"bin\":\"400555\",\"last4\":\"0019\",\"scheme\":\"VISA\"}},\"paymentReceipt\":{\"approvedAmount\":{\"total\":12.04,\"currency\":\"USD\"},\"processorResponseDetails\":{\"approvalStatus\":\"APPROVED\",\"approvalCode\":\"000119\",\"referenceNumber\":\"0af6e2e0bf55\",\"processor\":\"FISERV\",\"host\":\"NASHVILLE\",\"networkInternationalId\":\"0001\",\"responseCode\":\"000\",\"responseMessage\":\"Approved\",\"hostResponseCode\":\"00\",\"additionalInfo\":[{\"name\":\"HOST_RAW_PROCESSOR_RESPONSE\",\"value\":\"ARAyIAHvv70O77+9AAIAAAAAAAAAEgQSBRZIBTNCVQABWTBhZjZlMmUwYmY1NTAwMDExOTAwMDk5OTk5OTkABAACMTQ=\"}]}},\"transactionDetails\":{\"captureFlag\":true,\"transactionCaptureType\":\"hcs\",\"processingCode\":\"000000\",\"merchantInvoiceNumber\":\"995952121195\",\"createToken\":true,\"retrievalReferenceNumber\":\"0af6e2e0bf55\",\"cavvInPrimary\":false},\"transactionInteraction\":{\"posEntryMode\":\"UNSPECIFIED\",\"posConditionCode\":\"CARD_NOT_PRESENT_ECOM\",\"additionalPosInformation\":{\"dataEntrySource\":\"UNSPECIFIED\",\"posFeatures\":{\"pinAuthenticationCapability\":\"UNSPECIFIED\",\"terminalEntryCapability\":\"UNSPECIFIED\"}},\"hostPosEntryMode\":\"000\",\"hostPosConditionCode\":\"59\"},\"merchantDetails\":{\"tokenType\":\"BBY0\",\"terminalId\":\"10000001\",\"merchantId\":\"100008000003683\"},\"networkDetails\":{\"network\":{\"network\":\"Visa\"}}}"
+ read 1709 bytes
+ Conn close
+ POST_SCRUBBED
+ end
+end
diff --git a/test/unit/gateways/conekta_test.rb b/test/unit/gateways/conekta_test.rb
index 215a50b1ba3..710e7f063a3 100644
--- a/test/unit/gateways/conekta_test.rb
+++ b/test/unit/gateways/conekta_test.rb
@@ -4,41 +4,41 @@ class ConektaTest < Test::Unit::TestCase
include CommStub
def setup
- @gateway = ConektaGateway.new(:key => 'key_eYvWV7gSDkNYXsmr')
+ @gateway = ConektaGateway.new(key: 'key_eYvWV7gSDkNYXsmr')
@amount = 300
@credit_card = ActiveMerchant::Billing::CreditCard.new(
- :number => '4242424242424242',
- :verification_value => '183',
- :month => '01',
- :year => '2018',
- :first_name => 'Mario F.',
- :last_name => 'Moreno Reyes'
+ number: '4242424242424242',
+ verification_value: '183',
+ month: '01',
+ year: '2018',
+ first_name: 'Mario F.',
+ last_name: 'Moreno Reyes'
)
@declined_card = ActiveMerchant::Billing::CreditCard.new(
- :number => '4000000000000002',
- :verification_value => '183',
- :month => '01',
- :year => '2018',
- :first_name => 'Mario F.',
- :last_name => 'Moreno Reyes'
+ number: '4000000000000002',
+ verification_value: '183',
+ month: '01',
+ year: '2018',
+ first_name: 'Mario F.',
+ last_name: 'Moreno Reyes'
)
@options = {
- :device_fingerprint => '41l9l92hjco6cuekf0c7dq68v4',
- :description => 'Blue clip',
- :success_url => 'https://www.example.com/success',
- :failure_url => 'https://www.example.com/failure',
- :address1 => 'Rio Missisipi #123',
- :address2 => 'Paris',
- :city => 'Guerrero',
- :country => 'Mexico',
- :zip => '5555',
- :customer => 'Mario Reyes',
- :phone => '12345678',
- :carrier => 'Estafeta'
+ device_fingerprint: '41l9l92hjco6cuekf0c7dq68v4',
+ description: 'Blue clip',
+ success_url: 'https://www.example.com/success',
+ failure_url: 'https://www.example.com/failure',
+ address1: 'Rio Missisipi #123',
+ address2: 'Paris',
+ city: 'Guerrero',
+ country: 'Mexico',
+ zip: '5555',
+ customer: 'Mario Reyes',
+ phone: '12345678',
+ carrier: 'Estafeta'
}
end
@@ -69,8 +69,8 @@ def test_unsuccessful_purchase
def test_successful_purchase_with_installments
response = stub_comms(@gateway, :ssl_request) do
- @gateway.purchase(@amount, @credit_card, @options.merge({monthly_installments: '3'}))
- end.check_request do |method, endpoint, data, headers|
+ @gateway.purchase(@amount, @credit_card, @options.merge({ monthly_installments: '3' }))
+ end.check_request do |_method, _endpoint, data, _headers|
assert_match %r{monthly_installments=3}, data
end.respond_with(successful_purchase_response)
@@ -139,7 +139,7 @@ def test_unsuccessful_capture
end
def test_invalid_key
- gateway = ConektaGateway.new(:key => 'invalid_token')
+ gateway = ConektaGateway.new(key: 'invalid_token')
gateway.expects(:ssl_request).returns(failed_login_response)
assert response = gateway.purchase(@amount, @credit_card, @options)
assert_failure response
@@ -154,8 +154,8 @@ def test_adds_application_and_meta_headers
}
response = stub_comms(@gateway, :ssl_request) do
- @gateway.purchase(@amount, 'tok_xxxxxxxxxxxxxxxx', @options.merge(application: application, meta: {its_so_meta: 'even this acronym'}))
- end.check_request do |method, endpoint, data, headers|
+ @gateway.purchase(@amount, 'tok_xxxxxxxxxxxxxxxx', @options.merge(application: application, meta: { its_so_meta: 'even this acronym' }))
+ end.check_request do |_method, _endpoint, _data, headers|
assert_match(/\"application\"/, headers['X-Conekta-Client-User-Agent'])
assert_match(/\"name\":\"app\"/, headers['X-Conekta-Client-User-Agent'])
assert_match(/\"version\":\"1.0\"/, headers['X-Conekta-Client-User-Agent'])
diff --git a/test/unit/gateways/creditcall_test.rb b/test/unit/gateways/creditcall_test.rb
index 146606ff742..9103162f6cf 100644
--- a/test/unit/gateways/creditcall_test.rb
+++ b/test/unit/gateways/creditcall_test.rb
@@ -112,7 +112,7 @@ def test_failed_verify
def test_verification_value_sent
stub_comms do
@gateway.authorize(@amount, @credit_card, @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(%r(123)m, data)
end.respond_with(successful_authorize_response)
end
@@ -121,7 +121,7 @@ def test_verification_value_not_sent
@credit_card.verification_value = ' '
stub_comms do
@gateway.authorize(@amount, @credit_card, @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_no_match(/CSC/, data)
end.respond_with(successful_authorize_response)
end
@@ -129,25 +129,25 @@ def test_verification_value_not_sent
def test_options_add_avs_additional_verification_fields
stub_comms do
@gateway.authorize(@amount, @credit_card, @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_no_match(/AdditionalVerification/, data)
end.respond_with(successful_authorize_response)
stub_comms do
@gateway.authorize(@amount, @credit_card, @options.merge(verify_zip: 'false', verify_address: 'false'))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_no_match(/AdditionalVerification/, data)
end.respond_with(successful_authorize_response)
stub_comms do
@gateway.authorize(@amount, @credit_card, @options.merge(verify_zip: 'true', verify_address: 'true'))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/\n K1C2N6<\/Zip>\n /, data)
end.respond_with(successful_authorize_response)
stub_comms do
@gateway.authorize(@amount, @credit_card, @options.merge(verify_zip: 'true', verify_address: 'false'))
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/ \n K1C2N6<\/Zip>\n <\/AdditionalVerification>\n/, data)
end.respond_with(successful_authorize_response)
end
diff --git a/test/unit/gateways/credorax_test.rb b/test/unit/gateways/credorax_test.rb
index c93b3987470..625953f57f0 100644
--- a/test/unit/gateways/credorax_test.rb
+++ b/test/unit/gateways/credorax_test.rb
@@ -12,18 +12,75 @@ def setup
billing_address: address,
description: 'Store Purchase'
}
+
+ @normalized_3ds_2_options = {
+ reference: '345123',
+ shopper_email: 'john.smith@test.com',
+ shopper_ip: '77.110.174.153',
+ shopper_reference: 'John Smith',
+ billing_address: address,
+ shipping_address: address,
+ order_id: '123',
+ execute_threed: true,
+ three_ds_initiate: '03',
+ f23: '1',
+ three_ds_reqchallengeind: '04',
+ three_ds_challenge_window_size: '01',
+ stored_credential: { reason_type: 'unscheduled' },
+ three_ds_2: {
+ channel: 'browser',
+ notification_url: 'www.example.com',
+ browser_info: {
+ accept_header: 'unknown',
+ depth: 100,
+ java: false,
+ language: 'US',
+ height: 1000,
+ width: 500,
+ timezone: '-120',
+ user_agent: 'unknown'
+ }
+ }
+ }
+
+ @nt_credit_card = network_tokenization_credit_card(
+ '4176661000001015',
+ brand: 'visa',
+ eci: '07',
+ source: :network_token,
+ payment_cryptogram: 'AgAAAAAAosVKVV7FplLgQRYAAAA='
+ )
+
+ @apple_pay_card = network_tokenization_credit_card(
+ '4176661000001015',
+ month: 10,
+ year: Time.new.year + 2,
+ first_name: 'John',
+ last_name: 'Smith',
+ verification_value: '737',
+ payment_cryptogram: 'YwAAAAAABaYcCMX/OhNRQAAAAAA=',
+ eci: '07',
+ transaction_id: 'abc123',
+ source: :apple_pay
+ )
+ end
+
+ def test_supported_card_types
+ klass = @gateway.class
+ assert_equal %i[visa master maestro american_express jcb discover diners_club], klass.supported_cardtypes
end
def test_successful_purchase
response = stub_comms do
@gateway.purchase(@amount, @credit_card)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_no_match(/i8=sample-eci%3Asample-cavv%3Asample-xid/, data)
end.respond_with(successful_purchase_response)
assert_success response
assert_equal '8a82944a5351570601535955efeb513c;006596;02617cf5f02ccaed239b6521748298c5;purchase', response.authorization
+ assert_equal 'Succeeded', response.message
assert response.test?
end
@@ -47,11 +104,12 @@ def test_successful_authorize_and_capture
capture = stub_comms do
@gateway.capture(@amount, response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/8a829449535154bc0153595952a2517a/, data)
end.respond_with(successful_capture_response)
assert_success capture
+ assert_equal 'Succeeded', response.message
end
def test_failed_authorize
@@ -70,6 +128,7 @@ def test_failed_capture
end.respond_with(failed_capture_response)
assert_failure response
+ assert_equal '2. At least one of input parameters is malformed.: Parameter [g4] cannot be empty.', response.message
end
def test_successful_void
@@ -82,21 +141,23 @@ def test_successful_void
void = stub_comms do
@gateway.void(response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/8a829449535154bc0153595952a2517a/, data)
end.respond_with(successful_void_response)
assert_success void
+ assert_equal 'Succeeded', void.message
end
def test_failed_void
response = stub_comms do
@gateway.void('5d53a33d960c46d00f5dc061947d998c')
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/5d53a33d960c46d00f5dc061947d998c/, data)
end.respond_with(failed_void_response)
assert_failure response
+ assert_equal '2. At least one of input parameters is malformed.: Parameter [g4] cannot be empty.', response.message
end
def test_successful_refund
@@ -109,10 +170,30 @@ def test_successful_refund
refund = stub_comms do
@gateway.refund(@amount, response.authorization)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/8a82944a5351570601535955efeb513c/, data)
end.respond_with(successful_refund_response)
+ assert_success refund
+ assert_equal 'Succeeded', refund.message
+ end
+
+ def test_successful_refund_with_recipient_fields
+ refund_options = {
+ recipient_street_address: 'street',
+ recipient_city: 'chicago',
+ recipient_province_code: '312',
+ recipient_country_code: 'US'
+ }
+ refund = stub_comms do
+ @gateway.refund(@amount, '123', refund_options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/j6=street/, data)
+ assert_match(/j7=chicago/, data)
+ assert_match(/j8=312/, data)
+ assert_match(/j9=USA/, data)
+ end.respond_with(successful_refund_response)
+
assert_success refund
end
@@ -122,6 +203,43 @@ def test_failed_refund
end.respond_with(failed_refund_response)
assert_failure response
+ assert_equal '2. At least one of input parameters is malformed.: Parameter [g4] cannot be empty.', response.message
+ end
+
+ def test_successful_referral_cft
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ assert_equal '8a82944a5351570601535955efeb513c;006596;02617cf5f02ccaed239b6521748298c5;purchase', response.authorization
+
+ referral_cft = stub_comms do
+ @gateway.refund(@amount, response.authorization, { referral_cft: true, first_name: 'John', last_name: 'Smith' })
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/8a82944a5351570601535955efeb513c/, data)
+ # Confirm that `j5` (first name) and `j13` (surname) parameters are present
+ # These fields are required for CFT payouts as of Sept 1, 2020
+ assert_match(/j5=John/, data)
+ assert_match(/j13=Smith/, data)
+ # Confirm that the transaction type is `referral_cft`
+ assert_match(/O=34/, data)
+ end.respond_with(successful_referral_cft_response)
+
+ assert_success referral_cft
+ assert_equal 'Succeeded', referral_cft.message
+ end
+
+ def test_failed_referral_cft
+ response = stub_comms do
+ @gateway.refund(nil, '', referral_cft: true)
+ end.check_request do |_endpoint, data, _headers|
+ # Confirm that the transaction type is `referral_cft`
+ assert_match(/O=34/, data)
+ end.respond_with(failed_referral_cft_response)
+
+ assert_failure response
+ assert_equal 'Referred to transaction has not been found.', response.message
end
def test_successful_credit
@@ -132,9 +250,27 @@ def test_successful_credit
assert_success response
assert_equal '8a82944a53515706015359604c135301;;868f8b942fae639d28e27e8933d575d4;credit', response.authorization
+ assert_equal 'Succeeded', response.message
assert response.test?
end
+ def test_credit_sends_correct_action_code
+ stub_comms do
+ @gateway.credit(@amount, @credit_card)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/O=35/, data)
+ end.respond_with(successful_credit_response)
+ end
+
+ def test_credit_sends_customer_name
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, { first_name: 'Test', last_name: 'McTest' })
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/j5=Test/, data)
+ assert_match(/j13=McTest/, data)
+ end.respond_with(successful_credit_response)
+ end
+
def test_failed_credit
response = stub_comms do
@gateway.credit(@amount, @credit_card)
@@ -174,13 +310,144 @@ def test_transcript_scrubbing
assert_equal scrubbed_transcript, @gateway.scrub(transcript)
end
- def test_adds_3d_secure_fields
- options_with_3ds = @options.merge({eci: 'sample-eci', cavv: 'sample-cavv', xid: 'sample-xid'})
+ def test_adds_3d2_secure_fields
+ options_with_3ds = @normalized_3ds_2_options
response = stub_comms do
@gateway.purchase(@amount, @credit_card, options_with_3ds)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/3ds_channel=02/, data)
+ assert_match(/3ds_transtype=01/, data)
+ assert_match(/3ds_initiate=03/, data)
+ assert_match(/f23=1/, data)
+ assert_match(/3ds_reqchallengeind=04/, data)
+ assert_match(/3ds_redirect_url=www.example.com/, data)
+ assert_match(/3ds_challengewindowsize=01/, data)
+ assert_match(/d5=unknown/, data)
+ assert_match(/3ds_browsertz=-120/, data)
+ assert_match(/3ds_browserscreenwidth=500/, data)
+ assert_match(/3ds_browserscreenheight=1000/, data)
+ assert_match(/3ds_browsercolordepth=100/, data)
+ assert_match(/d6=US/, data)
+ assert_match(/3ds_browserjavaenabled=false/, data)
+ assert_match(/3ds_browseracceptheader=unknown/, data)
+ assert_match(/3ds_shipaddrstate=ON/, data)
+ assert_match(/3ds_shipaddrpostcode=K1C2N6/, data)
+ assert_match(/3ds_shipaddrline2=Apt\+1/, data)
+ assert_match(/3ds_shipaddrline1=456\+My\+Street/, data)
+ assert_match(/3ds_shipaddrcountry=CA/, data)
+ assert_match(/3ds_shipaddrcity=Ottawa/, data)
+ refute_match(/3ds_version/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+
+ assert_equal '8a82944a5351570601535955efeb513c;006596;02617cf5f02ccaed239b6521748298c5;purchase', response.authorization
+ assert response.test?
+ end
+
+ def test_does_not_add_incomplete_3d2_shipping_address
+ incomplete_shipping_address = {
+ state: 'ON',
+ zip: 'K1C2N6',
+ address1: '456 My Street',
+ address2: '',
+ country: 'CA',
+ city: 'Ottawa'
+ }
+ options_with_3ds = @normalized_3ds_2_options.merge(shipping_address: incomplete_shipping_address)
+
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, options_with_3ds)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/3ds_initiate=03/, data)
+ assert_not_match(/3ds_shipaddrstate=/, data)
+ assert_not_match(/3ds_shipaddrpostcode=/, data)
+ assert_not_match(/3ds_shipaddrline1=/, data)
+ assert_not_match(/3ds_shipaddrline2=/, data)
+ assert_not_match(/3ds_shipaddrcountry=/, data)
+ assert_not_match(/3ds_shipaddrcity=/, data)
+ end.respond_with(successful_purchase_response)
+ assert_success response
+ assert response.test?
+ end
+
+ def test_adds_correct_3ds_browsercolordepth_when_color_depth_is_30
+ @normalized_3ds_2_options[:three_ds_2][:browser_info][:depth] = 30
+
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, @normalized_3ds_2_options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/3ds_browsercolordepth=32/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+
+ assert_equal '8a82944a5351570601535955efeb513c;006596;02617cf5f02ccaed239b6521748298c5;purchase', response.authorization
+ assert response.test?
+ end
+
+ def test_adds_3d2_secure_fields_with_3ds_transtype_specified
+ options_with_3ds = @normalized_3ds_2_options.merge(three_ds_transtype: '03')
+
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, options_with_3ds)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/3ds_channel=02/, data)
+ assert_match(/3ds_transtype=03/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+
+ assert_equal '8a82944a5351570601535955efeb513c;006596;02617cf5f02ccaed239b6521748298c5;purchase', response.authorization
+ assert response.test?
+ end
+
+ def test_purchase_adds_3d_secure_fields
+ options_with_3ds = @options.merge({ eci: 'sample-eci', cavv: 'sample-cavv', xid: 'sample-xid', three_ds_version: '1.0.2' })
+
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, options_with_3ds)
+ end.check_request do |_endpoint, data, _headers|
assert_match(/i8=sample-eci%3Asample-cavv%3Asample-xid/, data)
+ assert_match(/3ds_version=1.0&/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+
+ assert_equal '8a82944a5351570601535955efeb513c;006596;02617cf5f02ccaed239b6521748298c5;purchase', response.authorization
+ assert response.test?
+ end
+
+ def test_purchase_adds_3d_secure_fields_via_normalized_hash
+ version = '1.0.2'
+ eci = 'sample-eci'
+ cavv = 'sample-cavv'
+ xid = 'sample-xid'
+ options_with_normalized_3ds = @options.merge(
+ three_d_secure: {
+ version: version,
+ eci: eci,
+ cavv: cavv,
+ xid: xid
+ }
+ )
+
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, options_with_normalized_3ds)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/i8=#{eci}%3A#{cavv}%3A#{xid}/, data)
+ assert_match(/3ds_version=1.0&/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_3ds_channel_field_set_by_stored_credential_initiator
+ options_with_3ds = @normalized_3ds_2_options.merge(stored_credential_options(:merchant, :unscheduled, id: 'abc123'))
+
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, options_with_3ds)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/3ds_channel=03/, data)
end.respond_with(successful_purchase_response)
assert_success response
@@ -189,12 +456,28 @@ def test_adds_3d_secure_fields
assert response.test?
end
+ def test_authorize_adds_3d_secure_fields
+ options_with_3ds = @options.merge({ eci: 'sample-eci', cavv: 'sample-cavv', xid: 'sample-xid' })
+
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options_with_3ds)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/i8=sample-eci%3Asample-cavv%3Asample-xid/, data)
+ assert_match(/3ds_version=1.0/, data)
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+
+ assert_equal '8a82944a5351570601535955efeb513c;006596;02617cf5f02ccaed239b6521748298c5;authorize', response.authorization
+ assert response.test?
+ end
+
def test_defaults_3d_secure_cavv_field_to_none_if_not_present
- options_with_3ds = @options.merge({eci: 'sample-eci', xid: 'sample-xid'})
+ options_with_3ds = @options.merge({ eci: 'sample-eci', xid: 'sample-xid' })
response = stub_comms do
@gateway.purchase(@amount, @credit_card, options_with_3ds)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/i8=sample-eci%3Anone%3Asample-xid/, data)
end.respond_with(successful_purchase_response)
@@ -204,36 +487,622 @@ def test_defaults_3d_secure_cavv_field_to_none_if_not_present
assert response.test?
end
- def test_adds_a9_field
- options_with_3ds = @options.merge({transaction_type: '8'})
+ def test_adds_3ds2_fields_via_normalized_hash
+ version = '2'
+ eci = '05'
+ cavv = '637574652070757070792026206b697474656e73'
+ ds_transaction_id = '97267598-FAE6-48F2-8083-C23433990FBC'
+ options_with_normalized_3ds = @options.merge(
+ three_d_secure: {
+ version: version,
+ eci: eci,
+ cavv: cavv,
+ ds_transaction_id: ds_transaction_id
+ }
+ )
+
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, options_with_normalized_3ds)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/i8=#{eci}%3A#{cavv}%3Anone/, data)
+ assert_match(/3ds_version=2.0/, data)
+ assert_match(/3ds_dstrxid=#{ds_transaction_id}/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_adds_default_cavv_when_omitted_from_normalized_hash
+ version = '2.2.0'
+ eci = '05'
+ ds_transaction_id = '97267598-FAE6-48F2-8083-C23433990FBC'
+ options_with_normalized_3ds = @options.merge(
+ three_d_secure: {
+ version: version,
+ eci: eci,
+ ds_transaction_id: ds_transaction_id
+ }
+ )
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, options_with_normalized_3ds)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/i8=#{eci}%3Anone%3Anone/, data)
+ assert_match(/3ds_version=2.0/, data)
+ assert_match(/3ds_dstrxid=#{ds_transaction_id}/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_purchase_adds_a9_field
+ options_with_3ds = @options.merge({ transaction_type: '8' })
stub_comms do
@gateway.purchase(@amount, @credit_card, options_with_3ds)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/a9=8/, data)
end.respond_with(successful_purchase_response)
end
- def test_adds_submerchant_id
+ def test_authorize_adds_a9_field
+ options_with_3ds = @options.merge({ transaction_type: '8' })
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, options_with_3ds)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=8/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_credit_adds_a9_field
+ options_with_3ds = @options.merge({ transaction_type: '8' })
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, options_with_3ds)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=8/, data)
+ end.respond_with(successful_credit_response)
+ end
+
+ def test_authorize_adds_authorization_details
+ options_with_auth_details = @options.merge({ authorization_type: '2', multiple_capture_count: '5' })
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, options_with_auth_details)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a10=2/, data)
+ assert_match(/a11=5/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_purchase_adds_submerchant_id
@options[:submerchant_id] = '12345'
stub_comms do
@gateway.purchase(@amount, @credit_card, @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/h3=12345/, data)
end.respond_with(successful_purchase_response)
end
- def test_supports_billing_descriptor
+ def test_adds_moto_a2_field
+ @options[:metadata] = { manual_entry: true }
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a2=3/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_authorize_adds_submerchant_id
+ @options[:submerchant_id] = '12345'
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/h3=12345/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_capture_adds_submerchant_id
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card)
+ end.respond_with(successful_authorize_response)
+
+ @options[:submerchant_id] = '12345'
+ stub_comms do
+ @gateway.capture(@amount, response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/h3=12345/, data)
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_void_adds_submerchant_id
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card)
+ end.respond_with(successful_authorize_response)
+
+ @options[:submerchant_id] = '12345'
+ stub_comms do
+ @gateway.void(response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/h3=12345/, data)
+ end.respond_with(successful_void_response)
+ end
+
+ def test_refund_adds_submerchant_id
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card)
+ end.respond_with(successful_purchase_response)
+
+ @options[:submerchant_id] = '12345'
+ stub_comms do
+ @gateway.refund(@amount, response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/h3=12345/, data)
+ end.respond_with(successful_refund_response)
+ end
+
+ def test_credit_adds_submerchant_id
+ @options[:submerchant_id] = '12345'
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/h3=12345/, data)
+ end.respond_with(successful_credit_response)
+ end
+
+ def test_purchase_adds_billing_descriptor
@options[:billing_descriptor] = 'abcdefghijkl'
stub_comms do
@gateway.purchase(@amount, @credit_card, @options)
- end.check_request do |endpoint, data, headers|
+ end.check_request do |_endpoint, data, _headers|
assert_match(/i2=abcdefghijkl/, data)
end.respond_with(successful_purchase_response)
end
+ def test_authorize_adds_billing_descriptor
+ @options[:billing_descriptor] = 'abcdefghijkl'
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/i2=abcdefghijkl/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_capture_adds_billing_descriptor
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card)
+ end.respond_with(successful_authorize_response)
+
+ @options[:billing_descriptor] = 'abcdefghijkl'
+ stub_comms do
+ @gateway.capture(@amount, response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/i2=abcdefghijkl/, data)
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_refund_adds_billing_descriptor
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card)
+ end.respond_with(successful_purchase_response)
+
+ @options[:billing_descriptor] = 'abcdefghijkl'
+ stub_comms do
+ @gateway.refund(@amount, response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/i2=abcdefghijkl/, data)
+ end.respond_with(successful_refund_response)
+ end
+
+ def test_credit_adds_billing_descriptor
+ @options[:billing_descriptor] = 'abcdefghijkl'
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/i2=abcdefghijkl/, data)
+ end.respond_with(successful_credit_response)
+ end
+
+ def test_purchase_adds_processor_fields
+ @options[:processor] = 'TEST'
+ @options[:processor_merchant_id] = '123'
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/r1=TEST/, data)
+ assert_match(/r2=123/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_authorize_adds_processor_fields
+ @options[:processor] = 'TEST'
+ @options[:processor_merchant_id] = '123'
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/r1=TEST/, data)
+ assert_match(/r2=123/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_capture_adds_processor_fields
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card)
+ end.respond_with(successful_authorize_response)
+
+ @options[:processor] = 'TEST'
+ @options[:processor_merchant_id] = '123'
+ stub_comms do
+ @gateway.capture(@amount, response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/r1=TEST/, data)
+ assert_match(/r2=123/, data)
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_void_adds_processor_fields
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card)
+ end.respond_with(successful_authorize_response)
+
+ @options[:processor] = 'TEST'
+ @options[:processor_merchant_id] = '123'
+ stub_comms do
+ @gateway.void(response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/r1=TEST/, data)
+ assert_match(/r2=123/, data)
+ end.respond_with(successful_void_response)
+ end
+
+ def test_refund_adds_processor_fields
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card)
+ end.respond_with(successful_purchase_response)
+
+ @options[:processor] = 'TEST'
+ @options[:processor_merchant_id] = '123'
+ stub_comms do
+ @gateway.refund(@amount, response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/r1=TEST/, data)
+ assert_match(/r2=123/, data)
+ end.respond_with(successful_refund_response)
+ end
+
+ def test_credit_adds_processor_fields
+ @options[:processor] = 'TEST'
+ @options[:processor_merchant_id] = '123'
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/r1=TEST/, data)
+ assert_match(/r2=123/, data)
+ end.respond_with(successful_credit_response)
+ end
+
+ def test_purchase_adds_echo_field
+ @options[:echo] = 'Echo Parameter'
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/d2=Echo\+Parameter/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_authorize_adds_echo_field
+ @options[:echo] = 'Echo Parameter'
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/d2=Echo\+Parameter/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_capture_adds_echo_field
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card)
+ end.respond_with(successful_authorize_response)
+
+ @options[:echo] = 'Echo Parameter'
+ stub_comms do
+ @gateway.capture(@amount, response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/d2=Echo\+Parameter/, data)
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_void_adds_echo_field
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card)
+ end.respond_with(successful_authorize_response)
+
+ @options[:echo] = 'Echo Parameter'
+ stub_comms do
+ @gateway.void(response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/d2=Echo\+Parameter/, data)
+ end.respond_with(successful_void_response)
+ end
+
+ def test_refund_adds_echo_field
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card)
+ end.respond_with(successful_purchase_response)
+
+ @options[:echo] = 'Echo Parameter'
+ stub_comms do
+ @gateway.refund(@amount, response.authorization, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/d2=Echo\+Parameter/, data)
+ end.respond_with(successful_refund_response)
+ end
+
+ def test_credit_adds_echo_field
+ @options[:echo] = 'Echo Parameter'
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/d2=Echo\+Parameter/, data)
+ end.respond_with(successful_credit_response)
+ end
+
+ def test_purchase_omits_phone_when_nil
+ # purchase passes the phone number when provided
+ @options[:billing_address][:phone] = '555-444-3333'
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/c2=555-444-3333/, data)
+ end.respond_with(successful_purchase_response)
+
+ # purchase doesn't pass the phone number when nil
+ @options[:billing_address][:phone] = nil
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_not_match(/c2=/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_purchase_omits_3ds_homephonecountry_when_phone_is_nil
+ # purchase passes 3ds_homephonecountry when it and phone number are provided
+ @options[:billing_address][:phone] = '555-444-3333'
+ @options[:three_ds_2] = { optional: { '3ds_homephonecountry': 'US' } }
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/c2=555-444-3333/, data)
+ assert_match(/3ds_homephonecountry=US/, data)
+ end.respond_with(successful_purchase_response)
+
+ # purchase doesn't pass 3ds_homephonecountry when phone number is nil
+ @options[:billing_address][:phone] = nil
+ @options[:three_ds_2] = { optional: { '3ds_homephonecountry': 'US' } }
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_not_match(/c2=/, data)
+ assert_not_match(/3ds_homephonecountry=/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_stored_credential_recurring_cit_initial
+ options = stored_credential_options(:cardholder, :recurring, :initial)
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=9/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_recurring_cit_used
+ options = stored_credential_options(:cardholder, :recurring, id: 'abc123')
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=9/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_recurring_mit_initial
+ options = stored_credential_options(:merchant, :recurring, :initial)
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=1/, data)
+ end.respond_with(successful_authorize_response)
+ assert_match(/z50=abc123/, successful_authorize_response)
+ assert_success response
+ end
+
+ def test_stored_credential_recurring_mit_used
+ options = stored_credential_options(:merchant, :recurring, id: 'abc123')
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=2/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_installment_cit_initial
+ options = stored_credential_options(:cardholder, :installment, :initial)
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=9/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_installment_cit_used
+ options = stored_credential_options(:cardholder, :installment, id: 'abc123')
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=9/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_installment_mit_initial
+ options = stored_credential_options(:merchant, :installment, :initial)
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=8/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_installment_mit_used
+ options = stored_credential_options(:merchant, :installment, id: 'abc123')
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=8/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_unscheduled_cit_initial
+ options = stored_credential_options(:cardholder, :unscheduled, :initial)
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=9/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_unscheduled_cit_used
+ options = stored_credential_options(:cardholder, :unscheduled, id: 'abc123')
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=9/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_unscheduled_mit_initial
+ options = stored_credential_options(:merchant, :unscheduled, :initial)
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=8/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_unscheduled_mit_used
+ options = stored_credential_options(:merchant, :unscheduled, id: 'abc123')
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=8/, data)
+ assert_match(/g6=abc123/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_purchase_with_stored_credential
+ options = stored_credential_options(:merchant, :recurring, id: 'abc123')
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=2/, data)
+ assert_match(/g6=abc123/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_add_transaction_type_overrides_stored_credential_option
+ options = stored_credential_options(:merchant, :unscheduled, id: 'abc123').merge(transaction_type: '6')
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a9=6/, data)
+ end.respond_with(successful_authorize_response)
+
+ assert_success response
+ end
+
+ def test_nonfractional_currency_handling
+ stub_comms do
+ @gateway.authorize(200, @credit_card, @options.merge(currency: 'ISK'))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/a4=2&a1=/, data)
+ end.respond_with(successful_authorize_response)
+ end
+
+ def test_3ds_2_optional_fields_adds_fields_to_the_root_of_the_post
+ post = {}
+ options = { three_ds_2: { optional: { '3ds_optional_field_1': :a, '3ds_optional_field_2': :b } } }
+
+ @gateway.add_3ds_2_optional_fields(post, options)
+
+ assert_equal post, { '3ds_optional_field_1': :a, '3ds_optional_field_2': :b }
+ end
+
+ def test_3ds_2_optional_fields_does_not_overwrite_fields
+ post = { '3ds_optional_field_1': :existing_value }
+ options = { three_ds_2: { optional: { '3ds_optional_field_1': :a, '3ds_optional_field_2': :b } } }
+
+ @gateway.add_3ds_2_optional_fields(post, options)
+
+ assert_equal post, { '3ds_optional_field_1': :existing_value, '3ds_optional_field_2': :b }
+ end
+
+ def test_3ds_2_optional_fields_does_not_empty_fields
+ post = {}
+ options = { three_ds_2: { optional: { '3ds_optional_field_1': '', '3ds_optional_field_2': 'null', '3ds_optional_field_3': nil } } }
+
+ @gateway.add_3ds_2_optional_fields(post, options)
+
+ assert_equal post, {}
+ end
+
+ def test_successful_purchase_with_network_token
+ response = stub_comms do
+ @gateway.purchase(@amount, @nt_credit_card)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/b21=vts_mdes_token&token_eci=07&token_crypto=AgAAAAAAosVKVV7FplLgQRYAAAA%3D/, data)
+ end.respond_with(successful_purchase_response)
+ assert_success response
+ end
+
+ def test_successful_purchase_with_other_than_network_token
+ response = stub_comms do
+ @gateway.purchase(@amount, @apple_pay_card)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/b21=applepay/, data)
+ assert_match(/token_eci=07/, data)
+ assert_not_match(/token_crypto=/, data)
+ end.respond_with(successful_purchase_response)
+ assert_success response
+ end
+
private
+ def stored_credential_options(*args, id: nil)
+ {
+ order_id: '#1001',
+ description: 'AM test',
+ currency: 'GBP',
+ customer: '123',
+ stored_credential: stored_credential(*args, id: id)
+ }
+ end
+
def successful_purchase_response
'M=SPREE978&O=1&T=03%2F09%2F2016+03%3A05%3A16&V=413&a1=02617cf5f02ccaed239b6521748298c5&a2=2&a4=100&a9=6&z1=8a82944a5351570601535955efeb513c&z13=606944188282&z14=U&z15=100&z2=0&z3=Transaction+has+been+executed+successfully.&z4=006596&z5=0&z6=00&z9=X&K=057e123af2fba5a37b4df76a7cb5cfb6'
end
@@ -243,7 +1112,7 @@ def failed_purchase_response
end
def successful_authorize_response
- 'M=SPREE978&O=2&T=03%2F09%2F2016+03%3A08%3A58&V=413&a1=90f7449d555f7bed0a2c5d780475f0bf&a2=2&a4=100&a9=6&z1=8a829449535154bc0153595952a2517a&z13=606944188284&z14=U&z15=100&z2=0&z3=Transaction+has+been+executed+successfully.&z4=006597&z5=0&z6=00&z9=X&K=00effd2c80ab7ecd45b499c0bbea3d20'
+ 'M=SPREE978&O=2&T=03%2F09%2F2016+03%3A08%3A58&V=413&a1=90f7449d555f7bed0a2c5d780475f0bf&a2=2&a4=100&a9=6&z1=8a829449535154bc0153595952a2517a&z13=606944188284&z14=U&z15=100&z2=0&z3=Transaction+has+been+executed+successfully.&z4=006597&z5=0&z6=00&z9=X&K=00effd2c80ab7ecd45b499c0bbea3d20z50=abc123'
end
def failed_authorize_response
@@ -274,12 +1143,20 @@ def failed_refund_response
'M=SPREE978&O=5&T=03%2F09%2F2016+03%3A16%3A06&V=413&a1=c2b481deffe0e27bdef1439655260092&a2=2&a4=-&a5=EUR&b1=-&z1=1A-1&z2=-9&z3=2.+At+least+one+of+input+parameters+is+malformed.%3A+Parameter+%5Bg4%5D+cannot+be+empty.&K=c2f6112b40c61859d03684ac8e422766'
end
+ def successful_referral_cft_response
+ 'M=SPREE978&O=34&T=11%2F15%2F2019+15%3A56%3A08&V=413&a1=e852c517da0ffb0cde45671b39165449&a2=2&a4=100&a9=9&b2=2&g2=XZZ72c3228fc3b58525STV56T7YMFAJB&z1=XZZ72e64209459e8C2BAMTBS65MCNGIF&z13=931924132623&z2=0&z3=Transaction+has+been+executed+successfully.&z33=CREDORAX&z34=59990010&z39=XZZ72e64209459e8C2BAMTBS65MCNGIF&z4=HOSTOK&z6=00&K=76f8a35c3357a7613d63438bd86c06d9'
+ end
+
+ def failed_referral_cft_response
+ 'T=11%2F15%2F2019+17%3A17%3A45&a1=896ffaf13766fff647d863e8ab0a707c&z1=XZZ7246087744e7993DRONGBWN4RNFWJ&z2=-9&z3=Referred+to+transaction+has+not+been+found.'
+ end
+
def successful_credit_response
- 'M=SPREE978&O=6&T=03%2F09%2F2016+03%3A16%3A35&V=413&a1=868f8b942fae639d28e27e8933d575d4&a2=2&a4=100&z1=8a82944a53515706015359604c135301&z13=606944188289&z15=100&z2=0&z3=Transaction+has+been+executed+successfully.&z5=0&z6=00&K=51ba24f6ef3aa161f86e53c34c9616ac'
+ 'M=SPREE978&O=35&T=03%2F09%2F2016+03%3A16%3A35&V=413&a1=868f8b942fae639d28e27e8933d575d4&a2=2&a4=100&z1=8a82944a53515706015359604c135301&z13=606944188289&z15=100&z2=0&z3=Transaction+has+been+executed+successfully.&z5=0&z6=00&K=51ba24f6ef3aa161f86e53c34c9616ac'
end
def failed_credit_response
- 'M=SPREE978&O=6&T=03%2F09%2F2016+03%3A16%3A59&V=413&a1=ff28246cfc811b1c686a52d08d075d9c&a2=2&a4=100&z1=8a829449535154bc01535960a962524f&z13=606944188290&z15=100&z2=05&z3=Transaction+has+been+declined.&z5=0&z6=57&K=cf34816d5c25dc007ef3525505c4c610'
+ 'M=SPREE978&O=35&T=03%2F09%2F2016+03%3A16%3A59&V=413&a1=ff28246cfc811b1c686a52d08d075d9c&a2=2&a4=100&z1=8a829449535154bc01535960a962524f&z13=606944188290&z15=100&z2=05&z3=Transaction+has+been+declined.&z5=0&z6=57&K=cf34816d5c25dc007ef3525505c4c610'
end
def empty_purchase_response
diff --git a/test/unit/gateways/cyber_source_rest_test.rb b/test/unit/gateways/cyber_source_rest_test.rb
new file mode 100644
index 00000000000..f6ba1b40eba
--- /dev/null
+++ b/test/unit/gateways/cyber_source_rest_test.rb
@@ -0,0 +1,585 @@
+require 'test_helper'
+
+class CyberSourceRestTest < Test::Unit::TestCase
+ include CommStub
+
+ def setup
+ @gateway = CyberSourceRestGateway.new(
+ merchant_id: 'abc123',
+ public_key: 'def345',
+ private_key: "NYlM1sgultLjvgaraWvDCXykdz1buqOW8yXE3pMlmxQ=\n"
+ )
+ @bank_account = check(account_number: '4100', routing_number: '121042882')
+ @credit_card = credit_card(
+ '4111111111111111',
+ verification_value: '987',
+ month: 12,
+ year: 2031
+ )
+ @apple_pay = network_tokenization_credit_card(
+ '4111111111111111',
+ payment_cryptogram: 'AceY+igABPs3jdwNaDg3MAACAAA=',
+ month: '11',
+ year: Time.now.year + 1,
+ source: :apple_pay,
+ verification_value: 569
+ )
+
+ @google_pay_mc = network_tokenization_credit_card(
+ '5555555555554444',
+ payment_cryptogram: 'AceY+igABPs3jdwNaDg3MAACAAA=',
+ month: '11',
+ year: Time.now.year + 1,
+ source: :google_pay,
+ verification_value: 569,
+ brand: 'master'
+ )
+
+ @apple_pay_jcb = network_tokenization_credit_card(
+ '3566111111111113',
+ payment_cryptogram: 'AceY+igABPs3jdwNaDg3MAACAAA=',
+ month: '11',
+ year: Time.now.year + 1,
+ source: :apple_pay,
+ verification_value: 569,
+ brand: 'jcb'
+ )
+ @amount = 100
+ @options = {
+ order_id: '1',
+ description: 'Store Purchase',
+ billing_address: {
+ name: 'John Doe',
+ address1: '1 Market St',
+ city: 'san francisco',
+ state: 'CA',
+ zip: '94105',
+ country: 'US',
+ phone: '4158880000'
+ },
+ email: 'test@cybs.com'
+ }
+ @gmt_time = Time.now.httpdate
+ @digest = 'SHA-256=gXWufV4Zc7VkN9Wkv9jh/JuAVclqDusx3vkyo3uJFWU='
+ @resource = '/pts/v2/payments/'
+ end
+
+ def test_required_merchant_id_and_secret
+ error = assert_raises(ArgumentError) { CyberSourceRestGateway.new }
+ assert_equal 'Missing required parameter: merchant_id', error.message
+ end
+
+ def test_supported_card_types
+ assert_equal CyberSourceRestGateway.supported_cardtypes, %i[visa master american_express discover diners_club jcb maestro elo union_pay cartes_bancaires mada]
+ end
+
+ def test_properly_format_on_zero_decilmal
+ stub_comms do
+ @gateway.authorize(1000, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ card = request['paymentInformation']['card']
+ amount_details = request['orderInformation']['amountDetails']
+
+ assert_equal '1', request['clientReferenceInformation']['code']
+ assert_equal '2031', card['expirationYear']
+ assert_equal '12', card['expirationMonth']
+ assert_equal '987', card['securityCode']
+ assert_equal '001', card['type']
+ assert_equal 'USD', amount_details['currency']
+ assert_equal '10.00', amount_details['totalAmount']
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_should_create_an_http_signature_for_a_post
+ signature = @gateway.send :get_http_signature, @resource, @digest, 'post', @gmt_time
+
+ parsed = parse_signature(signature)
+
+ assert_equal 'def345', parsed['keyid']
+ assert_equal 'HmacSHA256', parsed['algorithm']
+ assert_equal 'host date (request-target) digest v-c-merchant-id', parsed['headers']
+ assert_equal %w[algorithm headers keyid signature], signature.split(', ').map { |v| v.split('=').first }.sort
+ end
+
+ def test_should_create_an_http_signature_for_a_get
+ signature = @gateway.send :get_http_signature, @resource, nil, 'get', @gmt_time
+
+ parsed = parse_signature(signature)
+ assert_equal 'host date (request-target) v-c-merchant-id', parsed['headers']
+ end
+
+ def test_scrub
+ assert @gateway.supports_scrubbing?
+ assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed
+ end
+
+ def test_including_customer_if_customer_id_present
+ post = { paymentInformation: {} }
+
+ @gateway.send :add_customer_id, post, {}
+ assert_nil post[:paymentInformation][:customer]
+
+ @gateway.send :add_customer_id, post, { customer_id: 10 }
+ assert_equal 10, post[:paymentInformation][:customer][:customerId]
+ end
+
+ def test_add_ammount_and_currency
+ post = { orderInformation: {} }
+
+ @gateway.send :add_amount, post, 10221, {}
+
+ assert_equal '102.21', post.dig(:orderInformation, :amountDetails, :totalAmount)
+ assert_equal 'USD', post.dig(:orderInformation, :amountDetails, :currency)
+ end
+
+ def test_add_credit_card_data
+ post = { paymentInformation: {} }
+ @gateway.send :add_credit_card, post, @credit_card
+
+ card = post[:paymentInformation][:card]
+ assert_equal @credit_card.number, card[:number]
+ assert_equal '2031', card[:expirationYear]
+ assert_equal '12', card[:expirationMonth]
+ assert_equal '987', card[:securityCode]
+ assert_equal '001', card[:type]
+ end
+
+ def test_add_ach
+ post = { paymentInformation: {} }
+ @gateway.send :add_ach, post, @bank_account
+
+ bank = post[:paymentInformation][:bank]
+ assert_equal @bank_account.account_number, bank[:account][:number]
+ assert_equal @bank_account.routing_number, bank[:routingNumber]
+ end
+
+ def test_add_billing_address
+ post = { orderInformation: {} }
+
+ @gateway.send :add_address, post, @credit_card, @options[:billing_address], @options, :billTo
+
+ address = post[:orderInformation][:billTo]
+
+ assert_equal 'John', address[:firstName]
+ assert_equal 'Doe', address[:lastName]
+ assert_equal '1 Market St', address[:address1]
+ assert_equal 'san francisco', address[:locality]
+ assert_equal 'US', address[:country]
+ assert_equal 'test@cybs.com', address[:email]
+ assert_equal '4158880000', address[:phoneNumber]
+ end
+
+ def test_add_shipping_address
+ post = { orderInformation: {} }
+ @options[:shipping_address] = @options.delete(:billing_address)
+
+ @gateway.send :add_address, post, @credit_card, @options[:shipping_address], @options, :shipTo
+
+ address = post[:orderInformation][:shipTo]
+
+ assert_equal 'John', address[:firstName]
+ assert_equal 'Doe', address[:lastName]
+ assert_equal '1 Market St', address[:address1]
+ assert_equal 'san francisco', address[:locality]
+ assert_equal 'US', address[:country]
+ assert_equal 'test@cybs.com', address[:email]
+ assert_equal '4158880000', address[:phoneNumber]
+ end
+
+ def test_authorize_apple_pay_visa
+ stub_comms do
+ @gateway.authorize(100, @apple_pay, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal '001', request['paymentInformation']['tokenizedCard']['type']
+ assert_equal '1', request['paymentInformation']['tokenizedCard']['transactionType']
+ assert_equal 'AceY+igABPs3jdwNaDg3MAACAAA=', request['paymentInformation']['tokenizedCard']['cryptogram']
+ assert_nil request['paymentInformation']['tokenizedCard']['requestorId']
+ assert_equal '001', request['processingInformation']['paymentSolution']
+ assert_equal 'internet', request['processingInformation']['commerceIndicator']
+ assert_include request['consumerAuthenticationInformation'], 'cavv'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_authorize_google_pay_master_card
+ stub_comms do
+ @gateway.authorize(100, @google_pay_mc, @options.merge(merchant_id: 'MerchantId'))
+ end.check_request do |_endpoint, data, headers|
+ request = JSON.parse(data)
+ assert_equal 'MerchantId', headers['V-C-Merchant-Id']
+ assert_equal '002', request['paymentInformation']['tokenizedCard']['type']
+ assert_equal '1', request['paymentInformation']['tokenizedCard']['transactionType']
+ assert_nil request['paymentInformation']['tokenizedCard']['requestorId']
+ assert_equal '012', request['processingInformation']['paymentSolution']
+ assert_equal 'internet', request['processingInformation']['commerceIndicator']
+ assert_equal request['consumerAuthenticationInformation']['ucafCollectionIndicator'], '2'
+ assert_include request['consumerAuthenticationInformation'], 'ucafAuthenticationData'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_authorize_apple_pay_jcb
+ stub_comms do
+ @gateway.authorize(100, @apple_pay_jcb, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal '007', request['paymentInformation']['tokenizedCard']['type']
+ assert_equal '1', request['paymentInformation']['tokenizedCard']['transactionType']
+ assert_nil request['paymentInformation']['tokenizedCard']['requestorId']
+ assert_equal '001', request['processingInformation']['paymentSolution']
+ assert_nil request['processingInformation']['commerceIndicator']
+ assert_include request['consumerAuthenticationInformation'], 'cavv'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_url_building
+ assert_equal "#{@gateway.class.test_url}/pts/v2/action", @gateway.send(:url, 'action')
+ end
+
+ def test_stored_credential_cit_initial
+ @options[:stored_credential] = stored_credential(:cardholder, :internet, :initial)
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal 'internet', request['processingInformation']['commerceIndicator']
+ assert_equal 'customer', request.dig('processingInformation', 'authorizationOptions', 'initiator', 'type')
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_recurring_cit
+ @options[:stored_credential] = stored_credential(:cardholder, :recurring)
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal 'recurring', request['processingInformation']['commerceIndicator']
+ assert_equal 'customer', request.dig('processingInformation', 'authorizationOptions', 'initiator', 'type')
+ assert_equal true, request.dig('processingInformation', 'authorizationOptions', 'initiator', 'merchantInitiatedTransaction', 'storedCredentialUsed')
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ def test_stored_credential_recurring_mit_ntid
+ @options[:stored_credential] = stored_credential(:merchant, :recurring, ntid: '123456789619999')
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ request = JSON.parse(data)
+ assert_equal 'recurring', request['processingInformation']['commerceIndicator']
+ assert_equal 'merchant', request.dig('processingInformation', 'authorizationOptions', 'initiator', 'type')
+ assert_equal true, request.dig('processingInformation', 'authorizationOptions', 'initiator', 'merchantInitiatedTransaction', 'storedCredentialUsed')
+ end.respond_with(successful_purchase_response)
+
+ assert_success response
+ end
+
+ def test_successful_credit_card_purchase_single_request_ignore_avs
+ stub_comms do
+ options = @options.merge(ignore_avs: true)
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_endpoint, request_body, _headers|
+ json_body = JSON.parse(request_body)
+ assert_equal json_body['processingInformation']['authorizationOptions']['ignoreAvsResult'], 'true'
+ assert_nil json_body['processingInformation']['authorizationOptions']['ignoreCvResult']
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_successful_credit_card_purchase_single_request_without_ignore_avs
+ stub_comms do
+ # globally ignored AVS for gateway instance:
+ options = @options.merge(ignore_avs: false)
+ @gateway.options[:ignore_avs] = true
+ @gateway.purchase(@amount, @credit_card, options)
+ end.check_request do |_endpoint, request_body, _headers|
+ json_body = JSON.parse(request_body)
+ assert_nil json_body['processingInformation']['authorizationOptions']['ignoreAvsResult']
+ assert_nil json_body['processingInformation']['authorizationOptions']['ignoreCvResult']
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_successful_credit_card_purchase_single_request_ignore_ccv
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options.merge(ignore_cvv: true))
+ end.check_request do |_endpoint, request_body, _headers|
+ json_body = JSON.parse(request_body)
+ assert_nil json_body['processingInformation']['authorizationOptions']['ignoreAvsResult']
+ assert_equal json_body['processingInformation']['authorizationOptions']['ignoreCvResult'], 'true'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_successful_credit_card_purchase_single_request_without_ignore_ccv
+ stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options.merge(ignore_cvv: false))
+ end.check_request do |_endpoint, request_body, _headers|
+ json_body = JSON.parse(request_body)
+ assert_nil json_body['processingInformation']['authorizationOptions']['ignoreAvsResult']
+ assert_nil json_body['processingInformation']['authorizationOptions']['ignoreCvResult']
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_authorize_includes_mdd_fields
+ stub_comms do
+ @gateway.authorize(100, @credit_card, order_id: '1', mdd_field_2: 'CustomValue2', mdd_field_3: 'CustomValue3')
+ end.check_request do |_endpoint, data, _headers|
+ json_data = JSON.parse(data)
+ assert_equal json_data['merchantDefinedInformation'][0]['key'], 'mdd_field_2'
+ assert_equal json_data['merchantDefinedInformation'][0]['value'], 'CustomValue2'
+ assert_equal json_data['merchantDefinedInformation'].count, 2
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_capture_includes_mdd_fields
+ stub_comms do
+ @gateway.capture(100, '1846925324700976124593', order_id: '1', mdd_field_2: 'CustomValue2', mdd_field_3: 'CustomValue3')
+ end.check_request do |_endpoint, data, _headers|
+ json_data = JSON.parse(data)
+ assert_equal json_data['merchantDefinedInformation'][0]['key'], 'mdd_field_2'
+ assert_equal json_data['merchantDefinedInformation'][0]['value'], 'CustomValue2'
+ assert_equal json_data['merchantDefinedInformation'].count, 2
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_credit_includes_mdd_fields
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, mdd_field_2: 'CustomValue2', mdd_field_3: 'CustomValue3')
+ end.check_request do |_endpoint, data, _headers|
+ json_data = JSON.parse(data)
+ assert_equal json_data['merchantDefinedInformation'][0]['key'], 'mdd_field_2'
+ assert_equal json_data['merchantDefinedInformation'][0]['value'], 'CustomValue2'
+ assert_equal json_data['merchantDefinedInformation'].count, 2
+ 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')
+ end.check_request do |_endpoint, data, _headers|
+ json_data = JSON.parse(data)
+ assert_equal json_data['clientReferenceInformation']['reconciliationId'], '181537'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_bank_account_purchase_includes_sec_code
+ stub_comms do
+ @gateway.purchase(@amount, @bank_account, order_id: '1', sec_code: 'WEB')
+ end.check_request do |_endpoint, data, _headers|
+ json_data = JSON.parse(data)
+ assert_equal json_data['processingInformation']['bankTransferOptions']['secCode'], 'WEB'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_purchase_includes_invoice_number
+ stub_comms do
+ @gateway.purchase(100, @credit_card, invoice_number: '1234567')
+ end.check_request do |_endpoint, data, _headers|
+ json_data = JSON.parse(data)
+ assert_equal json_data['orderInformation']['invoiceDetails']['invoiceNumber'], '1234567'
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_adds_application_id_as_partner_solution_id
+ partner_id = 'partner_id'
+ CyberSourceRestGateway.application_id = partner_id
+
+ stub_comms do
+ @gateway.authorize(100, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ json_data = JSON.parse(data)
+ assert_equal json_data['clientReferenceInformation']['partner']['solutionId'], partner_id
+ end.respond_with(successful_purchase_response)
+ ensure
+ CyberSourceRestGateway.application_id = nil
+ end
+
+ private
+
+ def parse_signature(signature)
+ signature.gsub(/=\"$/, '').delete('"').split(', ').map { |x| x.split('=') }.to_h
+ end
+
+ def pre_scrubbed
+ <<-PRE
+ <- "POST /pts/v2/payments/ HTTP/1.1\r\nContent-Type: application/json;charset=utf-8\r\nAccept: application/hal+json;charset=utf-8\r\nV-C-Merchant-Id: testrest\r\nDate: Sun, 29 Jan 2023 17:13:30 GMT\r\nHost: apitest.cybersource.com\r\nSignature: keyid=\"08c94330-f618-42a3-b09d-e1e43be5efda\", algorithm=\"HmacSHA256\", headers=\"host date (request-target) digest v-c-merchant-id\", signature=\"DJHeHWceVrsJydd8BCbGowr9dzQ/ry5cGN1FocLakEw=\"\r\nDigest: SHA-256=wuV1cxGzs6KpuUKJmlD7pKV6MZ/5G1wQVoYbf8cRChM=\r\nConnection: close\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nUser-Agent: Ruby\r\nContent-Length: 584\r\n\r\n"
+ <- "{\"clientReferenceInformation\":{\"code\":\"b8779865d140125036016a0f85db907f\"},\"paymentInformation\":{\"card\":{\"number\":\"4111111111111111\",\"expirationMonth\":\"12\",\"expirationYear\":\"2031\",\"securityCode\":\"987\",\"type\":\"001\"}},\"orderInformation\":{\"amountDetails\":{\"totalAmount\":\"102.21\",\"currency\":\"USD\"},\"billTo\":{\"firstName\":\"John\",\"lastName\":\"Doe\",\"address1\":\"1 Market St\",\"locality\":\"san francisco\",\"administrativeArea\":\"CA\",\"postalCode\":\"94105\",\"country\":\"US\",\"email\":\"test@cybs.com\",\"phoneNumber\":\"4158880000\"},\"shipTo\":{\"firstName\":\"Longbob\",\"lastName\":\"Longsen\",\"email\":\"test@cybs.com\"}}}"
+ -> "HTTP/1.1 201 Created\r\n"
+ -> "Cache-Control: no-cache, no-store, must-revalidate\r\n"
+ -> "Pragma: no-cache\r\n"
+ -> "Expires: -1\r\n"
+ -> "Strict-Transport-Security: max-age=31536000\r\n"
+ -> "Content-Type: application/hal+json\r\n"
+ -> "Content-Length: 905\r\n"
+ -> "x-response-time: 291ms\r\n"
+ -> "X-OPNET-Transaction-Trace: 0b1f2bd7-9545-4939-9478-4b76cf7199b6\r\n"
+ -> "Connection: close\r\n"
+ -> "v-c-correlation-id: 42969bf5-a77d-4035-9d09-58d4ca070e8c\r\n"
+ -> "\r\n"
+ reading 905 bytes...
+ -> "{\"_links\":{\"authReversal\":{\"method\":\"POST\",\"href\":\"/pts/v2/payments/6750124114786780104953/reversals\"},\"self\":{\"method\":\"GET\",\"href\":\"/pts/v2/payments/6750124114786780104953\"},\"capture\":{\"method\":\"POST\",\"href\":\"/pts/v2/payments/6750124114786780104953/captures\"}},\"clientReferenceInformation\":{\"code\":\"b8779865d140125036016a0f85db907f\"},\"id\":\"6750124114786780104953\",\"orderInformation\":{\"amountDetails\":{\"authorizedAmount\":\"102.21\",\"currency\":\"USD\"}},\"paymentAccountInformation\":{\"card\":{\"type\":\"001\"}},\"paymentInformation\":{\"tokenizedCard\":{\"type\":\"001\"},\"card\":{\"type\":\"001\"}},\"pointOfSaleInformation\":{\"terminalId\":\"111111\"},\"processorInformation\":{\"approvalCode\":\"888888\",\"networkTransactionId\":\"123456789619999\",\"transactionId\":\"123456789619999\",\"responseCode\":\"100\",\"avs\":{\"code\":\"X\",\"codeRaw\":\"I1\"}},\"reconciliationId\":\"78243988SD9YL291\",\"status\":\"AUTHORIZED\",\"submitTimeUtc\":\"2023-01-29T17:13:31Z\"}"
+ PRE
+ end
+
+ def post_scrubbed
+ <<-POST
+ <- "POST /pts/v2/payments/ HTTP/1.1\r\nContent-Type: application/json;charset=utf-8\r\nAccept: application/hal+json;charset=utf-8\r\nV-C-Merchant-Id: testrest\r\nDate: Sun, 29 Jan 2023 17:13:30 GMT\r\nHost: apitest.cybersource.com\r\nSignature: keyid=\"[FILTERED]\", algorithm=\"HmacSHA256\", headers=\"host date (request-target) digest v-c-merchant-id\", signature=\"[FILTERED]\"\r\nDigest: SHA-256=[FILTERED]\r\nConnection: close\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nUser-Agent: Ruby\r\nContent-Length: 584\r\n\r\n"
+ <- "{\"clientReferenceInformation\":{\"code\":\"b8779865d140125036016a0f85db907f\"},\"paymentInformation\":{\"card\":{\"number\":\"[FILTERED]\",\"expirationMonth\":\"12\",\"expirationYear\":\"2031\",\"securityCode\":\"[FILTERED]\",\"type\":\"001\"}},\"orderInformation\":{\"amountDetails\":{\"totalAmount\":\"102.21\",\"currency\":\"USD\"},\"billTo\":{\"firstName\":\"John\",\"lastName\":\"Doe\",\"address1\":\"1 Market St\",\"locality\":\"san francisco\",\"administrativeArea\":\"CA\",\"postalCode\":\"94105\",\"country\":\"US\",\"email\":\"test@cybs.com\",\"phoneNumber\":\"4158880000\"},\"shipTo\":{\"firstName\":\"Longbob\",\"lastName\":\"Longsen\",\"email\":\"test@cybs.com\"}}}"
+ -> "HTTP/1.1 201 Created\r\n"
+ -> "Cache-Control: no-cache, no-store, must-revalidate\r\n"
+ -> "Pragma: no-cache\r\n"
+ -> "Expires: -1\r\n"
+ -> "Strict-Transport-Security: max-age=31536000\r\n"
+ -> "Content-Type: application/hal+json\r\n"
+ -> "Content-Length: 905\r\n"
+ -> "x-response-time: 291ms\r\n"
+ -> "X-OPNET-Transaction-Trace: 0b1f2bd7-9545-4939-9478-4b76cf7199b6\r\n"
+ -> "Connection: close\r\n"
+ -> "v-c-correlation-id: 42969bf5-a77d-4035-9d09-58d4ca070e8c\r\n"
+ -> "\r\n"
+ reading 905 bytes...
+ -> "{\"_links\":{\"authReversal\":{\"method\":\"POST\",\"href\":\"/pts/v2/payments/6750124114786780104953/reversals\"},\"self\":{\"method\":\"GET\",\"href\":\"/pts/v2/payments/6750124114786780104953\"},\"capture\":{\"method\":\"POST\",\"href\":\"/pts/v2/payments/6750124114786780104953/captures\"}},\"clientReferenceInformation\":{\"code\":\"b8779865d140125036016a0f85db907f\"},\"id\":\"6750124114786780104953\",\"orderInformation\":{\"amountDetails\":{\"authorizedAmount\":\"102.21\",\"currency\":\"USD\"}},\"paymentAccountInformation\":{\"card\":{\"type\":\"001\"}},\"paymentInformation\":{\"tokenizedCard\":{\"type\":\"001\"},\"card\":{\"type\":\"001\"}},\"pointOfSaleInformation\":{\"terminalId\":\"111111\"},\"processorInformation\":{\"approvalCode\":\"888888\",\"networkTransactionId\":\"123456789619999\",\"transactionId\":\"123456789619999\",\"responseCode\":\"100\",\"avs\":{\"code\":\"X\",\"codeRaw\":\"I1\"}},\"reconciliationId\":\"78243988SD9YL291\",\"status\":\"AUTHORIZED\",\"submitTimeUtc\":\"2023-01-29T17:13:31Z\"}"
+ POST
+ end
+
+ def successful_purchase_response
+ <<-RESPONSE
+ {
+ "_links": {
+ "authReversal": {
+ "method": "POST",
+ "href": "/pts/v2/payments/6750124114786780104953/reversals"
+ },
+ "self": {
+ "method": "GET",
+ "href": "/pts/v2/payments/6750124114786780104953"
+ },
+ "capture": {
+ "method": "POST",
+ "href": "/pts/v2/payments/6750124114786780104953/captures"
+ }
+ },
+ "clientReferenceInformation": {
+ "code": "b8779865d140125036016a0f85db907f"
+ },
+ "id": "6750124114786780104953",
+ "orderInformation": {
+ "amountDetails": {
+ "authorizedAmount": "102.21",
+ "currency": "USD"
+ }
+ },
+ "paymentAccountInformation": {
+ "card": {
+ "type": "001"
+ }
+ },
+ "paymentInformation": {
+ "tokenizedCard": {
+ "type": "001"
+ },
+ "card": {
+ "type": "001"
+ }
+ },
+ "pointOfSaleInformation": {
+ "terminalId": "111111"
+ },
+ "processorInformation": {
+ "approvalCode": "888888",
+ "networkTransactiDDDonId": "123456789619999",
+ "transactionId": "123456789619999",
+ "responseCode": "100",
+ "avs": {
+ "code": "X",
+ "codeRaw": "I1"
+ }
+ },
+ "reconciliationId": "78243988SD9YL291",
+ "status": "AUTHORIZED",
+ "submitTimeUtc": "2023-01-29T17:13:31Z"
+ }
+ RESPONSE
+ end
+
+ def successful_capture_response
+ <<-RESPONSE
+ {
+ "_links": {
+ "void": {
+ "method": "POST",
+ "href": "/pts/v2/captures/6799471903876585704951/voids"
+ },
+ "self": {
+ "method": "GET",
+ "href": "/pts/v2/captures/6799471903876585704951"
+ }
+ },
+ "clientReferenceInformation": {
+ "code": "TC50171_3"
+ },
+ "id": "6799471903876585704951",
+ "orderInformation": {
+ "amountDetails": {
+ "totalAmount": "102.21",
+ "currency": "USD"
+ }
+ },
+ "reconciliationId": "78243988SD9YL291",
+ "status": "PENDING",
+ "submitTimeUtc": "2023-03-27T19:59:50Z"
+ }
+ RESPONSE
+ end
+
+ def successful_credit_response
+ <<-RESPONSE
+ {
+ "_links": {
+ "void": {
+ "method": "POST",
+ "href": "/pts/v2/credits/6799499091686234304951/voids"
+ },
+ "self": {
+ "method": "GET",
+ "href": "/pts/v2/credits/6799499091686234304951"
+ }
+ },
+ "clientReferenceInformation": {
+ "code": "12345678"
+ },
+ "creditAmountDetails": {
+ "currency": "usd",
+ "creditAmount": "200.00"
+ },
+ "id": "6799499091686234304951",
+ "orderInformation": {
+ "amountDetails": {
+ "currency": "usd"
+ }
+ },
+ "paymentAccountInformation": {
+ "card": {
+ "type": "001"
+ }
+ },
+ "paymentInformation": {
+ "tokenizedCard": {
+ "type": "001"
+ },
+ "card": {
+ "type": "001"
+ }
+ },
+ "processorInformation": {
+ "approvalCode": "888888",
+ "responseCode": "100"
+ },
+ "reconciliationId": "70391830ZFKZI570",
+ "status": "PENDING",
+ "submitTimeUtc": "2023-03-27T20:45:09Z"
+ }
+ RESPONSE
+ end
+end
diff --git a/test/unit/gateways/cyber_source_test.rb b/test/unit/gateways/cyber_source_test.rb
index 77602767222..0e67c44700c 100644
--- a/test/unit/gateways/cyber_source_test.rb
+++ b/test/unit/gateways/cyber_source_test.rb
@@ -8,49 +8,63 @@ def setup
Base.mode = :test
@gateway = CyberSourceGateway.new(
- :login => 'l',
- :password => 'p'
+ login: 'l',
+ password: 'p'
)
@amount = 100
@customer_ip = '127.0.0.1'
- @credit_card = credit_card('4111111111111111', :brand => 'visa')
- @declined_card = credit_card('801111111111111', :brand => 'visa')
+ @credit_card = credit_card('4111111111111111', brand: 'visa')
+ @master_credit_card = credit_card('4111111111111111', brand: 'master')
+ @elo_credit_card = credit_card('5067310000000010', brand: 'elo')
+ @declined_card = credit_card('801111111111111', brand: 'visa')
+ @network_token = network_tokenization_credit_card('4111111111111111',
+ brand: 'visa',
+ transaction_id: '123',
+ eci: '05',
+ payment_cryptogram: '111111111100cryptogram',
+ source: :network_token)
+ @apple_pay = network_tokenization_credit_card('4111111111111111',
+ brand: 'visa',
+ transaction_id: '123',
+ eci: '05',
+ payment_cryptogram: '111111111100cryptogram',
+ source: :apple_pay)
+ @google_pay = network_tokenization_credit_card('4242424242424242', source: :google_pay)
@check = check()
@options = {
- :ip => @customer_ip,
- :order_id => '1000',
- :line_items => [
+ ip: @customer_ip,
+ order_id: '1000',
+ line_items: [
{
- :declared_value => @amount,
- :quantity => 2,
- :code => 'default',
- :description => 'Giant Walrus',
- :sku => 'WA323232323232323'
- },
- {
- :declared_value => @amount,
- :quantity => 2,
- :description => 'Marble Snowcone',
- :sku => 'FAKE1232132113123'
+ declared_value: @amount,
+ quantity: 2,
+ code: 'default',
+ description: 'Giant Walrus',
+ sku: 'WA323232323232323',
+ tax_amount: '10',
+ national_tax: '5'
}
],
- :currency => 'USD'
+ currency: 'USD'
}
@subscription_options = {
- :order_id => generate_unique_id,
- :credit_card => @credit_card,
- :setup_fee => 100,
- :subscription => {
- :frequency => 'weekly',
- :start_date => Date.today.next_week,
- :occurrences => 4,
- :automatic_renew => true,
- :amount => 100
+ order_id: generate_unique_id,
+ credit_card: @credit_card,
+ setup_fee: 100,
+ subscription: {
+ frequency: 'weekly',
+ start_date: Date.today.next_week,
+ occurrences: 4,
+ automatic_renew: true,
+ amount: 100
}
}
+
+ @issuer_additional_data = 'PR25000000000011111111111112222222sk111111111111111111111111111'
+ + '1111111115555555222233101abcdefghijkl7777777777777777777777777promotionCde'
end
def test_successful_credit_card_purchase
@@ -59,7 +73,51 @@ def test_successful_credit_card_purchase
assert response = @gateway.purchase(@amount, @credit_card, @options)
assert_equal 'Successful transaction', response.message
assert_success response
- assert_equal "#{@options[:order_id]};#{response.params['requestID']};#{response.params['requestToken']};purchase;100;USD;", response.authorization
+ assert_equal "#{@options[:order_id]};#{response.params['requestID']};#{response.params['requestToken']};purchase;100;USD;;credit_card", response.authorization
+ assert response.test?
+ end
+
+ def test_successful_purchase_with_other_tax_fields
+ stub_comms do
+ @gateway.purchase(100, @credit_card, @options.merge!(national_tax_indicator: 1, vat_tax_rate: 1.01, merchant_id: 'MerchantId'))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/MerchantId<\/merchantID>/, data)
+ assert_match(/\s+1.01<\/vatTaxRate>\s+1<\/nationalTaxIndicator>\s+<\/otherTax>/m, 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))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/\s+USD<\/currency>\s+T<\/discountManagementIndicator>\s+7.89<\/taxAmount>\s+1.00<\/grandTotalAmount>\s+1.23<\/originalAmount>\s+1.23<\/invoiceAmount>\s+<\/purchaseTotals>/m, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_successful_authorize_with_national_tax_indicator
+ national_tax_indicator = 1
+ stub_comms do
+ @gateway.authorize(100, @credit_card, @options.merge(national_tax_indicator: national_tax_indicator))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/\s+#{national_tax_indicator}<\/nationalTaxIndicator>\s+<\/otherTax>/m, 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'))
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/T<\/mobileRemotePaymentType>/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_successful_credit_card_purchase_with_elo
+ @gateway.expects(:ssl_post).returns(successful_purchase_response)
+
+ assert response = @gateway.purchase(@amount, @elo_credit_card, @options)
+ assert_equal 'Successful transaction', response.message
+ assert_success response
+ assert_equal "#{@options[:order_id]};#{response.params['requestID']};#{response.params['requestToken']};purchase;100;USD;;credit_card", response.authorization
assert response.test?
end
@@ -72,19 +130,232 @@ def test_purchase_includes_customer_ip
@gateway.purchase(@amount, @credit_card, @options)
end
+ def test_purchase_includes_issuer_additional_data
+ stub_comms do
+ @gateway.purchase(100, @credit_card, order_id: '1', issuer_additional_data: @issuer_additional_data)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/\s+#{@issuer_additional_data}<\/additionalData>\s+<\/issuer>/m, data)
+ end.respond_with(successful_purchase_response)
+ end
+
def test_purchase_includes_mdd_fields
stub_comms do
@gateway.purchase(100, @credit_card, order_id: '1', mdd_field_2: 'CustomValue2', mdd_field_3: 'CustomValue3')
- end.check_request do |endpoint, data, headers|
- assert_match(/field2>CustomValue2.*field3>CustomValue3CustomValue2181537<\/reconciliationID>/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_merchant_description
+ stub_comms do
+ @gateway.authorize(100, @credit_card, merchant_descriptor_name: 'Test Name', merchant_descriptor_address1: '123 Main Dr', merchant_descriptor_locality: 'Durham')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(%r(.*Test Name.*)m, data)
+ assert_match(%r(.*123 Main Dr.*)m, data)
+ assert_match(%r(.*Durham.*)m, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_allows_nil_values_in_billing_address
+ billing_address = {
+ address1: '123 Fourth St',
+ city: 'Fiveton',
+ state: '',
+ country: 'CA'
+ }
+
+ stub_comms do
+ @gateway.authorize(100, @credit_card, billing_address: billing_address)
+ end.check_request do |_endpoint, data, _headers|
+ assert_nil billing_address[:zip]
+ assert_nil billing_address[:phone]
+ assert_match(%r(.*123 Fourth St.*)m, data)
+ assert_match(%r(.*Fiveton.*)m, data)
+ assert_match(%r(.*NC.*)m, data)
+ assert_match(%r(.*00000.*)m, data)
+ assert_match(%r(.*CA.*)m, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_uses_names_from_billing_address_if_present
+ name = 'Wesley Crusher'
+
+ stub_comms do
+ @gateway.authorize(100, @credit_card, billing_address: { name: name })
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(%r(.*Wesley.*)m, data)
+ assert_match(%r(.*Crusher.*)m, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_uses_names_from_shipping_address_if_present
+ name = 'Wesley Crusher'
+
+ stub_comms do
+ @gateway.authorize(100, @credit_card, shipping_address: { name: name })
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(%r(.*Wesley.*)m, data)
+ assert_match(%r(.*Crusher.*)m, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_uses_names_from_the_payment_method
+ stub_comms do
+ @gateway.authorize(100, @credit_card)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(%r(.*#{@credit_card.first_name}.*)m, data)
+ assert_match(%r(.*#{@credit_card.last_name}.*)m, data)
+ assert_match(%r(.*#{@credit_card.first_name}.*)m, data)
+ assert_match(%r(.*#{@credit_card.last_name}.*)m, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_purchase_includes_invoice_header
+ stub_comms do
+ @gateway.purchase(100, @credit_card, merchant_descriptor: 'Spreedly', reference_data_code: '3A', invoice_number: '1234567')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/Spreedly<\/merchantDescriptor>/, data)
+ assert_match(/3A<\/referenceDataCode>/, data)
+ assert_match(/1234567<\/invoiceNumber>/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_purchase_with_apple_pay_includes_payment_solution_001
+ stub_comms do
+ @gateway.purchase(100, @apple_pay)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/001<\/paymentSolution>/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_purchase_with_google_pay_includes_payment_solution_012
+ stub_comms do
+ @gateway.purchase(100, @google_pay)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/012<\/paymentSolution>/, data)
end.respond_with(successful_purchase_response)
end
+ def test_purchase_includes_tax_management_indicator
+ stub_comms do
+ @gateway.purchase(100, @credit_card, tax_management_indicator: 3)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/3<\/taxManagementIndicator>/, data)
+ end.respond_with(successful_purchase_response)
+ end
+
+ def test_authorize_includes_issuer_additional_data
+ stub_comms do
+ @gateway.authorize(100, @credit_card, order_id: '1', issuer_additional_data: @issuer_additional_data)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/\s+#{@issuer_additional_data}<\/additionalData>\s+<\/issuer>/m, data)
+ end.respond_with(successful_authorization_response)
+ end
+
def test_authorize_includes_mdd_fields
stub_comms do
@gateway.authorize(100, @credit_card, order_id: '1', mdd_field_2: 'CustomValue2', mdd_field_3: 'CustomValue3')
- end.check_request do |endpoint, data, headers|
- assert_match(/field2>CustomValue2.*field3>CustomValue3CustomValue2181537<\/reconciliationID>/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_authorize_includes_commerce_indicator
+ stub_comms do
+ @gateway.authorize(100, @credit_card, commerce_indicator: 'internet')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/internet<\/commerceIndicator>/m, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_authorize_includes_installment_data
+ stub_comms do
+ @gateway.authorize(100, @credit_card, order_id: '1', installment_total_count: 5, installment_plan_type: 1, first_installment_date: '300101', installment_total_amount: 5.05, installment_annual_interest_rate: 1.09, installment_grace_period_duration: 3)
+ end.check_request do |_endpoint, data, _headers|
+ assert_xml_valid_to_xsd(data)
+ assert_match(/\s+5<\/totalCount>\s+5.05<\/totalAmount>\s+1<\/planType>\s+300101<\/firstInstallmentDate>\s+1.09<\/annualInterestRate>\s+3<\/gracePeriodDuration>\s+<\/installment>/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_authorize_includes_less_installment_data
+ stub_comms do
+ @gateway.authorize(100, @credit_card, order_id: '1', installment_grace_period_duration: 3)
+ end.check_request do |_endpoint, data, _headers|
+ assert_xml_valid_to_xsd(data)
+ assert_match(/\s+3<\/gracePeriodDuration>\s+<\/installment>/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_authorize_includes_customer_id
+ stub_comms do
+ @gateway.authorize(100, @credit_card, customer_id: '5afefb801188d70023b7debb')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/5afefb801188d70023b7debb<\/customerID>/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_authorize_with_apple_pay_includes_payment_solution_001
+ stub_comms do
+ @gateway.authorize(100, @apple_pay)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/001<\/paymentSolution>/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_authorize_with_google_pay_includes_payment_solution_012
+ stub_comms do
+ @gateway.authorize(100, @google_pay)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/012<\/paymentSolution>/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_authorize_includes_merchant_tax_id_in_billing_address_but_not_shipping_address
+ stub_comms do
+ @gateway.authorize(100, @credit_card, order_id: '1', merchant_tax_id: '123')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(%r(.*123.*)m, data)
+ assert_not_match(%r(.*123.*)m, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_authorize_includes_sales_slip_number
+ stub_comms do
+ @gateway.authorize(100, @credit_card, order_id: '1', sales_slip_number: '123')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/123<\/salesSlipNumber>/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_authorize_includes_airline_agent_code
+ stub_comms do
+ @gateway.authorize(100, @credit_card, order_id: '1', airline_agent_code: '7Q')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/\s+7Q<\/agentCode>\s+<\/airlineData>/, data)
+ end.respond_with(successful_authorization_response)
+ end
+
+ def test_bank_account_purchase_includes_sec_code
+ stub_comms do
+ @gateway.purchase(@amount, @check, order_id: '1', sec_code: 'WEB')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(%r(.*WEB.*)m, data)
end.respond_with(successful_authorization_response)
end
@@ -94,35 +365,46 @@ def test_successful_check_purchase
assert response = @gateway.purchase(@amount, @check, @options)
assert_equal 'Successful transaction', response.message
assert_success response
- assert_equal "#{@options[:order_id]};#{response.params['requestID']};#{response.params['requestToken']};purchase;100;USD;", response.authorization
+ assert_equal "#{@options[:order_id]};#{response.params['requestID']};#{response.params['requestToken']};purchase;100;USD;;check", response.authorization
assert response.test?
end
def test_successful_pinless_debit_card_purchase
@gateway.expects(:ssl_post).returns(successful_purchase_response)
- assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:pinless_debit_card => true))
+ assert response = @gateway.purchase(@amount, @credit_card, @options.merge(pinless_debit_card: true))
assert_equal 'Successful transaction', response.message
assert_success response
- assert_equal "#{@options[:order_id]};#{response.params['requestID']};#{response.params['requestToken']};purchase;100;USD;", response.authorization
+ assert_equal "#{@options[:order_id]};#{response.params['requestID']};#{response.params['requestToken']};purchase;100;USD;;credit_card", response.authorization
assert response.test?
end
def test_successful_credit_cart_purchase_single_request_ignore_avs
- @gateway.expects(:ssl_post).with do |host, request_body|
+ @gateway.expects(:ssl_post).with do |_host, request_body|
+ assert_match %r'true', request_body
+ assert_not_match %r'', request_body
+ true
+ end.returns(successful_purchase_response)
+
+ options = @options.merge(ignore_avs: true)
+ assert response = @gateway.purchase(@amount, @credit_card, options)
+ assert_success response
+ end
+
+ def test_successful_network_token_purchase_single_request_ignore_avs
+ @gateway.expects(:ssl_post).with do |_host, request_body|
assert_match %r'true', request_body
assert_not_match %r'', request_body
true
end.returns(successful_purchase_response)
- assert response = @gateway.purchase(@amount, @credit_card, @options.merge(
- ignore_avs: true
- ))
+ options = @options.merge(ignore_avs: true)
+ assert response = @gateway.purchase(@amount, @network_token, options)
assert_success response
end
def test_successful_credit_cart_purchase_single_request_without_ignore_avs
- @gateway.expects(:ssl_post).with do |host, request_body|
+ @gateway.expects(:ssl_post).with do |_host, request_body|
assert_not_match %r'', request_body
assert_not_match %r'', request_body
true
@@ -131,35 +413,123 @@ def test_successful_credit_cart_purchase_single_request_without_ignore_avs
# globally ignored AVS for gateway instance:
@gateway.options[:ignore_avs] = true
- assert response = @gateway.purchase(@amount, @credit_card, @options.merge(
- ignore_avs: false
- ))
+ options = @options.merge(ignore_avs: false)
+ assert response = @gateway.purchase(@amount, @credit_card, options)
+ assert_success response
+
+ @gateway.expects(:ssl_post).with do |_host, request_body|
+ assert_not_match %r'', request_body
+ assert_not_match %r'', request_body
+ true
+ end.returns(successful_purchase_response)
+
+ options = @options.merge(ignore_avs: 'false')
+ assert response = @gateway.purchase(@amount, @credit_card, options)
assert_success response
end
def test_successful_credit_cart_purchase_single_request_ignore_ccv
- @gateway.expects(:ssl_post).with do |host, request_body|
+ @gateway.expects(:ssl_post).with do |_host, request_body|
+ assert_not_match %r'', request_body
+ assert_match %r'true', request_body
+ true
+ end.returns(successful_purchase_response)
+
+ assert response = @gateway.purchase(@amount, @credit_card, @options.merge(ignore_cvv: true))
+ assert_success response
+ end
+
+ def test_successful_network_token_purchase_single_request_ignore_cvv
+ @gateway.expects(:ssl_post).with do |_host, request_body|
assert_not_match %r'', request_body
assert_match %r'true', request_body
true
end.returns(successful_purchase_response)
- assert response = @gateway.purchase(@amount, @credit_card, @options.merge(
- ignore_cvv: true
- ))
+ options = @options.merge(ignore_cvv: true)
+ assert response = @gateway.purchase(@amount, @network_token, options)
assert_success response
end
def test_successful_credit_cart_purchase_single_request_without_ignore_ccv
- @gateway.expects(:ssl_post).with do |host, request_body|
+ @gateway.expects(:ssl_post).with do |_host, request_body|
+ assert_not_match %r'', request_body
+ assert_not_match %r'', request_body
+ true
+ end.returns(successful_purchase_response)
+
+ assert response = @gateway.purchase(@amount, @credit_card, @options.merge(ignore_cvv: false))
+ assert_success response
+
+ @gateway.expects(:ssl_post).with do |_host, request_body|
assert_not_match %r'', request_body
assert_not_match %r'', request_body
true
end.returns(successful_purchase_response)
- assert response = @gateway.purchase(@amount, @credit_card, @options.merge(
- ignore_cvv: false
- ))
+ assert response = @gateway.purchase(@amount, @credit_card, @options.merge(ignore_cvv: 'false'))
+ assert_success response
+ end
+
+ def test_successful_apple_pay_purchase_subsequent_auth_visa
+ @gateway.expects(:ssl_post).with do |_host, request_body|
+ assert_not_match %r'', request_body
+ assert_not_match %r'', request_body
+ assert_match %r'internet', request_body
+ true
+ end.returns(successful_purchase_response)
+
+ options = @options.merge({
+ stored_credential: {
+ initiator: 'merchant',
+ reason_type: 'unscheduled',
+ network_transaction_id: '016150703802094'
+ }
+ })
+ assert response = @gateway.purchase(@amount, @apple_pay, options)
+ assert_success response
+ end
+
+ def test_successful_apple_pay_purchase_subsequent_auth_mastercard
+ @gateway.expects(:ssl_post).with do |_host, request_body|
+ assert_not_match %r'', request_body
+ assert_match %r'internet', request_body
+ true
+ end.returns(successful_purchase_response)
+
+ credit_card = network_tokenization_credit_card('5555555555554444',
+ brand: 'master',
+ transaction_id: '123',
+ eci: '05',
+ payment_cryptogram: '111111111100cryptogram',
+ source: :apple_pay)
+ options = @options.merge({
+ stored_credential: {
+ initiator: 'merchant',
+ reason_type: 'unscheduled',
+ network_transaction_id: '016150703802094'
+ }
+ })
+ assert response = @gateway.purchase(@amount, credit_card, options)
+ assert_success response
+ end
+
+ def test_successful_network_token_purchase_subsequent_auth_visa
+ @gateway.expects(:ssl_post).with do |_host, request_body|
+ assert_match %r'111111111100cryptogram', request_body
+ assert_match %r'vbv', request_body
+ assert_not_match %r'internet', request_body
+ true
+ end.returns(successful_purchase_response)
+
+ options = @options.merge({
+ stored_credential: {
+ initiator: 'merchant',
+ reason_type: 'unscheduled',
+ network_transaction_id: '016150703802094'
+ }
+ })
+ assert response = @gateway.purchase(@amount, @network_token, options)
assert_success response
end
@@ -198,6 +568,14 @@ def test_successful_auth_request
assert response.test?
end
+ def test_successful_auth_with_elo_request
+ @gateway.stubs(:ssl_post).returns(successful_authorization_response)
+ assert response = @gateway.authorize(@amount, @elo_credit_card, @options)
+ assert_equal Response, response.class
+ assert response.success?
+ assert response.test?
+ end
+
def test_successful_credit_card_tax_request
@gateway.stubs(:ssl_post).returns(successful_tax_response)
assert response = @gateway.calculate_tax(@credit_card, @options)
@@ -206,6 +584,32 @@ def test_successful_credit_card_tax_request
assert response.test?
end
+ def test_successful_credit_card_tax_request_with_amounts
+ stub_comms do
+ @gateway.calculate_tax(@credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ doc = REXML::Document.new(data)
+ REXML::XPath.each(doc, '//item') do |item|
+ request_item = @options[:line_items][item.attributes['id'].to_i]
+ assert_match(request_item[:tax_amount], item.get_elements('taxAmount')[0].text)
+ assert_match(request_item[:national_tax], item.get_elements('nationalTax')[0].text)
+ end
+ end.respond_with(successful_tax_response)
+ end
+
+ def test_successful_credit_card_authorize_request_with_line_items
+ stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ doc = REXML::Document.new(data)
+ REXML::XPath.each(doc, '//item') do |item|
+ request_item = @options[:line_items][item.attributes['id'].to_i]
+ assert_match(request_item[:tax_amount], item.get_elements('taxAmount')[0].text)
+ assert_match(request_item[:national_tax], item.get_elements('nationalTax')[0].text)
+ end
+ end.respond_with(successful_tax_response)
+ end
+
def test_successful_credit_card_capture_request
@gateway.stubs(:ssl_post).returns(successful_authorization_response, successful_capture_response)
assert response = @gateway.authorize(@amount, @credit_card, @options)
@@ -216,6 +620,58 @@ def test_successful_credit_card_capture_request
assert response_capture.test?
end
+ def test_capture_includes_local_tax_amount
+ stub_comms do
+ @gateway.capture(100, '1842651133440156177166', local_tax_amount: '0.17')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/\s+0.17<\/localTaxAmount>\s+<\/otherTax>/, data)
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_capture_includes_national_tax_amount
+ stub_comms do
+ @gateway.capture(100, '1842651133440156177166', national_tax_amount: '0.05')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/\s+0.05<\/nationalTaxAmount>\s+<\/otherTax>/, data)
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_capture_with_additional_tax_fields
+ stub_comms do
+ @gateway.capture(100, '1842651133440156177166', user_po: 'ABC123', taxable: true, national_tax_indicator: 1)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/ABC123<\/userPO>/, data)
+ assert_match(/true<\/taxable>/, data)
+ assert_match(/1<\/nationalTaxIndicator>/, data)
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_capture_includes_gratuity_amount
+ stub_comms do
+ @gateway.capture(100, '1842651133440156177166', gratuity_amount: '3.05')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/3.05<\/gratuityAmount>/, data)
+ end.respond_with(successful_capture_response)
+ end
+
+ def test_successful_credit_card_capture_with_elo_request
+ @gateway.stubs(:ssl_post).returns(successful_authorization_response, successful_capture_response)
+ assert response = @gateway.authorize(@amount, @elo_credit_card, @options)
+ assert response.success?
+ assert response.test?
+ assert response_capture = @gateway.capture(@amount, response.authorization)
+ assert response_capture.success?
+ assert response_capture.test?
+ end
+
+ def test_capture_includes_mdd_fields
+ stub_comms do
+ @gateway.capture(100, '1846925324700976124593', order_id: '1', mdd_field_2: 'CustomValue2', mdd_field_3: 'CustomValue3')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/CustomValue2 generate_unique_id)
+ assert response = @gateway.unstore(response.authorization, order_id: generate_unique_id)
assert response.success?
assert response.test?
end
@@ -270,7 +746,7 @@ def test_successful_credit_card_retrieve_request
assert response = @gateway.store(@credit_card, @subscription_options)
assert response.success?
assert response.test?
- assert response = @gateway.retrieve(response.authorization, :order_id => generate_unique_id)
+ assert response = @gateway.retrieve(response.authorization, order_id: generate_unique_id)
assert response.success?
assert response.test?
end
@@ -296,8 +772,36 @@ def test_successful_refund_request
assert_success(@gateway.refund(@amount, response.authorization))
end
- def test_successful_credit_request
- @gateway.stubs(:ssl_post).returns(successful_create_subscription_response, successful_credit_response)
+ def test_successful_refund_with_elo_request
+ @gateway.stubs(:ssl_post).returns(successful_capture_response, successful_refund_response)
+ assert_success(response = @gateway.purchase(@amount, @elo_credit_card, @options))
+
+ assert_success(@gateway.refund(@amount, response.authorization))
+ end
+
+ def test_successful_credit_to_card_request
+ @gateway.stubs(:ssl_post).returns(successful_card_credit_response)
+
+ assert_success(@gateway.credit(@amount, @credit_card, @options))
+ end
+
+ def test_successful_adjust_auth_request
+ @gateway.stubs(:ssl_post).returns(successful_incremental_auth_response)
+ assert_success(response = @gateway.authorize(@amount, @credit_card, @options))
+
+ assert_success(@gateway.adjust(@amount, response.authorization, @options))
+ end
+
+ def test_authorization_under_review_request
+ @gateway.stubs(:ssl_post).returns(authorization_review_response)
+
+ assert_failure(response = @gateway.authorize(@amount, @credit_card, @options))
+ assert response.fraud_review?
+ assert_equal(response.authorization, "#{@options[:order_id]};#{response.params['requestID']};#{response.params['requestToken']};authorize;100;USD;;")
+ end
+
+ def test_successful_credit_to_subscription_request
+ @gateway.stubs(:ssl_post).returns(successful_create_subscription_response, successful_subscription_credit_response)
assert response = @gateway.store(@credit_card, @subscription_options)
assert response.success?
@@ -305,42 +809,124 @@ def test_successful_credit_request
assert_success(@gateway.credit(@amount, response.authorization, @options))
end
+ def test_credit_includes_merchant_descriptor
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, merchant_descriptor: 'Spreedly')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/Spreedly<\/merchantDescriptor>/, data)
+ end.respond_with(successful_card_credit_response)
+ end
+
+ def test_credit_includes_issuer_additional_data
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, issuer_additional_data: @issuer_additional_data)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/\s+#{@issuer_additional_data}<\/additionalData>\s+<\/issuer>/m, data)
+ end.respond_with(successful_card_credit_response)
+ end
+
+ def test_credit_includes_mdd_fields
+ stub_comms do
+ @gateway.credit(@amount, @credit_card, mdd_field_2: 'CustomValue2', mdd_field_3: 'CustomValue3')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/CustomValue2\s+#{@issuer_additional_data}<\/additionalData>\s+<\/issuer>/m, data)
+ end.respond_with(successful_void_response)
+ end
+
+ def test_void_includes_mdd_fields
+ authorization = '1000;1842651133440156177166;AP4JY+Or4xRonEAOERAyMzQzOTEzMEM0MFZaNUZCBgDH3fgJ8AEGAMfd+AnwAwzRpAAA7RT/;authorize;100;USD;'
+
+ stub_comms do
+ @gateway.void(authorization, mdd_field_2: 'CustomValue2', mdd_field_3: 'CustomValue3')
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/CustomValue21.00<\/amount>), data
end.respond_with(successful_update_subscription_response)
end
def test_successful_verify
response = stub_comms(@gateway, :ssl_request) do
- @gateway.verify(@credit_card, @options)
+ @gateway.verify(@credit_card, @options)
+ end.respond_with(successful_authorization_response)
+ assert_success response
+ end
+
+ def test_successful_verify_zero_amount_request
+ @options[:zero_amount_auth] = true
+ stub_comms(@gateway, :ssl_post) do
+ @gateway.verify(@credit_card, @options)
+ end.check_request(skip_response: true) do |_endpoint, data|
+ assert_match %r(0.00<\/grandTotalAmount>), data
+ end
+ end
+
+ def test_successful_verify_request
+ stub_comms(@gateway, :ssl_post) do
+ @gateway.verify(@credit_card, @options)
+ end.check_request(skip_response: true) do |_endpoint, data|
+ assert_match %r(1.00<\/grandTotalAmount>), data
+ end
+ end
+
+ def test_successful_verify_with_elo
+ response = stub_comms(@gateway, :ssl_request) do
+ @gateway.verify(@elo_credit_card, @options)
end.respond_with(successful_authorization_response)
assert_success response
end
@@ -354,53 +940,40 @@ def test_unsuccessful_verify
end
def test_successful_auth_with_network_tokenization_for_visa
- credit_card = network_tokenization_credit_card('4111111111111111',
- :brand => 'visa',
- :transaction_id => '123',
- :eci => '05',
- :payment_cryptogram => '111111111100cryptogram'
- )
-
response = stub_comms do
- @gateway.authorize(@amount, credit_card, @options)
+ @gateway.authorize(@amount, @network_token, @options)
end.check_request do |_endpoint, body, _headers|
assert_xml_valid_to_xsd(body)
- assert_match %r'\n 111111111100cryptogram\n vbv\n 111111111100cryptogram\n\n\n 1\n', body
+ assert_match %r'\n 111111111100cryptogram\n vbv\n 111111111100cryptogram\n\n\n\n\n 1\n', body
end.respond_with(successful_purchase_response)
assert_success response
end
def test_successful_purchase_with_network_tokenization_for_visa
- credit_card = network_tokenization_credit_card('4111111111111111',
- :brand => 'visa',
- :transaction_id => '123',
- :eci => '05',
- :payment_cryptogram => '111111111100cryptogram'
- )
-
response = stub_comms do
- @gateway.purchase(@amount, credit_card, @options)
+ @gateway.purchase(@amount, @network_token, @options)
end.check_request do |_endpoint, body, _headers|
assert_xml_valid_to_xsd(body)
- assert_match %r'.+?'m, body
+ assert_match %r'.+?'m, body
end.respond_with(successful_purchase_response)
assert_success response
end
def test_successful_auth_with_network_tokenization_for_mastercard
- @gateway.expects(:ssl_post).with do |host, request_body|
+ @gateway.expects(:ssl_post).with do |_host, request_body|
assert_xml_valid_to_xsd(request_body)
- assert_match %r'\n 111111111100cryptogram\n 2\n\n\n spa\n\n\n 1\n', request_body
+ assert_match %r'\n 111111111100cryptogram\n 2\n\n\n spa\n\n\n\n\n 1\n', request_body
true
end.returns(successful_purchase_response)
- credit_card = network_tokenization_credit_card('5555555555554444',
- :brand => 'mastercard',
- :transaction_id => '123',
- :eci => '05',
- :payment_cryptogram => '111111111100cryptogram'
+ credit_card = network_tokenization_credit_card(
+ '5555555555554444',
+ brand: 'master',
+ transaction_id: '123',
+ eci: '05',
+ payment_cryptogram: '111111111100cryptogram'
)
assert response = @gateway.authorize(@amount, credit_card, @options)
@@ -408,25 +981,165 @@ def test_successful_auth_with_network_tokenization_for_mastercard
end
def test_successful_auth_with_network_tokenization_for_amex
- @gateway.expects(:ssl_post).with do |host, request_body|
+ @gateway.expects(:ssl_post).with do |_host, request_body|
assert_xml_valid_to_xsd(request_body)
- assert_match %r'\n MTExMTExMTExMTAwY3J5cHRvZ3I=\n\n aesk\n YW0=\n\n\n\n 1\n', request_body
+ assert_match %r'\n MTExMTExMTExMTAwY3J5cHRvZ3I=\n\n aesk\n YW0=\n\n\n\n\n\n 1\n', request_body
true
end.returns(successful_purchase_response)
- credit_card = network_tokenization_credit_card('378282246310005',
- :brand => 'american_express',
- :transaction_id => '123',
- :eci => '05',
- :payment_cryptogram => Base64.encode64('111111111100cryptogram')
+ credit_card = network_tokenization_credit_card(
+ '378282246310005',
+ brand: 'american_express',
+ transaction_id: '123',
+ eci: '05',
+ payment_cryptogram: Base64.encode64('111111111100cryptogram')
)
assert response = @gateway.authorize(@amount, credit_card, @options)
assert_success response
end
+ def test_cof_first
+ @options[:stored_credential] = {
+ initiator: 'cardholder',
+ reason_type: '',
+ initial_transaction: true,
+ network_transaction_id: ''
+ }
+ @options[:commerce_indicator] = 'internet'
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_match(/\true/, data)
+ assert_not_match(/\true/, data)
+ assert_not_match(/\/, data)
+ assert_not_match(/\/, data)
+ assert_match(/\internet/, data)
+ end.respond_with(successful_authorization_response)
+ assert response.success?
+ end
+
+ def test_cof_cit_auth
+ @options[:stored_credential] = {
+ initiator: 'cardholder',
+ reason_type: 'unscheduled',
+ initial_transaction: false,
+ network_transaction_id: ''
+ }
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_not_match(/\/, data)
+ assert_match(/\/, data)
+ assert_not_match(/\/, data)
+ assert_not_match(/\/, data)
+ end.respond_with(successful_authorization_response)
+ assert response.success?
+ end
+
+ def test_cof_unscheduled_mit_auth
+ @options[:stored_credential] = {
+ initiator: 'merchant',
+ reason_type: 'unscheduled',
+ initial_transaction: false,
+ network_transaction_id: '016150703802094'
+ }
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_not_match(/\/, data)
+ assert_match(/\true/, data)
+ assert_match(/\true/, data)
+ assert_match(/\016150703802094/, data)
+ end.respond_with(successful_authorization_response)
+ assert response.success?
+ end
+
+ def test_cof_installment_mit_auth
+ @options[:stored_credential] = {
+ initiator: 'merchant',
+ reason_type: 'installment',
+ initial_transaction: false,
+ network_transaction_id: '016150703802094'
+ }
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_not_match(/\/, data)
+ assert_not_match(/\/, data)
+ assert_match(/\true/, data)
+ assert_match(/\016150703802094/, data)
+ assert_match(/\install/, data)
+ end.respond_with(successful_authorization_response)
+ assert response.success?
+ end
+
+ def test_cof_recurring_mit_auth
+ @options[:stored_credential] = {
+ initiator: 'merchant',
+ reason_type: 'recurring',
+ initial_transaction: false,
+ network_transaction_id: '016150703802094'
+ }
+ response = stub_comms do
+ @gateway.authorize(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_not_match(/\/, data)
+ assert_not_match(/\/, data)
+ assert_match(/\true/, data)
+ assert_match(/\016150703802094/, data)
+ assert_match(/\recurring/, data)
+ end.respond_with(successful_authorization_response)
+ assert response.success?
+ end
+
+ def test_cof_recurring_mit_purchase
+ @options[:stored_credential] = {
+ initiator: 'merchant',
+ reason_type: 'recurring',
+ initial_transaction: false,
+ network_transaction_id: '016150703802094'
+ }
+ response = stub_comms do
+ @gateway.purchase(@amount, @credit_card, @options)
+ end.check_request do |_endpoint, data, _headers|
+ assert_not_match(/\/, data)
+ assert_not_match(/\